diff options
Diffstat (limited to 'gnu/usr.bin')
145 files changed, 28279 insertions, 9891 deletions
diff --git a/gnu/usr.bin/gcc/ChangeLog b/gnu/usr.bin/gcc/ChangeLog index 3f955fb4a2e..6754184fa5c 100644 --- a/gnu/usr.bin/gcc/ChangeLog +++ b/gnu/usr.bin/gcc/ChangeLog @@ -1,3 +1,70 @@ +Wed Feb 26 13:09:33 1997 Michael Meissner <meissner@cygnus.com> + + * reload.c (debug_reload): Fix format string to print + reload_nocombine[r]. + +Sun Feb 23 15:26:53 1997 Craig Burley <burley@gnu.ai.mit.edu> + + * fold-const.c (multiple_of_p): Clean up and improve. + (fold): Clean up invocation of multiple_of_p. + +Sat Feb 8 04:53:27 1997 Craig Burley <burley@gnu.ai.mit.edu> + + From <jfc@jfc.tiac.net> Fri, 07 Feb 1997 22:02:21 -0500: + * alias.c (init_alias_analysis): Reduce amount of time + needed to simplify the reg_base_value array in the + typical case (especially involving function inlining). + +Fri Jan 10 17:22:17 1997 Craig Burley <burley@gnu.ai.mit.edu> + + Minor improvements/fixes to better alias handling: + * Makefile.in (alias.o): Fix typo in rule (was RLT_H). + * cse.c, sched.c: Fix up some indenting. + * toplev.c: Add -fargument-alias flag, so Fortran users + can turn C-style aliasing on once g77 defaults to + -fargument-noalias-global. + + Integrate patch for better alias handling from + John Carr <jfc@mit.edu>: + * Makefile.in (OBJS, alias.o): New module and rule. + * alias.c: New source module. + * calls.c (expand_call): Recognize alias status of calls + to malloc(). + * combine.c (distribute_notes): New REG_NOALIAS note. + * rtl.h (REG_NOALIAS): Ditto. + Many other changes for new alias.c module. + * cse.c: Many changes, and much code moved into alias.c. + * flags.h (flag_alias_check, flag_argument_noalias): + New flags. + * toplev.c: New flags and related options. + * local-alloc.c (validate_equiv_mem_from_store): + Caller of true_dependence changed. + * loop.c (NUM_STORES): Increase to 50 from 20. + (prescan_loop): "const" functions don't alter unknown addresses. + (invariant_p): Caller of true_dependence changed. + (record_giv): Zero new unrolled and shared flags. + (emit_iv_add_mult): Record base value for register. + * sched.c: Many changes, mostly moving code to alias.c. + (sched_note_set): SCHED_SORT macro def form, but not function, + inexplicably changed. + * unroll.c: Record base values for registers, etc. + +Fri Jan 3 04:01:00 1997 Craig Burley <burley@gnu.ai.mit.edu> + + * loop.c (check_final_value): Handle insns with no luid's + appropriately, instead of crashing on INSN_LUID macro + invocations. + +Mon Dec 23 00:49:19 1996 Craig Burley <burley@gnu.ai.mit.edu> + + * config/alpha/alpha.md: Fix pattern that matches if_then_else + involving DF target, DF comparison, SF source. + +Fri Dec 20 15:42:52 1996 Craig Burley <burley@gnu.ai.mit.edu> + + * fold-const.c (multiple_of_p): New function. + (fold): Use new function to turn *_DIV_EXPR into EXACT_DIV_EXPR. + Sat Jun 29 12:33:39 1996 Richard Kenner <kenner@vlsi1.ultra.nyu.edu> * Version 2.7.2.1 released. diff --git a/gnu/usr.bin/gcc/Makefile.in b/gnu/usr.bin/gcc/Makefile.in index d8c7610c7de..30e7fe5f852 100644 --- a/gnu/usr.bin/gcc/Makefile.in +++ b/gnu/usr.bin/gcc/Makefile.in @@ -524,7 +524,7 @@ OBJS = toplev.o version.o tree.o print-tree.o stor-layout.o fold-const.o \ dbxout.o sdbout.o dwarfout.o xcoffout.o \ integrate.o jump.o cse.o loop.o unroll.o flow.o stupid.o combine.o \ regclass.o local-alloc.o global.o reload.o reload1.o caller-save.o \ - insn-peep.o reorg.o sched.o final.o recog.o reg-stack.o \ + insn-peep.o reorg.o alias.o sched.o final.o recog.o reg-stack.o \ insn-opinit.o insn-recog.o insn-extract.o insn-output.o insn-emit.o \ insn-attrtab.o $(out_object_file) getpwd.o convert.o $(EXTRA_OBJS) @@ -1249,6 +1249,7 @@ caller-save.o : caller-save.c $(CONFIG_H) $(RTL_H) flags.h \ reorg.o : reorg.c $(CONFIG_H) $(RTL_H) conditions.h hard-reg-set.h \ basic-block.h regs.h insn-config.h insn-attr.h insn-flags.h recog.h \ flags.h output.h +alias.o : $(CONFIG_H) $(RTL_H) flags.h hard-reg-set.h regs.h sched.o : sched.c $(CONFIG_H) $(RTL_H) basic-block.h regs.h hard-reg-set.h \ flags.h insn-config.h insn-attr.h final.o : final.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h regs.h \ diff --git a/gnu/usr.bin/gcc/README.g77 b/gnu/usr.bin/gcc/README.g77 index edded28aece..e95b60cdc01 100644 --- a/gnu/usr.bin/gcc/README.g77 +++ b/gnu/usr.bin/gcc/README.g77 @@ -1,6 +1,6 @@ -1996-03-05 +1997-02-28 -This directory contains the version 0.5.18 release of the GNU Fortran +This directory contains the version 0.5.20 release of the GNU Fortran compiler. The GNU Fortran compiler is free software. See the file COPYING.g77 for copying permission. @@ -14,11 +14,10 @@ which is the top-level directory containing the gcc back end, the gcc C front end, and other non-Fortran files, and gcc/f/, which contains all of the Fortran files. -* To build GNU Fortran, you must have a recent gcc distribution, - such as version 2.6.3 or 2.7.0. Do not attempt to use any version - of gcc prior to 2.6.2 or at or beyond 2.8.0 (or 3.0, etc.), because - this version of g77 is designed to work only with gcc versions 2.6.x - and 2.7.x. +* To build GNU Fortran, you must have a source distribution of gcc + version 2.7.2.2. Do not attempt to use any other version + of gcc, because this version of g77 is designed to work only with + gcc version 2.7.2.2. * Note that you must have source copies of these gcc distributions!! You cannot build g77 just using binaries of gcc. Also, unless you @@ -31,15 +30,15 @@ If you have just unpacked the g77 distribution, before proceeding, you must merge the contents of the g77 distribution with the appropriate gcc distribution on your system before proceeding. -* Read and follow the instructions in g77-0.5.18/f/INSTALL that +* Read and follow the instructions in g77-0.5.20/f/INSTALL that explain how to merge a g77 source directory into a gcc source directory. You can use Info to read the same installation instructions via: - info -f g77-0.5.18/f/g77.info -n Unpacking + info -f g77-0.5.20/f/g77.info -n Unpacking The resulting directory layout includes the following, where gcc/ might be -a link to, for example, gcc-2.7.2/: +a link to, for example, gcc-2.7.2.2/: gcc/ Non-Fortran files in gcc (not part of g77*.tar) gcc/README.g77 This file @@ -48,6 +47,7 @@ a link to, for example, gcc-2.7.2/: gcc/f/runtime/ libf2c configuration and f2c.h file generation gcc/f/runtime/libF77/ Non-I/O portion of libf2c gcc/f/runtime/libI77/ I/O portion of libf2c + gcc/f/runtime/libU77/ Additional interfaces to libc for libf2c gcc/f/ as a whole contains the program GNU Fortran (g77), plus a portion of the separate program f2c, which is in gcc/f/runtime. NOTE: The f2c @@ -110,7 +110,7 @@ seen in gcc/f/DOC) listed in the ~fortran/.plan file. Or: * Read gcc/f/BUGS, gcc/f/INSTALL, and gcc/f/NEWS at the very least! All users of g77 (not just installers) should read gcc/f/g77.info* as well, using the "more" command if the "info" command is - unavailable or they aren't used to using it. + unavailable or they aren't accustomed to using it. If you want to get into the FFE code, which lives entirely in gcc/f/, here are a few clues. The file g77.c is the stand-alone source file for the diff --git a/gnu/usr.bin/gcc/alias.c b/gnu/usr.bin/gcc/alias.c new file mode 100644 index 00000000000..bd7f1f4e6e5 --- /dev/null +++ b/gnu/usr.bin/gcc/alias.c @@ -0,0 +1,989 @@ +/* Alias analysis for GNU C, by John Carr (jfc@mit.edu). + Derived in part from sched.c */ +#include "config.h" +#include "rtl.h" +#include "expr.h" +#include "regs.h" +#include "hard-reg-set.h" +#include "flags.h" + +static rtx canon_rtx PROTO((rtx)); +static int rtx_equal_for_memref_p PROTO((rtx, rtx)); +static rtx find_symbolic_term PROTO((rtx)); +static int memrefs_conflict_p PROTO((int, rtx, int, rtx, + HOST_WIDE_INT)); + +/* Set up all info needed to perform alias analysis on memory references. */ + +#define SIZE_FOR_MODE(X) (GET_MODE_SIZE (GET_MODE (X))) + +/* reg_base_value[N] gives an address to which register N is related. + If all sets after the first add or subtract to the current value + or otherwise modify it so it does not point to a different top level + object, reg_base_value[N] is equal to the address part of the source + of the first set. The value will be a SYMBOL_REF, a LABEL_REF, or + (address (reg)) to indicate that the address is derived from an + argument or fixed register. */ +rtx *reg_base_value; +unsigned int reg_base_value_size; /* size of reg_base_value array */ +#define REG_BASE_VALUE(X) \ + (REGNO (X) < reg_base_value_size ? reg_base_value[REGNO (X)] : 0) + +/* Vector indexed by N giving the initial (unchanging) value known + for pseudo-register N. */ +rtx *reg_known_value; + +/* Indicates number of valid entries in reg_known_value. */ +static int reg_known_value_size; + +/* Vector recording for each reg_known_value whether it is due to a + REG_EQUIV note. Future passes (viz., reload) may replace the + pseudo with the equivalent expression and so we account for the + dependences that would be introduced if that happens. */ +/* ??? This is a problem only on the Convex. The REG_EQUIV notes created in + assign_parms mention the arg pointer, and there are explicit insns in the + RTL that modify the arg pointer. Thus we must ensure that such insns don't + get scheduled across each other because that would invalidate the REG_EQUIV + notes. One could argue that the REG_EQUIV notes are wrong, but solving + the problem in the scheduler will likely give better code, so we do it + here. */ +char *reg_known_equiv_p; + +/* Inside SRC, the source of a SET, find a base address. */ + +/* When copying arguments into pseudo-registers, record the (ADDRESS) + expression for the argument directly so that even if the argument + register is changed later (e.g. for a function call) the original + value is noted. */ +static int copying_arguments; + +static rtx +find_base_value (src) + register rtx src; +{ + switch (GET_CODE (src)) + { + case SYMBOL_REF: + case LABEL_REF: + return src; + + case REG: + if (copying_arguments && REGNO (src) < FIRST_PSEUDO_REGISTER) + return reg_base_value[REGNO (src)]; + return src; + + case MEM: + /* Check for an argument passed in memory. Only record in the + copying-arguments block; it is too hard to track changes + otherwise. */ + if (copying_arguments + && (XEXP (src, 0) == arg_pointer_rtx + || (GET_CODE (XEXP (src, 0)) == PLUS + && XEXP (XEXP (src, 0), 0) == arg_pointer_rtx))) + return gen_rtx (ADDRESS, VOIDmode, src); + return 0; + + case CONST: + src = XEXP (src, 0); + if (GET_CODE (src) != PLUS && GET_CODE (src) != MINUS) + break; + /* fall through */ + case PLUS: + case MINUS: + /* Guess which operand to set the register equivalent to. */ + /* If the first operand is a symbol or the second operand is + an integer, the first operand is the base address. */ + if (GET_CODE (XEXP (src, 0)) == SYMBOL_REF + || GET_CODE (XEXP (src, 0)) == LABEL_REF + || GET_CODE (XEXP (src, 1)) == CONST_INT) + return XEXP (src, 0); + /* If an operand is a register marked as a pointer, it is the base. */ + if (GET_CODE (XEXP (src, 0)) == REG + && REGNO_POINTER_FLAG (REGNO (XEXP (src, 0)))) + src = XEXP (src, 0); + else if (GET_CODE (XEXP (src, 1)) == REG + && REGNO_POINTER_FLAG (REGNO (XEXP (src, 1)))) + src = XEXP (src, 1); + else + return 0; + if (copying_arguments && REGNO (src) < FIRST_PSEUDO_REGISTER) + return reg_base_value[REGNO (src)]; + return src; + + case AND: + /* If the second operand is constant set the base + address to the first operand. */ + if (GET_CODE (XEXP (src, 1)) == CONST_INT + && GET_CODE (XEXP (src, 0)) == REG) + { + src = XEXP (src, 0); + if (copying_arguments && REGNO (src) < FIRST_PSEUDO_REGISTER) + return reg_base_value[REGNO (src)]; + return src; + } + return 0; + + case HIGH: + return XEXP (src, 0); + } + + return 0; +} + +/* Called from init_alias_analysis indirectly through note_stores. */ + +/* while scanning insns to find base values, reg_seen[N] is nonzero if + register N has been set in this function. */ +static char *reg_seen; + +static +void record_set (dest, set) + rtx dest, set; +{ + register int regno; + rtx src; + + if (GET_CODE (dest) != REG) + return; + + regno = REGNO (dest); + + if (set) + { + /* A CLOBBER wipes out any old value but does not prevent a previously + unset register from acquiring a base address (i.e. reg_seen is not + set). */ + if (GET_CODE (set) == CLOBBER) + { + reg_base_value[regno] = 0; + return; + } + src = SET_SRC (set); + } + else + { + static int unique_id; + if (reg_seen[regno]) + { + reg_base_value[regno] = 0; + return; + } + reg_seen[regno] = 1; + reg_base_value[regno] = gen_rtx (ADDRESS, Pmode, + GEN_INT (unique_id++)); + return; + } + + /* This is not the first set. If the new value is not related to the + old value, forget the base value. Note that the following code is + not detected: + extern int x, y; int *p = &x; p += (&y-&x); + ANSI C does not allow computing the difference of addresses + of distinct top level objects. */ + if (reg_base_value[regno]) + switch (GET_CODE (src)) + { + case PLUS: + case MINUS: + if (XEXP (src, 0) != dest && XEXP (src, 1) != dest) + reg_base_value[regno] = 0; + break; + case AND: + if (XEXP (src, 0) != dest || GET_CODE (XEXP (src, 1)) != CONST_INT) + reg_base_value[regno] = 0; + break; + case LO_SUM: + if (XEXP (src, 0) != dest) + reg_base_value[regno] = 0; + break; + default: + reg_base_value[regno] = 0; + break; + } + /* If this is the first set of a register, record the value. */ + else if ((regno >= FIRST_PSEUDO_REGISTER || ! fixed_regs[regno]) + && ! reg_seen[regno] && reg_base_value[regno] == 0) + reg_base_value[regno] = find_base_value (src); + + reg_seen[regno] = 1; +} + +/* Called from loop optimization when a new pseudo-register is created. */ +void +record_base_value (regno, val) + int regno; + rtx val; +{ + if (!flag_alias_check || regno >= reg_base_value_size) + return; + if (GET_CODE (val) == REG) + { + if (REGNO (val) < reg_base_value_size) + reg_base_value[regno] = reg_base_value[REGNO (val)]; + return; + } + reg_base_value[regno] = find_base_value (val); +} + +static rtx +canon_rtx (x) + rtx x; +{ + /* Recursively look for equivalences. */ + if (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER + && REGNO (x) < reg_known_value_size) + return reg_known_value[REGNO (x)] == x + ? x : canon_rtx (reg_known_value[REGNO (x)]); + else if (GET_CODE (x) == PLUS) + { + rtx x0 = canon_rtx (XEXP (x, 0)); + rtx x1 = canon_rtx (XEXP (x, 1)); + + if (x0 != XEXP (x, 0) || x1 != XEXP (x, 1)) + { + /* We can tolerate LO_SUMs being offset here; these + rtl are used for nothing other than comparisons. */ + if (GET_CODE (x0) == CONST_INT) + return plus_constant_for_output (x1, INTVAL (x0)); + else if (GET_CODE (x1) == CONST_INT) + return plus_constant_for_output (x0, INTVAL (x1)); + return gen_rtx (PLUS, GET_MODE (x), x0, x1); + } + } + /* This gives us much better alias analysis when called from + the loop optimizer. Note we want to leave the original + MEM alone, but need to return the canonicalized MEM with + all the flags with their original values. */ + else if (GET_CODE (x) == MEM) + { + rtx addr = canon_rtx (XEXP (x, 0)); + if (addr != XEXP (x, 0)) + { + rtx new = gen_rtx (MEM, GET_MODE (x), addr); + MEM_VOLATILE_P (new) = MEM_VOLATILE_P (x); + RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (x); + MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (x); + x = new; + } + } + return x; +} + +/* Return 1 if X and Y are identical-looking rtx's. + + We use the data in reg_known_value above to see if two registers with + different numbers are, in fact, equivalent. */ + +static int +rtx_equal_for_memref_p (x, y) + rtx x, y; +{ + register int i; + register int j; + register enum rtx_code code; + register char *fmt; + + if (x == 0 && y == 0) + return 1; + if (x == 0 || y == 0) + return 0; + x = canon_rtx (x); + y = canon_rtx (y); + + if (x == y) + return 1; + + code = GET_CODE (x); + /* Rtx's of different codes cannot be equal. */ + if (code != GET_CODE (y)) + return 0; + + /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent. + (REG:SI x) and (REG:HI x) are NOT equivalent. */ + + if (GET_MODE (x) != GET_MODE (y)) + return 0; + + /* REG, LABEL_REF, and SYMBOL_REF can be compared nonrecursively. */ + + if (code == REG) + return REGNO (x) == REGNO (y); + if (code == LABEL_REF) + return XEXP (x, 0) == XEXP (y, 0); + if (code == SYMBOL_REF) + return XSTR (x, 0) == XSTR (y, 0); + + /* For commutative operations, the RTX match if the operand match in any + order. Also handle the simple binary and unary cases without a loop. */ + if (code == EQ || code == NE || GET_RTX_CLASS (code) == 'c') + return ((rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 0)) + && rtx_equal_for_memref_p (XEXP (x, 1), XEXP (y, 1))) + || (rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 1)) + && rtx_equal_for_memref_p (XEXP (x, 1), XEXP (y, 0)))); + else if (GET_RTX_CLASS (code) == '<' || GET_RTX_CLASS (code) == '2') + return (rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 0)) + && rtx_equal_for_memref_p (XEXP (x, 1), XEXP (y, 1))); + else if (GET_RTX_CLASS (code) == '1') + return rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 0)); + + /* Compare the elements. If any pair of corresponding elements + fail to match, return 0 for the whole things. */ + + fmt = GET_RTX_FORMAT (code); + for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) + { + switch (fmt[i]) + { + case 'w': + if (XWINT (x, i) != XWINT (y, i)) + return 0; + break; + + case 'n': + case 'i': + if (XINT (x, i) != XINT (y, i)) + return 0; + break; + + case 'V': + case 'E': + /* Two vectors must have the same length. */ + if (XVECLEN (x, i) != XVECLEN (y, i)) + return 0; + + /* And the corresponding elements must match. */ + for (j = 0; j < XVECLEN (x, i); j++) + if (rtx_equal_for_memref_p (XVECEXP (x, i, j), XVECEXP (y, i, j)) == 0) + return 0; + break; + + case 'e': + if (rtx_equal_for_memref_p (XEXP (x, i), XEXP (y, i)) == 0) + return 0; + break; + + case 'S': + case 's': + if (strcmp (XSTR (x, i), XSTR (y, i))) + return 0; + break; + + case 'u': + /* These are just backpointers, so they don't matter. */ + break; + + case '0': + break; + + /* It is believed that rtx's at this level will never + contain anything but integers and other rtx's, + except for within LABEL_REFs and SYMBOL_REFs. */ + default: + abort (); + } + } + return 1; +} + +/* Given an rtx X, find a SYMBOL_REF or LABEL_REF within + X and return it, or return 0 if none found. */ + +static rtx +find_symbolic_term (x) + rtx x; +{ + register int i; + register enum rtx_code code; + register char *fmt; + + code = GET_CODE (x); + if (code == SYMBOL_REF || code == LABEL_REF) + return x; + if (GET_RTX_CLASS (code) == 'o') + return 0; + + fmt = GET_RTX_FORMAT (code); + for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) + { + rtx t; + + if (fmt[i] == 'e') + { + t = find_symbolic_term (XEXP (x, i)); + if (t != 0) + return t; + } + else if (fmt[i] == 'E') + break; + } + return 0; +} + +static rtx +find_base_term (x) + rtx x; +{ + switch (GET_CODE (x)) + { + case REG: + return REG_BASE_VALUE (x); + + case HIGH: + return find_base_value (XEXP (x, 0)); + + case CONST: + x = XEXP (x, 0); + if (GET_CODE (x) != PLUS && GET_CODE (x) != MINUS) + return 0; + /* fall through */ + case LO_SUM: + case PLUS: + case MINUS: + { + rtx tmp = find_base_term (XEXP (x, 0)); + if (tmp) + return tmp; + return find_base_term (XEXP (x, 1)); + } + + case AND: + if (GET_CODE (XEXP (x, 0)) == REG && GET_CODE (XEXP (x, 1)) == CONST_INT) + return REG_BASE_VALUE (XEXP (x, 0)); + return 0; + + case SYMBOL_REF: + case LABEL_REF: + return x; + + default: + return 0; + } +} + +/* Return 0 if the addresses X and Y are known to point to different + objects, 1 if they might be pointers to the same object. */ + +static int +base_alias_check (x, y) + rtx x, y; +{ + rtx x_base = find_base_term (x); + rtx y_base = find_base_term (y); + + /* If either base address is unknown or the base addresses are equal, + nothing is known about aliasing. */ + if (x_base == 0 || y_base == 0 || rtx_equal_p (x_base, y_base)) + return 1; + + /* The base addresses of the read and write are different + expressions. If they are both symbols there is no + conflict. */ + if (GET_CODE (x_base) != ADDRESS && GET_CODE (y_base) != ADDRESS) + return 0; + + /* If one address is a stack reference there can be no alias: + stack references using different base registers do not alias, + a stack reference can not alias a parameter, and a stack reference + can not alias a global. */ + if ((GET_CODE (x_base) == ADDRESS && GET_MODE (x_base) == Pmode) + || (GET_CODE (y_base) == ADDRESS && GET_MODE (y_base) == Pmode)) + return 0; + + if (! flag_argument_noalias) + return 1; + + if (flag_argument_noalias > 1) + return 0; + + /* Weak noalias assertion (arguments are distinct, but may match globals). */ + return ! (GET_MODE (x_base) == VOIDmode && GET_MODE (y_base) == VOIDmode); +} + +/* Return nonzero if X and Y (memory addresses) could reference the + same location in memory. C is an offset accumulator. When + C is nonzero, we are testing aliases between X and Y + C. + XSIZE is the size in bytes of the X reference, + similarly YSIZE is the size in bytes for Y. + + If XSIZE or YSIZE is zero, we do not know the amount of memory being + referenced (the reference was BLKmode), so make the most pessimistic + assumptions. + + We recognize the following cases of non-conflicting memory: + + (1) addresses involving the frame pointer cannot conflict + with addresses involving static variables. + (2) static variables with different addresses cannot conflict. + + Nice to notice that varying addresses cannot conflict with fp if no + local variables had their addresses taken, but that's too hard now. */ + + +static int +memrefs_conflict_p (xsize, x, ysize, y, c) + register rtx x, y; + int xsize, ysize; + HOST_WIDE_INT c; +{ + if (GET_CODE (x) == HIGH) + x = XEXP (x, 0); + else if (GET_CODE (x) == LO_SUM) + x = XEXP (x, 1); + else + x = canon_rtx (x); + if (GET_CODE (y) == HIGH) + y = XEXP (y, 0); + else if (GET_CODE (y) == LO_SUM) + y = XEXP (y, 1); + else + y = canon_rtx (y); + + if (rtx_equal_for_memref_p (x, y)) + { + if (xsize == 0 || ysize == 0) + return 1; + if (c >= 0 && xsize > c) + return 1; + if (c < 0 && ysize+c > 0) + return 1; + return 0; + } + + if (y == frame_pointer_rtx || y == hard_frame_pointer_rtx + || y == stack_pointer_rtx) + { + rtx t = y; + int tsize = ysize; + y = x; ysize = xsize; + x = t; xsize = tsize; + } + + if (x == frame_pointer_rtx || x == hard_frame_pointer_rtx + || x == stack_pointer_rtx) + { + rtx y1; + + if (CONSTANT_P (y)) + return 0; + + if (GET_CODE (y) == PLUS + && canon_rtx (XEXP (y, 0)) == x + && (y1 = canon_rtx (XEXP (y, 1))) + && GET_CODE (y1) == CONST_INT) + { + c += INTVAL (y1); + return (xsize == 0 || ysize == 0 + || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0)); + } + + if (GET_CODE (y) == PLUS + && (y1 = canon_rtx (XEXP (y, 0))) + && CONSTANT_P (y1)) + return 0; + + return 1; + } + + if (GET_CODE (x) == PLUS) + { + /* The fact that X is canonicalized means that this + PLUS rtx is canonicalized. */ + rtx x0 = XEXP (x, 0); + rtx x1 = XEXP (x, 1); + + if (GET_CODE (y) == PLUS) + { + /* The fact that Y is canonicalized means that this + PLUS rtx is canonicalized. */ + rtx y0 = XEXP (y, 0); + rtx y1 = XEXP (y, 1); + + if (rtx_equal_for_memref_p (x1, y1)) + return memrefs_conflict_p (xsize, x0, ysize, y0, c); + if (rtx_equal_for_memref_p (x0, y0)) + return memrefs_conflict_p (xsize, x1, ysize, y1, c); + if (GET_CODE (x1) == CONST_INT) + if (GET_CODE (y1) == CONST_INT) + return memrefs_conflict_p (xsize, x0, ysize, y0, + c - INTVAL (x1) + INTVAL (y1)); + else + return memrefs_conflict_p (xsize, x0, ysize, y, c - INTVAL (x1)); + else if (GET_CODE (y1) == CONST_INT) + return memrefs_conflict_p (xsize, x, ysize, y0, c + INTVAL (y1)); + + /* Handle case where we cannot understand iteration operators, + but we notice that the base addresses are distinct objects. */ + /* ??? Is this still necessary? */ + x = find_symbolic_term (x); + if (x == 0) + return 1; + y = find_symbolic_term (y); + if (y == 0) + return 1; + return rtx_equal_for_memref_p (x, y); + } + else if (GET_CODE (x1) == CONST_INT) + return memrefs_conflict_p (xsize, x0, ysize, y, c - INTVAL (x1)); + } + else if (GET_CODE (y) == PLUS) + { + /* The fact that Y is canonicalized means that this + PLUS rtx is canonicalized. */ + rtx y0 = XEXP (y, 0); + rtx y1 = XEXP (y, 1); + + if (GET_CODE (y1) == CONST_INT) + return memrefs_conflict_p (xsize, x, ysize, y0, c + INTVAL (y1)); + else + return 1; + } + + if (GET_CODE (x) == GET_CODE (y)) + switch (GET_CODE (x)) + { + case MULT: + { + /* Handle cases where we expect the second operands to be the + same, and check only whether the first operand would conflict + or not. */ + rtx x0, y0; + rtx x1 = canon_rtx (XEXP (x, 1)); + rtx y1 = canon_rtx (XEXP (y, 1)); + if (! rtx_equal_for_memref_p (x1, y1)) + return 1; + x0 = canon_rtx (XEXP (x, 0)); + y0 = canon_rtx (XEXP (y, 0)); + if (rtx_equal_for_memref_p (x0, y0)) + return (xsize == 0 || ysize == 0 + || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0)); + + /* Can't properly adjust our sizes. */ + if (GET_CODE (x1) != CONST_INT) + return 1; + xsize /= INTVAL (x1); + ysize /= INTVAL (x1); + c /= INTVAL (x1); + return memrefs_conflict_p (xsize, x0, ysize, y0, c); + } + } + + /* Treat an access through an AND (e.g. a subword access on an Alpha) + as an access with indeterminate size. */ + if (GET_CODE (x) == AND && GET_CODE (XEXP (x, 1)) == CONST_INT) + return memrefs_conflict_p (0, XEXP (x, 0), ysize, y, c); + if (GET_CODE (y) == AND && GET_CODE (XEXP (y, 1)) == CONST_INT) + return memrefs_conflict_p (xsize, x, 0, XEXP (y, 0), c); + + if (CONSTANT_P (x)) + { + if (GET_CODE (x) == CONST_INT && GET_CODE (y) == CONST_INT) + { + c += (INTVAL (y) - INTVAL (x)); + return (xsize == 0 || ysize == 0 + || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0)); + } + + if (GET_CODE (x) == CONST) + { + if (GET_CODE (y) == CONST) + return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)), + ysize, canon_rtx (XEXP (y, 0)), c); + else + return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)), + ysize, y, c); + } + if (GET_CODE (y) == CONST) + return memrefs_conflict_p (xsize, x, ysize, + canon_rtx (XEXP (y, 0)), c); + + if (CONSTANT_P (y)) + return (rtx_equal_for_memref_p (x, y) + && (xsize == 0 || ysize == 0 + || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0))); + + return 1; + } + return 1; +} + +/* Functions to compute memory dependencies. + + Since we process the insns in execution order, we can build tables + to keep track of what registers are fixed (and not aliased), what registers + are varying in known ways, and what registers are varying in unknown + ways. + + If both memory references are volatile, then there must always be a + dependence between the two references, since their order can not be + changed. A volatile and non-volatile reference can be interchanged + though. + + A MEM_IN_STRUCT reference at a non-QImode varying address can never + conflict with a non-MEM_IN_STRUCT reference at a fixed address. We must + allow QImode aliasing because the ANSI C standard allows character + pointers to alias anything. We are assuming that characters are + always QImode here. */ + +/* Read dependence: X is read after read in MEM takes place. There can + only be a dependence here if both reads are volatile. */ + +int +read_dependence (mem, x) + rtx mem; + rtx x; +{ + return MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem); +} + +/* True dependence: X is read after store in MEM takes place. */ + +int +true_dependence (mem, mem_mode, x, varies) + rtx mem; + enum machine_mode mem_mode; + rtx x; + int (*varies)(); +{ + rtx x_addr, mem_addr; + + if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem)) + return 1; + + x_addr = XEXP (x, 0); + mem_addr = XEXP (mem, 0); + + if (flag_alias_check && ! base_alias_check (x_addr, mem_addr)) + return 0; + + /* If X is an unchanging read, then it can't possibly conflict with any + non-unchanging store. It may conflict with an unchanging write though, + because there may be a single store to this address to initialize it. + Just fall through to the code below to resolve the case where we have + both an unchanging read and an unchanging write. This won't handle all + cases optimally, but the possible performance loss should be + negligible. */ + if (RTX_UNCHANGING_P (x) && ! RTX_UNCHANGING_P (mem)) + return 0; + + x_addr = canon_rtx (x_addr); + mem_addr = canon_rtx (mem_addr); + if (mem_mode == VOIDmode) + mem_mode = GET_MODE (mem); + + if (! memrefs_conflict_p (mem_mode, mem_addr, SIZE_FOR_MODE (x), x_addr, 0)) + return 0; + + /* If both references are struct references, or both are not, nothing + is known about aliasing. + + If either reference is QImode or BLKmode, ANSI C permits aliasing. + + If both addresses are constant, or both are not, nothing is known + about aliasing. */ + if (MEM_IN_STRUCT_P (x) == MEM_IN_STRUCT_P (mem) + || mem_mode == QImode || mem_mode == BLKmode + || GET_MODE (x) == QImode || GET_MODE (mem) == BLKmode + || varies (x_addr) == varies (mem_addr)) + return 1; + + /* One memory reference is to a constant address, one is not. + One is to a structure, the other is not. + + If either memory reference is a variable structure the other is a + fixed scalar and there is no aliasing. */ + if ((MEM_IN_STRUCT_P (mem) && varies (mem_addr)) + || (MEM_IN_STRUCT_P (x) && varies (x))) + return 0; + + return 1; +} + +/* Anti dependence: X is written after read in MEM takes place. */ + +int +anti_dependence (mem, x) + rtx mem; + rtx x; +{ + if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem)) + return 1; + + if (flag_alias_check && ! base_alias_check (XEXP (x, 0), XEXP (mem, 0))) + return 0; + + /* If MEM is an unchanging read, then it can't possibly conflict with + the store to X, because there is at most one store to MEM, and it must + have occurred somewhere before MEM. */ + x = canon_rtx (x); + mem = canon_rtx (mem); + if (RTX_UNCHANGING_P (mem)) + return 0; + + return (memrefs_conflict_p (SIZE_FOR_MODE (mem), XEXP (mem, 0), + SIZE_FOR_MODE (x), XEXP (x, 0), 0) + && ! (MEM_IN_STRUCT_P (mem) && rtx_addr_varies_p (mem) + && GET_MODE (mem) != QImode + && ! MEM_IN_STRUCT_P (x) && ! rtx_addr_varies_p (x)) + && ! (MEM_IN_STRUCT_P (x) && rtx_addr_varies_p (x) + && GET_MODE (x) != QImode + && ! MEM_IN_STRUCT_P (mem) && ! rtx_addr_varies_p (mem))); +} + +/* Output dependence: X is written after store in MEM takes place. */ + +int +output_dependence (mem, x) + register rtx mem; + register rtx x; +{ + if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem)) + return 1; + + if (flag_alias_check && !base_alias_check (XEXP (x, 0), XEXP (mem, 0))) + return 0; + + x = canon_rtx (x); + mem = canon_rtx (mem); + return (memrefs_conflict_p (SIZE_FOR_MODE (mem), XEXP (mem, 0), + SIZE_FOR_MODE (x), XEXP (x, 0), 0) + && ! (MEM_IN_STRUCT_P (mem) && rtx_addr_varies_p (mem) + && GET_MODE (mem) != QImode + && ! MEM_IN_STRUCT_P (x) && ! rtx_addr_varies_p (x)) + && ! (MEM_IN_STRUCT_P (x) && rtx_addr_varies_p (x) + && GET_MODE (x) != QImode + && ! MEM_IN_STRUCT_P (mem) && ! rtx_addr_varies_p (mem))); +} + +void +init_alias_analysis () +{ + int maxreg = max_reg_num (); + register int i; + register rtx insn; + rtx note; + rtx set; + int changed; + + reg_known_value_size = maxreg; + + reg_known_value + = (rtx *) oballoc ((maxreg - FIRST_PSEUDO_REGISTER) * sizeof (rtx)) + - FIRST_PSEUDO_REGISTER; + reg_known_equiv_p = + oballoc (maxreg - FIRST_PSEUDO_REGISTER) - FIRST_PSEUDO_REGISTER; + bzero ((char *) (reg_known_value + FIRST_PSEUDO_REGISTER), + (maxreg-FIRST_PSEUDO_REGISTER) * sizeof (rtx)); + bzero (reg_known_equiv_p + FIRST_PSEUDO_REGISTER, + (maxreg - FIRST_PSEUDO_REGISTER) * sizeof (char)); + + if (flag_alias_check) + { + /* Overallocate reg_base_value to allow some growth during loop + optimization. Loop unrolling can create a large number of + registers. */ + reg_base_value_size = maxreg * 2; + reg_base_value = (rtx *)oballoc (reg_base_value_size * sizeof (rtx)); + reg_seen = (char *)alloca (reg_base_value_size); + bzero (reg_base_value, reg_base_value_size * sizeof (rtx)); + bzero (reg_seen, reg_base_value_size); + + /* Mark all hard registers which may contain an address. + The stack, frame and argument pointers may contain an address. + An argument register which can hold a Pmode value may contain + an address even if it is not in BASE_REGS. + + The address expression is VOIDmode for an argument and + Pmode for other registers. */ + for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) + if (FUNCTION_ARG_REGNO_P (i) && HARD_REGNO_MODE_OK (i, Pmode)) + reg_base_value[i] = gen_rtx (ADDRESS, VOIDmode, + gen_rtx (REG, Pmode, i)); + + reg_base_value[STACK_POINTER_REGNUM] + = gen_rtx (ADDRESS, Pmode, stack_pointer_rtx); + reg_base_value[ARG_POINTER_REGNUM] + = gen_rtx (ADDRESS, Pmode, arg_pointer_rtx); + reg_base_value[FRAME_POINTER_REGNUM] + = gen_rtx (ADDRESS, Pmode, frame_pointer_rtx); + reg_base_value[HARD_FRAME_POINTER_REGNUM] + = gen_rtx (ADDRESS, Pmode, hard_frame_pointer_rtx); + } + + copying_arguments = 1; + /* Fill in the entries with known constant values. */ + for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) + { + if (flag_alias_check && GET_RTX_CLASS (GET_CODE (insn)) == 'i') + { + /* If this insn has a noalias note, process it, Otherwise, + scan for sets. A simple set will have no side effects + which could change the base value of any other register. */ + rtx noalias_note; + if (GET_CODE (PATTERN (insn)) == SET + && (noalias_note = find_reg_note (insn, REG_NOALIAS, NULL_RTX))) + record_set(SET_DEST (PATTERN (insn)), 0); + else + note_stores (PATTERN (insn), record_set); + } + else if (GET_CODE (insn) == NOTE + && NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_BEG) + copying_arguments = 0; + + if ((set = single_set (insn)) != 0 + && GET_CODE (SET_DEST (set)) == REG + && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER + && (((note = find_reg_note (insn, REG_EQUAL, 0)) != 0 + && reg_n_sets[REGNO (SET_DEST (set))] == 1) + || (note = find_reg_note (insn, REG_EQUIV, NULL_RTX)) != 0) + && GET_CODE (XEXP (note, 0)) != EXPR_LIST) + { + int regno = REGNO (SET_DEST (set)); + reg_known_value[regno] = XEXP (note, 0); + reg_known_equiv_p[regno] = REG_NOTE_KIND (note) == REG_EQUIV; + } + } + + /* Fill in the remaining entries. */ + for (i = FIRST_PSEUDO_REGISTER; i < maxreg; i++) + if (reg_known_value[i] == 0) + reg_known_value[i] = regno_reg_rtx[i]; + + if (! flag_alias_check) + return; + + /* Simplify the reg_base_value array so that no register refers to + another register, except to special registers indirectly through + ADDRESS expressions. + + In theory this loop can take as long as O(registers^2), but unless + there are very long dependency chains it will run in close to linear + time. */ + do + { + changed = 0; + for (i = FIRST_PSEUDO_REGISTER; i < reg_base_value_size; i++) + { + rtx base = reg_base_value[i]; + if (base && GET_CODE (base) == REG) + { + int base_regno = REGNO (base); + if (base_regno == i) /* register set from itself */ + reg_base_value[i] = 0; + else + reg_base_value[i] = reg_base_value[base_regno]; + changed = 1; + } + } + } + while (changed); + + reg_seen = 0; +} + +void +end_alias_analysis () +{ + reg_known_value = 0; + reg_base_value = 0; + reg_base_value_size = 0; +} diff --git a/gnu/usr.bin/gcc/calls.c b/gnu/usr.bin/gcc/calls.c index ad05be4f7c0..5eedf493af1 100644 --- a/gnu/usr.bin/gcc/calls.c +++ b/gnu/usr.bin/gcc/calls.c @@ -563,6 +563,8 @@ expand_call (exp, target, ignore) /* Nonzero if it is plausible that this is a call to alloca. */ int may_be_alloca; + /* Nonzero if this is a call to malloc or a related function. */ + int is_malloc; /* Nonzero if this is a call to setjmp or a related function. */ int returns_twice; /* Nonzero if this is a call to `longjmp'. */ @@ -851,6 +853,7 @@ expand_call (exp, target, ignore) returns_twice = 0; is_longjmp = 0; + is_malloc = 0; if (name != 0 && IDENTIFIER_LENGTH (DECL_NAME (fndecl)) <= 15) { @@ -890,6 +893,10 @@ expand_call (exp, target, ignore) else if (tname[0] == 'l' && tname[1] == 'o' && ! strcmp (tname, "longjmp")) is_longjmp = 1; + /* Only recognize malloc when alias analysis is enabled. */ + else if (tname[0] == 'm' && flag_alias_check + && ! strcmp(tname, "malloc")) + is_malloc = 1; } if (may_be_alloca) @@ -1362,7 +1369,7 @@ expand_call (exp, target, ignore) /* Now we are about to start emitting insns that can be deleted if a libcall is deleted. */ - if (is_const) + if (is_const || is_malloc) start_sequence (); /* If we have no actual push instructions, or shouldn't use them, @@ -1951,6 +1958,20 @@ expand_call (exp, target, ignore) end_sequence (); emit_insns (insns); } + else if (is_malloc) + { + rtx temp = gen_reg_rtx (GET_MODE (valreg)); + rtx last, insns; + + emit_move_insn (temp, valreg); + last = get_last_insn (); + REG_NOTES (last) = + gen_rtx (EXPR_LIST, REG_NOALIAS, temp, REG_NOTES (last)); + insns = get_insns (); + end_sequence (); + emit_insns (insns); + valreg = temp; + } /* For calls to `setjmp', etc., inform flow.c it should complain if nonvolatile values are live. */ diff --git a/gnu/usr.bin/gcc/combine.c b/gnu/usr.bin/gcc/combine.c index 473adc83460..e33fc10ce37 100644 --- a/gnu/usr.bin/gcc/combine.c +++ b/gnu/usr.bin/gcc/combine.c @@ -10647,6 +10647,7 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1) case REG_EQUAL: case REG_EQUIV: case REG_NONNEG: + case REG_NOALIAS: /* These notes say something about results of an insn. We can only support them if they used to be on I3 in which case they remain on I3. Otherwise they are ignored. diff --git a/gnu/usr.bin/gcc/config/alpha/alpha.c b/gnu/usr.bin/gcc/config/alpha/alpha.c index 0efe27ca733..fc8e9ec0dec 100644 --- a/gnu/usr.bin/gcc/config/alpha/alpha.c +++ b/gnu/usr.bin/gcc/config/alpha/alpha.c @@ -1369,6 +1369,11 @@ output_prolog (file, size) We never need a GP for Windows/NT. */ alpha_function_needs_gp = 0; +#ifdef __linux__ + if(profile_flag) { + alpha_function_needs_gp = 1; + } +#endif for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) if ((GET_CODE (insn) == CALL_INSN) || (GET_RTX_CLASS (GET_CODE (insn)) == 'i' diff --git a/gnu/usr.bin/gcc/config/alpha/alpha.md b/gnu/usr.bin/gcc/config/alpha/alpha.md index 72c54eee371..7ba3a50d682 100644 --- a/gnu/usr.bin/gcc/config/alpha/alpha.md +++ b/gnu/usr.bin/gcc/config/alpha/alpha.md @@ -1745,9 +1745,9 @@ [(set (match_operand:DF 0 "register_operand" "=f,f") (if_then_else:DF (match_operator 3 "signed_comparison_operator" - [(match_operand:DF 1 "reg_or_fp0_operand" "fG,fG") + [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG") (match_operand:DF 2 "fp0_operand" "G,G")]) - (float_extend:DF (match_operand:SF 4 "reg_or_fp0_operand" "fG,0")) + (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG,0")) (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))] "TARGET_FP" "@ diff --git a/gnu/usr.bin/gcc/config/alpha/x-linux b/gnu/usr.bin/gcc/config/alpha/x-linux new file mode 100644 index 00000000000..c3b3fbf43a7 --- /dev/null +++ b/gnu/usr.bin/gcc/config/alpha/x-linux @@ -0,0 +1 @@ +CLIB=-lbfd -liberty diff --git a/gnu/usr.bin/gcc/config/alpha/xm-alpha.h b/gnu/usr.bin/gcc/config/alpha/xm-alpha.h index 642e1cf1a6e..ed925b20f17 100644 --- a/gnu/usr.bin/gcc/config/alpha/xm-alpha.h +++ b/gnu/usr.bin/gcc/config/alpha/xm-alpha.h @@ -45,8 +45,10 @@ Boston, MA 02111-1307, USA. */ #if !defined(__GNUC__) && !defined(_WIN32) #include <alloca.h> #else +#ifndef __alpha__ extern void *alloca (); #endif +#endif /* The host compiler has problems with enum bitfields since it makes them signed so we can't fit all our codes in. */ @@ -67,7 +69,9 @@ extern void *malloc (), *realloc (), *calloc (); /* OSF/1 has vprintf. */ +#ifndef linux /* 1996/02/22 mauro@craftwork.com -- unreliable with Linux */ #define HAVE_VPRINTF +#endif /* OSF/1 has putenv. */ diff --git a/gnu/usr.bin/gcc/config/x-linux b/gnu/usr.bin/gcc/config/x-linux index ea2a5f270b3..eeca9d1d843 100644 --- a/gnu/usr.bin/gcc/config/x-linux +++ b/gnu/usr.bin/gcc/config/x-linux @@ -12,3 +12,6 @@ BOOT_CFLAGS = -O $(CFLAGS) -Iinclude # Don't run fixproto STMP_FIXPROTO = + +# Don't install "assert.h" in gcc. We use the one in glibc. +INSTALL_ASSERT_H = diff --git a/gnu/usr.bin/gcc/configure b/gnu/usr.bin/gcc/configure index e072cbf286e..5a0a5b72a13 100644 --- a/gnu/usr.bin/gcc/configure +++ b/gnu/usr.bin/gcc/configure @@ -81,6 +81,7 @@ exec_prefix='$(prefix)' # # The default g++ include directory is $(libdir)/g++-include. gxx_include_dir='$(libdir)/g++-include' +#gxx_include_dir='$(exec_prefix)/include/g++' # Default --program-transform-name to nothing. program_transform_name= @@ -555,6 +556,13 @@ for machine in $canon_build $canon_host $canon_target; do tmake_file=t-libc-ok xmake_file=x-openbsd ;; + alpha-*-linux*) + tm_file=alpha/linux.h + tmake_file=alpha/t-linux + xmake_file=alpha/x-linux + fixincludes=Makefile.in + xm_file=alpha/xm-linux.h + ;; alpha-dec-osf[23456789]*) tm_file=alpha/osf2.h if [ x$stabs = xyes ] @@ -1001,7 +1009,7 @@ for machine in $canon_build $canon_host $canon_target; do i[345]86-*-linux*oldld*) # Intel 80386's running Linux cpu_type=i386 # with a.out format using pre BFD linkers xm_file=i386/xm-linux.h - xmake_file=x-linux + xmake_file=x-linux-aout tm_file=i386/linux-oldld.h fixincludes=Makefile.in #On Linux, the headers are ok already. broken_install=yes @@ -1010,7 +1018,7 @@ for machine in $canon_build $canon_host $canon_target; do i[345]86-*-linux*aout*) # Intel 80386's running Linux cpu_type=i386 # with a.out format xm_file=i386/xm-linux.h - xmake_file=x-linux + xmake_file=x-linux-aout tm_file=i386/linux-aout.h fixincludes=Makefile.in #On Linux, the headers are ok already. broken_install=yes @@ -1019,7 +1027,7 @@ for machine in $canon_build $canon_host $canon_target; do i[345]86-*-linux*) # Intel 80386's running Linux cpu_type=i386 # with ELF format xm_file=i386/xm-linux.h - xmake_file=x-linux + xmake_file=x-linux-aout tm_file=i386/linux.h fixincludes=Makefile.in #On Linux, the headers are ok already. broken_install=yes diff --git a/gnu/usr.bin/gcc/cse.c b/gnu/usr.bin/gcc/cse.c index efd05dedaf9..e6d2884245f 100644 --- a/gnu/usr.bin/gcc/cse.c +++ b/gnu/usr.bin/gcc/cse.c @@ -519,27 +519,6 @@ static struct table_elt *last_jump_equiv_class; static int constant_pool_entries_cost; -/* Bits describing what kind of values in memory must be invalidated - for a particular instruction. If all three bits are zero, - no memory refs need to be invalidated. Each bit is more powerful - than the preceding ones, and if a bit is set then the preceding - bits are also set. - - Here is how the bits are set: - Pushing onto the stack invalidates only the stack pointer, - writing at a fixed address invalidates only variable addresses, - writing in a structure element at variable address - invalidates all but scalar variables, - and writing in anything else at variable address invalidates everything. */ - -struct write_data -{ - int sp : 1; /* Invalidate stack pointer. */ - int var : 1; /* Invalidate variable addresses. */ - int nonscalar : 1; /* Invalidate all but scalar variables. */ - int all : 1; /* Invalidate all memory refs. */ -}; - /* Define maximum length of a branch path. */ #define PATHLENGTH 10 @@ -625,9 +604,10 @@ static struct table_elt *insert PROTO((rtx, struct table_elt *, unsigned, static void merge_equiv_classes PROTO((struct table_elt *, struct table_elt *)); static void invalidate PROTO((rtx, enum machine_mode)); +static int cse_rtx_varies_p PROTO((rtx)); static void remove_invalid_refs PROTO((int)); static void rehash_using_reg PROTO((rtx)); -static void invalidate_memory PROTO((struct write_data *)); +static void invalidate_memory PROTO((void)); static void invalidate_for_call PROTO((void)); static rtx use_related_value PROTO((rtx, struct table_elt *)); static unsigned canon_hash PROTO((rtx, enum machine_mode)); @@ -637,9 +617,6 @@ static void set_nonvarying_address_components PROTO((rtx, int, rtx *, HOST_WIDE_INT *, HOST_WIDE_INT *)); static int refers_to_p PROTO((rtx, rtx)); -static int refers_to_mem_p PROTO((rtx, rtx, HOST_WIDE_INT, - HOST_WIDE_INT)); -static int cse_rtx_addr_varies_p PROTO((rtx)); static rtx canon_reg PROTO((rtx, rtx)); static void find_best_addr PROTO((rtx, rtx *)); static enum rtx_code find_comparison_args PROTO((enum rtx_code, rtx *, rtx *, @@ -655,8 +632,8 @@ static void record_jump_equiv PROTO((rtx, int)); static void record_jump_cond PROTO((enum rtx_code, enum machine_mode, rtx, rtx, int)); static void cse_insn PROTO((rtx, int)); -static void note_mem_written PROTO((rtx, struct write_data *)); -static void invalidate_from_clobbers PROTO((struct write_data *, rtx)); +static int note_mem_written PROTO((rtx)); +static void invalidate_from_clobbers PROTO((rtx)); static rtx cse_process_notes PROTO((rtx, rtx)); static void cse_around_loop PROTO((rtx)); static void invalidate_skipped_set PROTO((rtx, rtx)); @@ -1511,8 +1488,6 @@ invalidate (x, full_mode) { register int i; register struct table_elt *p; - rtx base; - HOST_WIDE_INT start, end; /* If X is a register, dependencies on its contents are recorded through the qty number mechanism. @@ -1604,16 +1579,17 @@ invalidate (x, full_mode) if (full_mode == VOIDmode) full_mode = GET_MODE (x); - set_nonvarying_address_components (XEXP (x, 0), GET_MODE_SIZE (full_mode), - &base, &start, &end); - for (i = 0; i < NBUCKETS; i++) { register struct table_elt *next; for (p = table[i]; p; p = next) { next = p->next_same_hash; - if (refers_to_mem_p (p->exp, base, start, end)) + /* Invalidate ASM_OPERANDS which reference memory (this is easier + than checking all the aliases). */ + if (p->in_memory + && (GET_CODE (p->exp) != MEM + || true_dependence (x, full_mode, p->exp, cse_rtx_varies_p))) remove_from_table (p, i); } } @@ -1694,30 +1670,6 @@ rehash_using_reg (x) } } -/* Remove from the hash table all expressions that reference memory, - or some of them as specified by *WRITES. */ - -static void -invalidate_memory (writes) - struct write_data *writes; -{ - register int i; - register struct table_elt *p, *next; - int all = writes->all; - int nonscalar = writes->nonscalar; - - for (i = 0; i < NBUCKETS; i++) - for (p = table[i]; p; p = next) - { - next = p->next_same_hash; - if (p->in_memory - && (all - || (nonscalar && p->in_struct) - || cse_rtx_addr_varies_p (p->exp))) - remove_from_table (p, i); - } -} - /* Remove from the hash table any expression that is a call-clobbered register. Also update their TICK values. */ @@ -1755,6 +1707,12 @@ invalidate_for_call () { next = p->next_same_hash; + if (p->in_memory) + { + remove_from_table (p, hash); + continue; + } + if (GET_CODE (p->exp) != REG || REGNO (p->exp) >= FIRST_PSEUDO_REGISTER) continue; @@ -2394,105 +2352,31 @@ set_nonvarying_address_components (addr, size, pbase, pstart, pend) *pend = end; } -/* Return 1 iff any subexpression of X refers to memory - at an address of BASE plus some offset - such that any of the bytes' offsets fall between START (inclusive) - and END (exclusive). - - The value is undefined if X is a varying address (as determined by - cse_rtx_addr_varies_p). This function is not used in such cases. - - When used in the cse pass, `qty_const' is nonzero, and it is used - to treat an address that is a register with a known constant value - as if it were that constant value. - In the loop pass, `qty_const' is zero, so this is not done. */ - -static int -refers_to_mem_p (x, base, start, end) - rtx x, base; - HOST_WIDE_INT start, end; -{ - register HOST_WIDE_INT i; - register enum rtx_code code; - register char *fmt; - - repeat: - if (x == 0) - return 0; - - code = GET_CODE (x); - if (code == MEM) - { - register rtx addr = XEXP (x, 0); /* Get the address. */ - rtx mybase; - HOST_WIDE_INT mystart, myend; - - set_nonvarying_address_components (addr, GET_MODE_SIZE (GET_MODE (x)), - &mybase, &mystart, &myend); - - - /* refers_to_mem_p is never called with varying addresses. - If the base addresses are not equal, there is no chance - of the memory addresses conflicting. */ - if (! rtx_equal_p (mybase, base)) - return 0; - - return myend > start && mystart < end; - } - - /* X does not match, so try its subexpressions. */ - - fmt = GET_RTX_FORMAT (code); - for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) - if (fmt[i] == 'e') - { - if (i == 0) - { - x = XEXP (x, 0); - goto repeat; - } - else - if (refers_to_mem_p (XEXP (x, i), base, start, end)) - return 1; - } - else if (fmt[i] == 'E') - { - int j; - for (j = 0; j < XVECLEN (x, i); j++) - if (refers_to_mem_p (XVECEXP (x, i, j), base, start, end)) - return 1; - } - - return 0; -} - -/* Nonzero if X refers to memory at a varying address; +/* Nonzero if X, a memory address, refers to a varying address; except that a register which has at the moment a known constant value isn't considered variable. */ static int -cse_rtx_addr_varies_p (x) - rtx x; +cse_rtx_varies_p (x) + register rtx x; { /* We need not check for X and the equivalence class being of the same mode because if X is equivalent to a constant in some mode, it doesn't vary in any mode. */ - if (GET_CODE (x) == MEM - && GET_CODE (XEXP (x, 0)) == REG - && REGNO_QTY_VALID_P (REGNO (XEXP (x, 0))) - && GET_MODE (XEXP (x, 0)) == qty_mode[reg_qty[REGNO (XEXP (x, 0))]] - && qty_const[reg_qty[REGNO (XEXP (x, 0))]] != 0) + if (GET_CODE (x) == REG + && REGNO_QTY_VALID_P (REGNO (x)) + && GET_MODE (x) == qty_mode[reg_qty[REGNO (x)]] + && qty_const[reg_qty[REGNO (x)]] != 0) return 0; - if (GET_CODE (x) == MEM - && GET_CODE (XEXP (x, 0)) == PLUS - && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT - && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG - && REGNO_QTY_VALID_P (REGNO (XEXP (XEXP (x, 0), 0))) - && (GET_MODE (XEXP (XEXP (x, 0), 0)) - == qty_mode[reg_qty[REGNO (XEXP (XEXP (x, 0), 0))]]) - && qty_const[reg_qty[REGNO (XEXP (XEXP (x, 0), 0))]]) + if (GET_CODE (x) == PLUS + && GET_CODE (XEXP (x, 1)) == CONST_INT + && GET_CODE (XEXP (x, 0)) == REG + && REGNO_QTY_VALID_P (REGNO (XEXP (x, 0))) + && (GET_MODE (XEXP (x, 0)) + == qty_mode[reg_qty[REGNO (XEXP (x, 0))]]) + && qty_const[reg_qty[REGNO (XEXP (x, 0))]]) return 0; /* This can happen as the result of virtual register instantiation, if @@ -2500,21 +2384,20 @@ cse_rtx_addr_varies_p (x) us a three instruction sequence, load large offset into a register, load fp minus a constant into a register, then a MEM which is the sum of the two `constant' registers. */ - if (GET_CODE (x) == MEM - && GET_CODE (XEXP (x, 0)) == PLUS - && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG - && GET_CODE (XEXP (XEXP (x, 0), 1)) == REG - && REGNO_QTY_VALID_P (REGNO (XEXP (XEXP (x, 0), 0))) - && (GET_MODE (XEXP (XEXP (x, 0), 0)) - == qty_mode[reg_qty[REGNO (XEXP (XEXP (x, 0), 0))]]) - && qty_const[reg_qty[REGNO (XEXP (XEXP (x, 0), 0))]] - && REGNO_QTY_VALID_P (REGNO (XEXP (XEXP (x, 0), 1))) - && (GET_MODE (XEXP (XEXP (x, 0), 1)) - == qty_mode[reg_qty[REGNO (XEXP (XEXP (x, 0), 1))]]) - && qty_const[reg_qty[REGNO (XEXP (XEXP (x, 0), 1))]]) + if (GET_CODE (x) == PLUS + && GET_CODE (XEXP (x, 0)) == REG + && GET_CODE (XEXP (x, 1)) == REG + && REGNO_QTY_VALID_P (REGNO (XEXP (x, 0))) + && (GET_MODE (XEXP (x, 0)) + == qty_mode[reg_qty[REGNO (XEXP (x, 0))]]) + && qty_const[reg_qty[REGNO (XEXP (x, 0))]] + && REGNO_QTY_VALID_P (REGNO (XEXP (x, 1))) + && (GET_MODE (XEXP (x, 1)) + == qty_mode[reg_qty[REGNO (XEXP (x, 1))]]) + && qty_const[reg_qty[REGNO (XEXP (x, 1))]]) return 0; - return rtx_addr_varies_p (x); + return rtx_varies_p (x); } /* Canonicalize an expression: @@ -6104,8 +5987,6 @@ cse_insn (insn, in_libcall_block) /* Records what this insn does to set CC0. */ rtx this_insn_cc0 = 0; enum machine_mode this_insn_cc0_mode; - struct write_data writes_memory; - static struct write_data init = {0, 0, 0, 0}; rtx src_eqv = 0; struct table_elt *src_eqv_elt = 0; @@ -6117,7 +5998,6 @@ cse_insn (insn, in_libcall_block) struct set *sets; this_insn = insn; - writes_memory = init; /* Find all the SETs and CLOBBERs in this instruction. Record all the SETs in the array `set' and count them. @@ -6219,14 +6099,13 @@ cse_insn (insn, in_libcall_block) } else if (GET_CODE (y) == CLOBBER) { - /* If we clobber memory, take note of that, - and canon the address. + /* If we clobber memory, canon the address. This does nothing when a register is clobbered because we have already invalidated the reg. */ if (GET_CODE (XEXP (y, 0)) == MEM) { canon_reg (XEXP (y, 0), NULL_RTX); - note_mem_written (XEXP (y, 0), &writes_memory); + note_mem_written (XEXP (y, 0)); } } else if (GET_CODE (y) == USE @@ -6248,7 +6127,7 @@ cse_insn (insn, in_libcall_block) if (GET_CODE (XEXP (x, 0)) == MEM) { canon_reg (XEXP (x, 0), NULL_RTX); - note_mem_written (XEXP (x, 0), &writes_memory); + note_mem_written (XEXP (x, 0)); } } @@ -6673,7 +6552,7 @@ cse_insn (insn, in_libcall_block) } } #endif /* LOAD_EXTEND_OP */ - + if (src == src_folded) src_folded = 0; @@ -6859,7 +6738,8 @@ cse_insn (insn, in_libcall_block) && (src_folded == 0 || (GET_CODE (src_folded) != MEM && ! src_folded_force_flag)) - && GET_MODE_CLASS (mode) != MODE_CC) + && GET_MODE_CLASS (mode) != MODE_CC + && mode != VOIDmode) { src_folded_force_flag = 1; src_folded = trial; @@ -6983,12 +6863,7 @@ cse_insn (insn, in_libcall_block) if (GET_CODE (dest) == MEM) { dest = fold_rtx (dest, insn); - - /* Decide whether we invalidate everything in memory, - or just things at non-fixed places. - Writing a large aggregate must invalidate everything - because we don't know how long it is. */ - note_mem_written (dest, &writes_memory); + note_mem_written (dest); } /* Compute the hash code of the destination now, @@ -7233,17 +7108,15 @@ cse_insn (insn, in_libcall_block) so that the destination goes into that class. */ sets[i].src_elt = src_eqv_elt; - invalidate_from_clobbers (&writes_memory, x); + invalidate_from_clobbers (x); /* Some registers are invalidated by subroutine calls. Memory is invalidated by non-constant calls. */ if (GET_CODE (insn) == CALL_INSN) { - static struct write_data everything = {0, 1, 1, 1}; - if (! CONST_CALL_P (insn)) - invalidate_memory (&everything); + invalidate_memory (); invalidate_for_call (); } @@ -7264,8 +7137,7 @@ cse_insn (insn, in_libcall_block) Needed for memory if this is a nonvarying address, unless we have just done an invalidate_memory that covers even those. */ if (GET_CODE (dest) == REG || GET_CODE (dest) == SUBREG - || (GET_CODE (dest) == MEM && ! writes_memory.all - && ! cse_rtx_addr_varies_p (dest))) + || GET_CODE (dest) == MEM) invalidate (dest, VOIDmode); else if (GET_CODE (dest) == STRICT_LOW_PART || GET_CODE (dest) == ZERO_EXTRACT) @@ -7531,51 +7403,46 @@ cse_insn (insn, in_libcall_block) prev_insn = insn; } -/* Store 1 in *WRITES_PTR for those categories of memory ref - that must be invalidated when the expression WRITTEN is stored in. - If WRITTEN is null, say everything must be invalidated. */ - static void -note_mem_written (written, writes_ptr) - rtx written; - struct write_data *writes_ptr; +invalidate_memory () { - static struct write_data everything = {0, 1, 1, 1}; + register int i; + register struct table_elt *p, *next; + + for (i = 0; i < NBUCKETS; i++) + for (p = table[i]; p; p = next) + { + next = p->next_same_hash; + if (p->in_memory) + remove_from_table (p, i); + } +} - if (written == 0) - *writes_ptr = everything; - else if (GET_CODE (written) == MEM) +static int +note_mem_written (mem) + register rtx mem; +{ + if (mem == 0 || GET_CODE(mem) != MEM ) + return 0; + else + { + register rtx addr = XEXP (mem, 0); + /* Pushing or popping the stack invalidates just the stack pointer. */ + if ((GET_CODE (addr) == PRE_DEC || GET_CODE (addr) == PRE_INC + || GET_CODE (addr) == POST_DEC || GET_CODE (addr) == POST_INC) + && GET_CODE (XEXP (addr, 0)) == REG + && REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM) { - /* Pushing or popping the stack invalidates just the stack pointer. */ - rtx addr = XEXP (written, 0); - if ((GET_CODE (addr) == PRE_DEC || GET_CODE (addr) == PRE_INC - || GET_CODE (addr) == POST_DEC || GET_CODE (addr) == POST_INC) - && GET_CODE (XEXP (addr, 0)) == REG - && REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM) - { - writes_ptr->sp = 1; - return; - } - else if (GET_MODE (written) == BLKmode) - *writes_ptr = everything; - /* (mem (scratch)) means clobber everything. */ - else if (GET_CODE (addr) == SCRATCH) - *writes_ptr = everything; - else if (cse_rtx_addr_varies_p (written)) - { - /* A varying address that is a sum indicates an array element, - and that's just as good as a structure element - in implying that we need not invalidate scalar variables. - However, we must allow QImode aliasing of scalars, because the - ANSI C standard allows character pointers to alias anything. */ - if (! ((MEM_IN_STRUCT_P (written) - || GET_CODE (XEXP (written, 0)) == PLUS) - && GET_MODE (written) != QImode)) - writes_ptr->all = 1; - writes_ptr->nonscalar = 1; - } - writes_ptr->var = 1; + if (reg_tick[STACK_POINTER_REGNUM] >= 0) + reg_tick[STACK_POINTER_REGNUM]++; + + /* This should be *very* rare. */ + if (TEST_HARD_REG_BIT (hard_regs_in_table, STACK_POINTER_REGNUM)) + invalidate (stack_pointer_rtx, VOIDmode); + return 1; } + return 0; + } } /* Perform invalidation on the basis of everything about an insn @@ -7583,38 +7450,19 @@ note_mem_written (written, writes_ptr) This includes the places CLOBBERed, and anything that might alias with something that is SET or CLOBBERed. - W points to the writes_memory for this insn, a struct write_data - saying which kinds of memory references must be invalidated. X is the pattern of the insn. */ static void -invalidate_from_clobbers (w, x) - struct write_data *w; +invalidate_from_clobbers (x) rtx x; { - /* If W->var is not set, W specifies no action. - If W->all is set, this step gets all memory refs - so they can be ignored in the rest of this function. */ - if (w->var) - invalidate_memory (w); - - if (w->sp) - { - if (reg_tick[STACK_POINTER_REGNUM] >= 0) - reg_tick[STACK_POINTER_REGNUM]++; - - /* This should be *very* rare. */ - if (TEST_HARD_REG_BIT (hard_regs_in_table, STACK_POINTER_REGNUM)) - invalidate (stack_pointer_rtx, VOIDmode); - } - if (GET_CODE (x) == CLOBBER) { rtx ref = XEXP (x, 0); if (ref) { if (GET_CODE (ref) == REG || GET_CODE (ref) == SUBREG - || (GET_CODE (ref) == MEM && ! w->all)) + || GET_CODE (ref) == MEM) invalidate (ref, VOIDmode); else if (GET_CODE (ref) == STRICT_LOW_PART || GET_CODE (ref) == ZERO_EXTRACT) @@ -7633,7 +7481,7 @@ invalidate_from_clobbers (w, x) if (ref) { if (GET_CODE (ref) == REG || GET_CODE (ref) == SUBREG - || (GET_CODE (ref) == MEM && !w->all)) + || GET_CODE (ref) == MEM) invalidate (ref, VOIDmode); else if (GET_CODE (ref) == STRICT_LOW_PART || GET_CODE (ref) == ZERO_EXTRACT) @@ -7799,10 +7647,6 @@ cse_around_loop (loop_start) } } -/* Variable used for communications between the next two routines. */ - -static struct write_data skipped_writes_memory; - /* Process one SET of an insn that was skipped. We ignore CLOBBERs since they are done elsewhere. This function is called via note_stores. */ @@ -7811,6 +7655,22 @@ invalidate_skipped_set (dest, set) rtx set; rtx dest; { + enum rtx_code code = GET_CODE (dest); + + if (code == MEM + && ! note_mem_written (dest) /* If this is not a stack push ... */ + /* There are times when an address can appear varying and be a PLUS + during this scan when it would be a fixed address were we to know + the proper equivalences. So invalidate all memory if there is + a BLKmode or nonscalar memory reference or a reference to a + variable address. */ + && (MEM_IN_STRUCT_P (dest) || GET_MODE (dest) == BLKmode + || cse_rtx_varies_p (XEXP (dest, 0)))) + { + invalidate_memory (); + return; + } + if (GET_CODE (set) == CLOBBER #ifdef HAVE_cc0 || dest == cc0_rtx @@ -7818,21 +7678,10 @@ invalidate_skipped_set (dest, set) || dest == pc_rtx) return; - if (GET_CODE (dest) == MEM) - note_mem_written (dest, &skipped_writes_memory); - - /* There are times when an address can appear varying and be a PLUS - during this scan when it would be a fixed address were we to know - the proper equivalences. So promote "nonscalar" to be "all". */ - if (skipped_writes_memory.nonscalar) - skipped_writes_memory.all = 1; - - if (GET_CODE (dest) == REG || GET_CODE (dest) == SUBREG - || (! skipped_writes_memory.all && ! cse_rtx_addr_varies_p (dest))) - invalidate (dest, VOIDmode); - else if (GET_CODE (dest) == STRICT_LOW_PART - || GET_CODE (dest) == ZERO_EXTRACT) + if (code == STRICT_LOW_PART || code == ZERO_EXTRACT) invalidate (XEXP (dest, 0), GET_MODE (dest)); + else if (code == REG || code == SUBREG || code == MEM) + invalidate (dest, VOIDmode); } /* Invalidate all insns from START up to the end of the function or the @@ -7844,8 +7693,6 @@ invalidate_skipped_block (start) rtx start; { rtx insn; - static struct write_data init = {0, 0, 0, 0}; - static struct write_data everything = {0, 1, 1, 1}; for (insn = start; insn && GET_CODE (insn) != CODE_LABEL; insn = NEXT_INSN (insn)) @@ -7853,16 +7700,14 @@ invalidate_skipped_block (start) if (GET_RTX_CLASS (GET_CODE (insn)) != 'i') continue; - skipped_writes_memory = init; - if (GET_CODE (insn) == CALL_INSN) { + if (! CONST_CALL_P (insn)) + invalidate_memory (); invalidate_for_call (); - skipped_writes_memory = everything; } note_stores (PATTERN (insn), invalidate_skipped_set); - invalidate_from_clobbers (&skipped_writes_memory, PATTERN (insn)); } } @@ -7912,10 +7757,6 @@ cse_set_around_loop (x, insn, loop_start) rtx loop_start; { struct table_elt *src_elt; - static struct write_data init = {0, 0, 0, 0}; - struct write_data writes_memory; - - writes_memory = init; /* If this is a SET, see if we can replace SET_SRC, but ignore SETs that are setting PC or CC0 or whose SET_SRC is already a register. */ @@ -7975,18 +7816,14 @@ cse_set_around_loop (x, insn, loop_start) } /* Now invalidate anything modified by X. */ - note_mem_written (SET_DEST (x), &writes_memory); - - if (writes_memory.var) - invalidate_memory (&writes_memory); - - /* See comment on similar code in cse_insn for explanation of these tests. */ - if (GET_CODE (SET_DEST (x)) == REG || GET_CODE (SET_DEST (x)) == SUBREG - || (GET_CODE (SET_DEST (x)) == MEM && ! writes_memory.all - && ! cse_rtx_addr_varies_p (SET_DEST (x)))) - invalidate (SET_DEST (x), VOIDmode); - else if (GET_CODE (SET_DEST (x)) == STRICT_LOW_PART - || GET_CODE (SET_DEST (x)) == ZERO_EXTRACT) + note_mem_written (SET_DEST (x)); + + /* See comment on similar code in cse_insn for explanation of these tests. */ + if (GET_CODE (SET_DEST (x)) == REG || GET_CODE (SET_DEST (x)) == SUBREG + || GET_CODE (SET_DEST (x)) == MEM) + invalidate (SET_DEST (x), VOIDmode); + else if (GET_CODE (SET_DEST (x)) == STRICT_LOW_PART + || GET_CODE (SET_DEST (x)) == ZERO_EXTRACT) invalidate (XEXP (SET_DEST (x), 0), GET_MODE (SET_DEST (x))); } @@ -8233,6 +8070,7 @@ cse_main (f, nregs, after_loop, file) val.path_size = 0; init_recog (); + init_alias_analysis (); max_reg = nregs; diff --git a/gnu/usr.bin/gcc/f/BUGS b/gnu/usr.bin/gcc/f/BUGS index f6232ce52ba..a1e7fc6ff6e 100644 --- a/gnu/usr.bin/gcc/f/BUGS +++ b/gnu/usr.bin/gcc/f/BUGS @@ -15,24 +15,17 @@ separating them out. For information on bugs that might afflict people who configure, port, build, and install `g77', *Note Problems Installing::. - * When using `-fugly', `g77' assumes an extra `%VAL(0)' argument is - to be passed to intrinsics taking no arguments, such as `IARGC()', - which in turn reject such a call. Although this has been worked - around for 0.5.18 due to changes in the handling of intrinsics, - `g77' needs to do the ugly-argument-appending trick only for - external-function invocation, as this would probably be more - consistent with compilers that default to using that trick. - - * Although `g77' generally supports `SELECT CASE', it doesn't do so - for `CHARACTER' types. Worse, it just crashes with a barely - servicable diagnostic. If the time can't be taken soon to finish - implementing this feature, at least a better way of diagnosing the - problem should be provided. - - * To accept a lot of fine code, `g77' needs to accept `FORMAT' and - `ENTRY' before an `IMPLICIT NONE'. - - * Some crashes occur when compiling under Solaris on x86 machines. + * Work is needed on the `SIGNAL()' intrinsic to ensure that pointers + and integers are properly handled on all targets, including 64-bit + machines. + + * When using `-fugly-comma', `g77' assumes an extra `%VAL(0)' + argument is to be passed to intrinsics taking no arguments, such + as `IARGC()', which in turn reject such a call. Although this has + been worked around for 0.5.18 due to changes in the handling of + intrinsics, `g77' needs to do the ugly-argument-appending trick + only for external-function invocation, as this would probably be + more consistent with compilers that default to using that trick. * Something about `g77''s straightforward handling of label references and definitions sometimes prevents the GBE from @@ -47,12 +40,9 @@ port, build, and install `g77', *Note Problems Installing::. * Some confusion in diagnostics concerning failing `INCLUDE' statements from within `INCLUDE''d or `#include''d files. - * Some problems on RS/6000 regarding statement functions and/or - `COMPLEX' arithmetic? - - * `g77' assumes that `INTEGER' constants range from `-2**31' to - `2**31-1' (the range for two's-complement 32-bit values), instead - of determining their range from the actual range of the `INTEGER' + * `g77' assumes that `INTEGER(KIND=1)' constants range from `-2**31' + to `2**31-1' (the range for two's-complement 32-bit values), + instead of determining their range from the actual range of the type for the configuration (and, someday, for the constant). Further, it generally doesn't implement the handling of constants @@ -113,9 +103,24 @@ port, build, and install `g77', *Note Problems Installing::. that's the state in which the debugger should start up, as is the case for languages like C. + * Debugging `g77'-compiled code using debuggers other than `gdb' is + likely not to work. + + Getting `g77' and `gdb' to work together is a known + problem--getting `g77' to work properly with other debuggers, for + which source code often is unavailable to `g77' developers, seems + like a much larger, unknown problem, and is a lower priority than + making `g77' and `gdb' work together properly. + + On the other hand, information about problems other debuggers have + with `g77' output might make it easier to properly fix `g77', and + perhaps even improve `gdb', so it is definitely welcome. Such + information might even lead to all relevant products working + together properly sooner. + * `g77' currently inserts needless padding for things like `COMMON - A,IPAD' where `A' is `CHARACTER*1' and `IPAD' is `INTEGER*4' on - machines like x86, because the back end insists that `IPAD' be + A,IPAD' where `A' is `CHARACTER*1' and `IPAD' is `INTEGER(KIND=1)' + on machines like x86, because the back end insists that `IPAD' be aligned to a 4-byte boundary, but the processor has no such requirement (though it's good for performance). @@ -126,6 +131,12 @@ port, build, and install `g77', *Note Problems Installing::. potential, with the current setup, for interface differences in the way such areas are laid out between `g77' and other compilers. + * Some crashes occur when compiling under Solaris on x86 machines. + + Nothing has been heard about any such problems for some time, so + this is considering a closed item as of 0.5.20. Please submit any + bug reports pertinent to `g77''s support for Solaris/x86 systems. + * RS/6000 support is not complete as of the gcc 2.6.3 back end. The 2.7.0 back end appears to fix this problem, or at least mitigate it significantly, but there is at least one known problem that is @@ -133,13 +144,34 @@ port, build, and install `g77', *Note Problems Installing::. `g77-0.5.16'. This problem shows up only when compiling the Fortran program with `-O'. + Nothing has been heard about any RS/6000 problems for some time, + so this is considering a closed item as of 0.5.20. Please submit + any bug reports pertinent to `g77''s support for RS/6000 systems. + * SGI support is known to be a bit buggy. The known problem shows up only when compiling the Fortran program with `-O'. - * `g77' doesn't work on 64-bit configurations such as the Alpha. - This problem is expected to be largely resolved as of version - 0.5.20, and version 0.6 should solve most or all related problems - (such as 64-bit machines other than DEC Alphas). + It is possible these problems have all been fixed in 0.5.20 by + emulating complex arithmetic in the front end. Please submit any + bug reports pertinent to `g77''s support for SGI systems. + + * `g77' doesn't work perfectly on 64-bit configurations such as the + Alpha. This problem is expected to be largely resolved as of + version 0.5.20, and version 0.6 should solve most or all related + problems (such as 64-bit machines other than DEC Alphas). + + One known bug that causes a compile-time crash occurs when + compiling code such as the following with optimization: + + SUBROUTINE CRASH (TEMP) + INTEGER*2 HALF(2) + REAL TEMP + HALF(1) = NINT (TEMP) + END + + It is expected that a future version of `g77' will have a fix for + this problem, almost certainly by the time `g77' supports the + forthcoming version 2.8.0 of `gcc'. * Maintainers of gcc report that the back end definitely has "broken" support for `COMPLEX' types. Based on their input, it seems many @@ -147,9 +179,11 @@ port, build, and install `g77', *Note Problems Installing::. `__complex__' type, such as `__complex__ int' (where the real and imaginary parts are integers) that GNU Fortran does not use. - Version 0.5.20 of `g77' is expected to work around this problem by - not using the back end's support for `COMPLEX'. This work has - already been done, and is being tested by developers. + Version 0.5.20 of `g77' works around this problem by not using the + back end's support for `COMPLEX'. The new option + `-fno-emulate-complex' avoids the work-around, reverting to using + the same "broken" mechanism as that used by versions of `g77' + prior to 0.5.20. * There seem to be some problems with passing constants, and perhaps general expressions (other than simple variables/arrays), to @@ -160,5 +194,3 @@ port, build, and install `g77', *Note Problems Installing::. the gcc back end, and it apparently occurs only when compiling sufficiently complicated functions *without* the `-O' option. - This might be fixed in version 2.7.2 of `gcc'. - diff --git a/gnu/usr.bin/gcc/f/ChangeLog b/gnu/usr.bin/gcc/f/ChangeLog index 031133da65e..6e483dcadef 100644 --- a/gnu/usr.bin/gcc/f/ChangeLog +++ b/gnu/usr.bin/gcc/f/ChangeLog @@ -1,3 +1,374 @@ +Fri Feb 28 13:16:50 1997 Craig Burley <burley@gnu.ai.mit.edu> + + * Version 0.5.20 released. + +Fri Feb 28 01:45:25 1997 Craig Burley <burley@gnu.ai.mit.edu> + + * Make-lang.in (RUNTIMESTAGESTUFF, LIBU77STAGESTUFF): + Move some files incorrectly in the former to the latter, + and add another file or two to the latter. + + New meanings for (KIND=n), and new denotations in the + little language describing intrinsics: + * com.c (ffecom_init_0): Assign new meanings. + * intdoc.c: Document new meanings. + Support the new denotations. + * intrin.c: Employ new meanings, mapping them to internal + values (which are the same as they ever were for now). + Support the new denotations. + * intrin.def: Switch DEFIMP table to the new denotations. + + * intrin.c (ffeintrin_check_): Fix bug that was leaving + LOC() and %LOC() returning INTEGER*4 on systems where + it should return INTEGER*8. + + * type.c: Canonicalize function definitions, for etags + and such. + +Wed Feb 26 20:43:03 1997 Craig Burley <burley@gnu.ai.mit.edu> + + * com.c (ffecom_init_0): Choose INTEGER(KIND=n) types, + where n is 2, 3, and 4, according to the new docs + instead of according to the old C correspondences + (which seem less useful at this point). + + * equiv.c (ffeequiv_destroy_): New function. + (ffeequiv_layout_local_): Use this new function + whenever the laying out of a local equivalence chain + is aborted for any reason. + Otherwise ensure that symbols no longer reference + the stale ffeequiv entries that result when they + are killed off in this procedure. + Also, the rooted symbol is one that has storage, + it really is irrelevant whether it has an equiv entry + at this point (though the code to remove the equiv + entry was put in at the end, just in case). + (ffeequiv_kill): When doing internal checks, make + sure the victim isn't named by any symbols it points + to. Not as complete a check as looking through the + entire symbol table (which does matter, since some + code in equiv.c used to remove symbols from the lists + for an ffeequiv victim but not remove that victim as the + symbol's equiv info), but this check did find some + real bugs in the code (that were fixed). + +Mon Feb 24 16:42:13 1997 Craig Burley <burley@gnu.ai.mit.edu> + + * com.c (ffecom_expr_intrinsic_): Fix a couple of + warnings about uninitialized variables. + * intrin.c (ffeintrin_check_): Ditto, but there were + a couple of _real_ uninitialized-variable _bugs_ here! + (ffeintrin_fulfill_specific): Ditto, no real bug here. + +Sun Feb 23 15:01:20 1997 Craig Burley <burley@gnu.ai.mit.edu> + + Clean up diagnostics (especially about intrinsics): + * bad.def (FFEBAD_UNIMPL_STMT): Remove. + (FFEBAD_INTRINSIC_*, FFEBAD_NEED_INTRINSIC): Clean these + up so they're friendlier. + (FFEBAD_INTRINSIC_CMPAMBIG): New. + * intrin.c (ffeintrin_fulfill_generic, + ffeintrin_fulfill_specific, ffeintrin_is_intrinsic): + Always choose + generic or specific name text (which is for doc purposes + anyway) over implementation name text (which is for + internal use). + * intrin.def: Use more descriptive name texts for generics + and specifics in cases where the names themselves are not + enough (e.g. IDATE, which has two forms). + + Fix some intrinsic mappings: + * intrin.def (FFEINTRIN_specIDINT, FFEINTRIN_specAND, + FFEINTRIN_specDFLOAT, FFEINTRIN_specDREAL, FFEINTRIN_specOR, + FFEINTRIN_specXOR): Now have their own implementations, + instead of borrowing from others. + (FFEINTRIN_specAJMAX0, FFEINTRIN_specAJMIN0, FFEINTRIN_specBJTEST, + FFEINTRIN_specDFLOTJ, FFEINTRIN_specFLOATJ, FFEINTRIN_specJIABS, + FFEINTRIN_specJIAND, FFEINTRIN_specJIBCLR, FFEINTRIN_specJIBITS, + FFEINTRIN_specJIBSET, FFEINTRIN_specJIDIM, FFEINTRIN_specJIDINT, + FFEINTRIN_specJIDNNT, FFEINTRIN_specJIEOR, FFEINTRIN_specJIFIX, + FFEINTRIN_specJINT, FFEINTRIN_specJIOR, FFEINTRIN_specJISHFT, + FFEINTRIN_specJISHFTC, FFEINTRIN_specJISIN, FFEINTRIN_specJMAX0, + FFEINTRIN_specJMAX1, FFEINTRIN_specJMIN0, FFEINTRIN_specJMIN1, + FFEINTRIN_specJMOD, FFEINTRIN_specJNINT, FFEINTRIN_specJNOT,): + Turn these implementations off, since it's not clear + just what types they expect in the context of portable Fortran. + (DFLOAT): Now in FVZ family, since f2c supports them + + Support intrinsic inquiry functions (BIT_SIZE, LEN): + * intrin.c: Allow `i' in <arg_extra>. + * intrin.def (FFEINTRIN_impBIT_SIZE, FFEINTRIN_impLEN): + Mark args with `i'. + +Sat Feb 22 13:34:09 1997 Craig Burley <burley@gnu.ai.mit.edu> + + Only warn, don't error, for reference to unimplemented + intrinsic: + * bad.def (FFEBAD_INTRINSIC_UNIMPLW): Warning version + of _UNIMPL. + * intrin.c (ffeintrin_is_intrinsic): Use new warning + version of _UNIMPL (FFEBAD_INTRINSIC_UNIMPLW). + + Complain about REAL(Z) and AIMAG(Z) (Z is DOUBLE COMPLEX): + * bad.def (FFEBAD_INTRINSIC_CMPAMBIG): New diagnostic. + * expr.c: Needed #include "intrin.h" anyway. + (ffeexpr_token_intrincheck_): New function handles delayed + diagnostic for "REAL(REAL(expr)" if next token isn't ")". + (ffeexpr_token_arguments_): Do most of the actual checking here. + * intrin.h, intrin.c (ffeintrin_fulfill_specific): New + argument, check_intrin, to tell caller that intrin is REAL(Z) + or AIMAG(Z). All callers updated, mostly to pass NULL in + for this. + (ffeintrin_check_): Also has new arg check_intrin for same + purpose. All callers updated the same way. + * intrin.def (FFEINTRIN_impAIMAG): Change return type + from "R0" to "RC", to accommodate f2c (and perhaps other + non-F90 F77 compilers). + * top.h, top.c: New option -fugly-complex. + + New GNU intrinsics REALPART, IMAGPART, and COMPLEX: + * com.c (ffecom_expr_intrinsic_): Implement impCOMPLEX + and impREALPART here. (specIMAGPART => specAIMAG.) + * intrin.def: Add the intrinsics here. + + Rename implementations of VXTIDATE and VXTTIME to IDATEVXT + and TIMEVXT, so they sort more consistently: + * com.c (ffecom_expr_intrinsic_): + * intrin.def: + + Delete intrinsic group `dcp', add `gnu', etc.: + * intrin.c (ffeintrin_state_family): FFEINTRIN_familyGNU + replaces FFEINTRIN_familyDCP, and gets state from `gnu' + group. + Get rid of FFEINTRIN_familyF2Z, nobody needs it. + Move FFEINTRIN_specDCMPLX from DCP family to FVZ family, + as f2c has it. + Move FFEINTRIN_specDFLOAT from F2C family to FVZ family. + (FFEINTRIN_specZABS, FFEINTRIN_specZCOS, FFEINTRIN_specZEXP, + FFEINTRIN_specZLOG, FFEINTRIN_specZSIN, FFEINTRIN_specZSQRT): + Move these from F2Z family to F2C family. + * intrin.h (FFEINTRIN_familyF2Z, FFEINTRIN_familyDCP): Remove. + (FFEINTRIN_familyGNU): Add. + * top.h, top.c: Replace `dcp' with `gnu'. + + * com.c (ffecom_expr_intrinsic_): Clean up by collecting + simple conversions into one nice, conceptual place. + Fix up some intrinsic subroutines (MVBITS, KILL, UMASK) to + properly push and pop call temps, to avoid wasting temp + registers. + + * g77.c (doit): Toon says variables should be defined + before being referenced. Spoilsport. + + * intrin.c (ffeintrin_check_): Now Dave's worried about + warnings about uninitialized variables. Okay, so for + basic return values 'g' and 's', they _were_ + uninitialized -- is determinism really _that_ useful? + + * intrin.def (FFEINTRIN_impFGETC): Fix STATUS argument + so that it is INTENT(OUT) instead of INTENT(IN). + +1997-02-21 Dave Love <d.love@dl.ac.uk> + + * intrin.def, com.c: Support Sun-type `short' and `long' + intrinsics. Perhaps should also do Microcruft-style `int2'. + +Thu Feb 20 15:16:53 1997 Craig Burley <burley@gnu.ai.mit.edu> + + * com.c (ffecom_expr_intrinsic_): Clean up indentation. + Support SECONDSUBR intrinsic implementation. + Rename SECOND to SECONDFUNC for direct support via library. + + * g77.c: Fix to return proper status value to shell, + by obtaining it from processes it spawns. + + * intdoc.c: Fix minor typo. + + * intrin.def: Turn SECOND into generic that maps into + function and subroutine forms. + + * intrin.def: Make FLOAT and SNGL into specific intrinsics. + + * intrin.def, intrin.h: Change the way DEFGEN and DEFSPEC + macros work, to save on verbage. + +Mon Feb 17 02:08:04 1997 Craig Burley <burley@gnu.ai.mit.edu> + + New subsystem to automatically generate documentation + on intrinsics: + * Make-lang.in ($(srcdir)/f/g77.info, + $(srcdir)/f/g77.dvi): Move g77 doc rules around. + Add to g77 doc rules the new subsystem. + (f77.mostlyclean, f77.maintainer-clean): Also clean up + after new doc subsystem. + * intdoc.c, intdoc.h: New doc subsystem code. + * intrin.h [FFEINTRIN_DOC]: When 1, don't pull in + stuff not needed by doc subsystem. + + Improve on intrinsics mechanism to both be more + self-documenting and to catch more user errors: + * intrin.c (ffeintrin_check_): Recognize new arg-len + and arg-rank information, and check it. + Move goto and signal indicators to the basic type. + Permit reference to arbitrary argument number, not + just first argument (for BESJN and BESYN). + (ffeintrin_init_0): Check and accept new notations. + * intrin.c, intrin.def: Value in COL now identifies + arguments starting with number 0 being the first. + + Some minor intrinsics cleanups (resulting from doc work): + * com.c (ffecom_expr_intrinsic_): Implement FLUSH + directly once again, handle its optional argument, + so it need not be a generic (awkward to handle in docs). + * intrin.def (BESJ0, BESJ1, BESJN, BESY0, BESY1, BESYN, + CHDIR, CHMOD, CTIME, DBESJ0, DBESJ1, DBESJN, DBESY0, + DBESY1, DBESYN, DDIM, ETIME, FGETC, FNUM, FPUTC, FSTAT, + GERROR, GETCWD, GETGID, GETLOG, GETPID, GETUID, GMTIME, + HOSTNM, IDATE, IERRNO, IIDINT, IRAND, ISATTY, ITIME, JIDINT, + LNBLNK, LSTAT, LTIME, MCLOCK, PERROR, SRAND, SYMLNK, TTYNAM, + UMASK): Change capitalization of initcaps (official) name + to be consistent with Burley's somewhat arbitrary rules. + (BESJN, BESYN): These have return arguments of same type + as their _second_ argument. + (FLUSH): Now a specific, not generic, intrinsic, with one + optional argument. + (FLUSH1): Eliminated. + Add arg-len and arg-rank info to several intrinsics. + (ITIME): Change argument type from REAL to INTEGER. + +Tue Feb 11 14:04:42 1997 Craig Burley <burley@gnu.ai.mit.edu> + + * Make-lang.in (f771): Invocation of Makefile now done + with $(srcdir)=gcc to go along with $(VPATH)=gcc. + ($(srcdir)/f/runtime/configure, + $(srcdir)/f/runtime/libU77/configure): Break these out + so spurious triggers of this rule don't happen (as when + configure.in is more recent than libU77/configure). + (f77.rebuilt): Distinguish source versus build files, + so this target can be invoked from build directory and + still work. + * Makefile.in: This now expects $(srcdir) to be the gcc + source directory, not gcc/f, to agree with $(VPATH). + Accordingly, $(INCLUDES) has been fixed, various cruft + removed, the removal of f771 has been fixed to remove + the _real_ f771 (not the one in gcc's parent directory), + and so on. + + * lex.c: Part of ffelex_finish_statement_() now done + by new function ffelex_prepare_eos_(), so that, in one + popular case, the EOS can be prepared while the pointer + is at the end of the non-continued line instead of the + end of the line that marks no continuation. This improves + the appearance of diagnostics substantially. + +Mon Feb 10 12:44:06 1997 Craig Burley <burley@gnu.ai.mit.edu> + + * Make-lang.in: runtime Makefile's, and include/f2c.h, + also depend on f/runtime/configure and f/runtime/libU77/configure. + + Fix various libU77 routines: + * com-rt.def (FFECOM_gfrtCTIME, FFECOM_gfrtMCLOCK, + FFECOM_gfrtTIME): These now use INTEGER*8 for time values, + for compatibility with systems like Alpha. + (FFECOM_gfrtSYSTEM_CLOCK, FFECOM_gfrtTTYNAM): Delete incorrect + trailing underscore in routine names. + * intrin.c, intrin.def: Support INTEGER*8 return values and + arguments ('4'). Change FFEINTRIN_impCTIME, FFEINTRIN_impMCLOCK, + and FFEINTRIN_impTIME accordingly. + (ffeintrin_is_intrinsic): Don't give caller a clue about + form of intrinsic -- shouldn't be needed at this point. + + Cope with generic intrinsics that are subroutines and functions: + * com.c (ffecom_finish_symbol_transform_, ffecom_expr_transform_): + Don't transform an intrinsic that is not known to be a subroutine + or a function. (Maybe someday have to avoid transforming + any intrinsic with an undecided or unknown implementation.) + * expr.c (ffeexpr_declare_unadorned_, + ffeexpr_declare_parenthesized_): Ok to invoke generic + intrinsic that has at least one subroutine form as a + subroutine. + Ok to pass intrinsic as actual arg if it has a known specific + intrinsic form that is valid as actual arg. + (ffeexpr_declare_parenthesized_): An unknown kind of + intrinsic has a paren_type chosen based on context. + (ffeexpr_token_arguments_): Build funcref/subrref based + on context, not on kind of procedure being called. + * intrin.h, intrin.c (ffeintrin_is_intrinsic): Undo changes of + Tue Feb 4 23:12:04 1997 by me, change all callers to leave + intrinsics as FFEINFO_kindNONE at this point. (Some callers + also had unused variables deleted as a result.) + + Enable all intrinsic groups (especially f90 and vxt): + * target.h (FFETARGET_defaultSTATE_DCP, FFETARGET_defaultSTATE_F2C, + FFETARGET_defaultSTATE_F90, FFETARGET_defaultSTATE_MIL, + FFETARGET_defaultSTATE_UNIX, FFETARGET_defaultSTATE_VXT): + Delete these macros, let top.c set them directly. + * top.c (ffeintrinsic_state_dcp_, ffe_intrinsic_state_f2c_, + ffe_intrinsic_state_f90_, ffe_intrinsic_state_mil_, + ffe_intrinsic_state_unix_, ffe_intrinsic_state_vxt_): + Enable all these directly. + +Sat Feb 8 03:21:50 1997 Craig Burley <burley@gnu.ai.mit.edu> + + * g77.c: Incorporate recent changes to ../gcc.c. + For version magic (e.g. `g77 -v'), instead of compiling + /dev/null, write, compile, run, and then delete a small + program that prints the version numbers of the three + components of libf2c (libF77, libI77, and libU77), + so we get this info with bug reports. + Also, this change reduces the chances of accidentally + linking to an old (complex-alias-problem) libf2c. + Fix `-L' so the argument is expected in `-Larg'. + + * com.h (FFECOM_f2cLONGINT): For INTEGER*8 support in f2c.h, + dynamically determine proper type here, instead of + assuming `long long int' is correct. + +Tue Feb 4 23:12:04 1997 Craig Burley <burley@gnu.ai.mit.edu> + + Add libU77 library from Dave Love <d.love@dl.ac.uk>: + * Make-lang.in (f77-runtime): Depend on new Makefile. + (f/runtime/libU77/Makefile): New rule. + Also configure libU77. + ($(srcdir)/f/runtime/configure: Use Makefile.in, + so configuration doesn't have to have happened. + (f77.mostlyclean, f77.clean, f77.distclean, + f77.maintainer-clean): Some fixups here, but more work + needed. + (RUNTIMESTAGESTUFF): Add libU77's config.status. + (LIBU77STAGESTUFF, f77.stage1, f77.stage2, f77.stage3, + f77.stage4): New macro, appropriate uses added. + * com-rt.def: Add libU77 procedures. + * com.c (ffecom_f2c_ptr_to_integer_type_node, + ffecom_f2c_ptr_to_real_type_node): New type nodes. + (FFECOM_rttypeCHARACTER_): New type of run-time function. + (ffecom_char_args_): Handle CHARACTER*n intrinsics + where n != 1 here, instead of in ffecom_expr_intrinsic_. + (ffecom_expr_intrinsic_): New code to handle new + intrinsics. + In particular, change how FFEINTRIN_impFLUSH is handled. + (ffecom_make_gfrt_): Handle new type of run-time function. + (ffecom_init_0): Initialize new type nodes. + * config-lang.in: New libU77 directory. + * intrin.h, intrin.c (ffeintrin_is_intrinsic): Handle + potential generic for subroutine _and_ function + specifics via two new arguments. All callers changed. + Properly ignore deleted/disabled intrinsics in resolving + generics. + (ffeintrin_check_, ffeintrin_init_0): Handle CHARACTER intrinsics of (*) + length. + * intrin.def: Permission granted by FSF to place this in + public domain, which will allow it to serve as source + for both g77 program and its documentation. + Add libU77 intrinsics. + (FLUSH): Now a generic, not specific, intrinsic. + (DEFIMP): Now support return modifier for CHARACTER intrinsics. + + * com-rt.def (FFECOM_gfrtDIM, FFECOM_gfrtERF, + FFECOM_gfrtERFC, FFECOM_gfrtEXP, FFECOM_gfrtSIGN, + FFECOM_gfrtSIN, FFECOM_gfrtSINH, FFECOM_gfrtTAN, + FFECOM_gfrtTANH, FFECOM_gfrtPOW_RI): Change "&r" to "&f". + Sat Feb 1 12:15:09 1997 Craig Burley <burley@gnu.ai.mit.edu> * Version 0.5.19.1 released. @@ -12,6 +383,224 @@ Sat Feb 1 12:15:09 1997 Craig Burley <burley@gnu.ai.mit.edu> FFECOM_gfrtDIV_CC, FFECOM_gfrtDIV_ZZ: These all require result to _not_ overlap one or more inputs. +Sat Feb 1 00:25:55 1997 Craig Burley <burley@gnu.ai.mit.edu> + + * com.c (ffecom_init_0): Do internal checks only if + -fset-g77-defaults not specified. + + Fix %LOC(), LOC() to return sufficiently wide type: + * com.h, com.c (ffecom_pointer_kind_, ffecom_label_kind_, + ffecom_pointer_kind(), ffecom_label_kind()): New globals + and accessor macros hold kind for integer pointers on target + machine. + (ffecom_init_0): Determine narrowest INTEGER type that + can hold a pointer (usually INTEGER*4 or INTEGER*8), + store it in ffecom_pointer_kind_, etc. + * expr.c (ffeexpr_cb_end_loc_): Use right type for %LOC(). + * intrin.c (ffeintrin_check_, ffeintrin_init_0): Support + new 'p' kind for type of intrinsic. + * intrin.def (FFEINTRIN_impLOC): Returns "Ip" instead of "I1", + so LOC() type is correct for target machine. + + Support -fugly-assign: + * lang-options.h, top.h, top.c (ffe_decode_option): + Accept -fugly-assign and -fno-ugly-assign. + * com.c (ffecom_expr_): Handle -fugly-assign. + * expr.c (ffeexpr_finished_): Check right type for ASSIGN + contexts. + +Fri Jan 31 14:30:00 1997 Craig Burley <burley@gnu.ai.mit.edu> + + Remove last vestiges of -fvxt-not-f90: + * stb.c (ffestb_R10012_, ffestb_R10014_, ffestb_V0201_): + top.c, top.h: + +Fri Jan 31 02:13:54 1997 Craig Burley <burley@gnu.ai.mit.edu> + + * top.c (ffe_decode_option): Warn if -fugly is specified, + it'll go away soon. + + * symbol.h: No need to #include "bad.h". + + Reorganize features from -fvxt-not-f90 to -fvxt: + * lang-options.h, top.h, top.c: + Accept -fvxt and -fno-vxt, but not -fvxt-not-f90 or -ff90-not-vxt. + Warn if the latter two are used. + * expr.c (ffeexpr_nil_rhs_): Double-quote means octal constant. + (ffeexpr_token_rhs_): Double-quote means octal constant. + * target.h (FFETARGET_defaultIS_VXT_NOT_90): Delete macro + definition, no longer needed. + + Make some -ff90 features the default: + * data.c (ffedata_value): DATA implies SAVE. + * src.h (ffesrc_is_name_noninit): Underscores always okay. + + Fix up some more #error directives by quoting their text: + * bld.c (ffebld_constant_is_zero): + * target.h: + +Sat Jan 18 18:22:09 1997 Craig Burley <burley@gnu.ai.mit.edu> + + * g77.c (lookup_option, main): Recognize `-Xlinker', + `-Wl,', `-l', `-L', `--library-directory', `-o', + `--output'. + (lookup_option): Don't depend on SWITCH_TAKES_ARG + being correct, it might or might not have `-x' in + it depending on host. + Return NULL argument if it would be an empty string. + (main): If no input files (by gcc.c's definition) + but `-o' or `--output' specified, produce diagnostic + to avoid overwriting output via gcc. + Recognize C++ `+e' options. + Treat -L as another non-magical option (like -B). + Don't append_arg `-x' twice. + +Fri Jan 10 23:36:00 1997 Craig Burley <burley@gnu.ai.mit.edu> + + * top.c [BUILT_FOR_270] (ffe_decode_option): Make + -fargument-noalias-global the default. + +Fri Jan 10 07:42:27 1997 Craig Burley <burley@gnu.ai.mit.edu> + + Enable inlining of previously-compiled program units: + * com.c (ffecom_do_entry_, ffecom_start_progunit_): + Register new public function in ffeglobal database. + (ffecom_sym_transform_): Any GLOBAL or potentially GLOBAL + symbol should be looked up in ffeglobal database and + that tree node used, if found. That way, gcc knows + the references are to those earlier definitions, so it + can emit shorter branches/calls, inline, etc. + (ffecom_transform_common_): Minor change for clarity. + * expr.c (ffeexpr_sym-lhs_call_, ffeexpr_sym_lhs_extfunc_, + ffeexpr_sym_rhs_actualarg_, ffeexpr_paren_rhs_let_, + ffeexpr_token_funsubstr_): Globalize symbol as needed. + * global.c (ffeglobal_promoted): New function to look up + existing local symbol in ffeglobal database. + * global.h: Declare new function. + * name.h (ffename_token): New macro, plus alphabetize. + * stc.c (ffestc_R1207_item): Globalize EXTERNAL symbol. + * stu.c (ffestu_sym_end_transition, ffestu_sym_exec_transition): + Globalize symbol as needed. + * symbol.h, symbol.c (ffesymbol_globalize): New function. + +Thu Jan 9 14:20:00 1997 Craig Burley <burley@gnu.ai.mit.edu> + + * ste.c (ffeste_R809): Produce a diagnostic for SELECT CASE + on CHARACTER type, instead of crashing. + +Thu Jan 9 00:52:45 1997 Craig Burley <burley@gnu.ai.mit.edu> + + * stc.c (ffestc_order_entry_, ffestc_order_format_, + ffestc_R1226): Allow ENTRY and FORMAT before IMPLICIT + NONE, by having them transition only to state 1 instead + of state 2 (which is disallowed by IMPLICIT NONE). + +Mon Jan 6 22:44:53 1997 Craig Burley <burley@gnu.ai.mit.edu> + + Fix AXP bug found by Rick Niles (961201-1.f): + * com.c (ffecom_init_0): Undo my 1996-05-14 change, as + it is incorrect and prevented easily finding this bug. + * target.h [__alpha__] (ffetargetReal1, ffetargetReal2): + Use int instead of long. + (ffetarget_cvt_r1_to_rv_, ffetarget_cvt_rv_to_r1_, + ffetarget_cvt_r2_to_rv_, ffetarget_cvt_rv_to_r2_): + New functions that intercede for callers of + REAL_VALUE_(TO|UNTO)_TARGET_(SINGLE|DOUBLE). + All callers changed, and damaging casts to (long *) removed. + +Sun Jan 5 03:26:11 1997 Craig Burley <burley@gnu.ai.mit.edu> + + * Make-lang.in (g77, g77-cross): Depend on both g77.c and + zzz.c, in $(srcdir)/f/. + + Better design for -fugly-assumed: + * stc.c (ffestc_R501_item, ffestc_R524_item, + ffestc_R547_item_object): Pass new is_ugly_assumed flag. + * stt.c, stt.h (ffestt_dimlist_as_expr, + ffestt_dimlist_type): New is_ugly_assumed flag now + controls whether "1" is treated as "*". + Don't treat "2-1" or other collapsed constants as "*". + +Sat Jan 4 15:26:22 1997 Craig Burley <burley@gnu.ai.mit.edu> + + * stb.c (ffestb_R10012_): Don't confirm on FORMAT(A,) + or even FORMAT(A,,B), as R1229 only warns about the + former currently, and this seems reasonable. + + Improvements to diagnostics: + * sta.c (ffesta_second_): Don't add any ffestb parsers + unless they're specifically called for. + Set up ffesta_tokens[0] before calling ffestc_exec_transition, + else stale info might get used. + (ffesta_save_): Do a better job picking which parser to run + after running all parsers with no confirmed possibles. + (FFESTA_maxPOSSIBLES_): Decrease from 100 now that so few + possibles are ever on the list at a given time. + (struct _ffesta_possible): Add named attribute. + (ffesta_add_possible_exec_, ffesta_add_possible_nonexec_): + Make these into macros that call a single function that now + sets the named attribute. + (ffesta_add_possible_unnamed_exec_, + ffeseta_add_possible_unnamed_nonexec_): New macros. + (ffesta_second_): Designate unnamed possibles as + appropriate. + * stb.c (ffestb_R1229, ffestb_R12291_): Use more general + diagnostic, so things like "POINTER (FOO, BAR)" are + diagnosed as unrecognized statements, not invalid statement + functions. + * stb.h, stb.c (ffestb_unimplemented): Remove function. + +1996-12-30 Dave Love <d.love@dl.ac.uk> + + * com.c: #include libU77/config.h + (ffecom_f2c_ptr_to_integer_type_node, + ffecom_f2c_ptr_to_integer_type_node): New variables. + (ffecom_init_0): Use them. + (ffecom_expr_intrinsic_): Many news cases for libU77 intrinsics. + + * com-rt.def: New definitions for libU77. + * intrin.def: Likewise. Also correct ftell arg spec. + + * Makefile.in (f/runtime/libU77/config.h): New target for com.c + dependency. + * Make-lang.in (f771): Depend on f/runtime/Makefile for the above. + +Sat Dec 28 12:28:29 1996 Craig Burley <burley@gnu.ai.mit.edu> + + * stt.c (ffestt_dimlist_type): Treat ([...,]1) in dimlist + as ([...,]*) if -fugly-assumed, so assumed-size array + detected early enough. + +Thu Dec 19 14:01:57 1996 Craig Burley <burley@gnu.ai.mit.edu> + + * target.h (FFETARGET_REAL_VALUE_FROM_INT_): Conditionalize + definition on BUILT_FOR_280, not BUILT_WITH_280, since + the name of the macro was (properly) changed since 0.5.19. + + Fix warnings/errors resulting from ffetargetOffset becoming + `long long int' instead of `unsigned long' as of 0.5.19, + while ffebitCount remains `unsigned long': + * bld.c (ffebld_constantarray_dump): Avoid warnings by + using loop var of appropriate type, and using casts. + * com.c (ffecom_expr_): Use right type for loop var. + (ffecom_sym_transform_, ffecom_transform_equiv_): + Cast to right type in assertions. + * data.c (ffedata_gather_, ffedata_value_): Cast to right + type in assertions and comparisons. + +Wed Dec 18 12:07:11 1996 Craig Burley <burley@gnu.ai.mit.edu> + + Patch from Alexandre Oliva <oliva@dcc.unicamp.br>: + * Makefile.in (all.indirect): Don't pass -bbigtoc option + to GNU ld. + + Cope with new versions of gcc: + * com.h (BUILT_FOR_280): New macro. + * com.c (ffecom_ptr_to_expr): Conditionalize test of + OFFSET_REF. + (ffecom_build_complex_constant_): Conditionalize calling + sequence for build_complex. + Sat Dec 7 07:15:17 1996 Craig Burley <burley@gnu.ai.mit.edu> * Version 0.5.19 released. @@ -200,6 +789,11 @@ Thu Oct 31 20:56:28 1996 Craig Burley <burley@gnu.ai.mit.edu> if pre-2.7.0 gcc is involved (since our patch for that doesn't add support for tooning). +Sat Oct 26 05:56:51 1996 Craig Burley <burley@gnu.ai.mit.edu> + + * bad.def (FFEBAD_TYPELESS_TOO_LARGE): Remove this + unused and redundant diagnostic. + Sat Oct 26 00:45:42 1996 Craig Burley <burley@gnu.ai.mit.edu> * target.c (ffetarget_integerhex): Fix dumb bug. @@ -246,6 +840,12 @@ Sun Oct 13 22:15:23 1996 Craig Burley <burley@gnu.ai.mit.edu> * top.c (ffe_decode_option): Don't set back-end flags that are nonexistent prior to gcc 2.7.0. +Sun Oct 13 12:48:45 1996 Craig Burley <burley@gnu.ai.mit.edu> + + * com.c (convert): Don't convert emulated complex expr to + real (via REALPART_EXPR) if the target type is (emulated) + complex. + Wed Oct 2 21:57:12 1996 Craig Burley <burley@gnu.ai.mit.edu> * com.c (ffecom_debug_kludge_): Set DECL_IN_SYSTEM_HEADER so @@ -299,6 +899,62 @@ Thu Sep 26 00:18:40 1996 Craig Burley <burley@gnu.ai.mit.edu> Depend on stmp-hdrs, not stmp-int-hdrs, since libF77 needs float.h. +Sat Jun 22 18:17:11 1996 Craig Burley <burley@gnu.ai.mit.edu> + + * com.c (ffecom_tree_divide_): Fix RECORD_TYPE case to + look at type of first field, properly, to determine + whether to call c_div or z_div. + +Tue Jun 4 04:27:18 1996 Craig Burley <burley@gnu.ai.mit.edu> + + * com.c (ffecom_build_complex_constant_): Explicitly specify + TREE_PURPOSE. + (ffecom_expr_): Fix thinko. + (ffecom_2): For COMPLEX_EXPR, explicitly specify TREE_PURPOSE. + +Mon May 27 16:23:43 1996 Craig Burley <burley@gnu.ai.mit.edu> + + Changes to optionally avoid gcc's back-end complex support: + * com.c (ffecom_stabilize_aggregate_): New function. + (ffecom_convert_to_complex_): New function. + (ffecom_make_complex_type_): New function. + (ffecom_build_complex_constant_): New function. + (ffecom_expr_): For opCONVERT of non-COMPLEX to COMPLEX, + don't bother explicitly converting to the subtype first, + because gcc does that anyway, and more code would have + to be added to find the subtype for the emulated-complex + case. + (ffecom_f2c_make_type_): Use ffecom_make_complex_type_ + instead of make_node etc. to make a complex type. + (ffecom_1, ffecom_2): Translate operations on COMPLEX operands + to appropriate operations when emulating complex. + (ffecom_constantunion): Use ffecom_build_complex_constant_ + instead of build_complex to build a complex constant. + (ffecom_init_0): Change point at which types are laid out + for improved consistency. + Use ffecom_make_complex_type_ instead of make_node etc. + to make a complex type. + Always calculate storage sizes from TYPE_SIZE, never TYPE_PRECISION. + (convert): Use e, not expr, since we've copied into that anyway. + For RECORD_TYPE cases, do emulated-complex conversions. + (ffecom_f2c_set_lio_code_): Always calculate storage sizes + from TYPE_SIZE, never TYPE_PRECISION. + (ffecom_tree_divide_): Allow RECORD_TYPE to also be handled + by run-time library. + (ffecom_expr_intrinsic_): Handle possible RECORD_TYPE as argument + to AIMAG intrinsic. + + * top.h, top.c, lang-options.h: Support new -f(no-)emulate-complex option. + + * com.c (ffecom_sym_transform_): Clarify and fix typos in comments. + +Mon May 20 02:06:27 1996 Craig Burley <burley@gnu.ai.mit.edu> + + * target.h: Use new REAL_VALUE_UNTO_TARGET_* macros instead + of REAL_VALUE_FROM_TARGET_DOUBLE and _SINGLE. + Explicitly use long instead of HOST_WIDE_INT for emulation + of ffetargetReal1 and ffetargetReal2. + 1996-05-20 Dave Love <d.love@dl.ac.uk> * config-lang.in: @@ -317,6 +973,17 @@ Thu Sep 26 00:18:40 1996 Craig Burley <burley@gnu.ai.mit.edu> * g77.c (DEFAULT_SWITCH_TAKES_ARG): Define a la gcc.c in the current GCC snapshot. +Tue May 14 00:24:07 1996 Craig Burley <burley@gnu.ai.mit.edu> + + Changes for DEC Alpha AXP support: + * com.c (ffecom_init_0): REAL_ARITHMETIC means internal + REAL/DOUBLE PRECISION might well have a different size + than the compiled type, so don't crash if this is the + case. + * target.h: Use `int' for ffetargetInteger1, + ffetargetLogical1, and magical tests. Set _f format + strings accordingly. + Tue Apr 16 14:08:28 1996 Craig Burley <burley@gnu.ai.mit.edu> * top.c (ffe_decode_option): -Wall no longer implies diff --git a/gnu/usr.bin/gcc/f/DOC b/gnu/usr.bin/gcc/f/DOC deleted file mode 100644 index a050e2550a4..00000000000 --- a/gnu/usr.bin/gcc/f/DOC +++ /dev/null @@ -1,2582 +0,0 @@ -This file explains how to use the GNU Fortran system. -Copyright (C) 1995 Free Software Foundation, Inc. You may copy, -distribute, and modify it freely as long as you preserve this copyright -notice and permission notice. Contributed by James Craig Burley -(burley@gnu.ai.mit.edu). - -1996-03-23 - -[WARNING: THIS FILE IS BEING DEPRECATED as of version 0.5.18 of -GNU Fortran. - -This is the last version of this file that is up-to-date with -respect to changes to GNU Fortran itself. - -In future versions of GNU Fortran, this file will become obsolete -and, at some point, will be removed from the distribution -entirely. - -The contents of this file have been assimilated into the Info -documentation for GNU Fortran, newly available as of version 0.5.18. - -The one-version overlap, or coexistence, of both the Info -documentation and the contents of this file, is being provided -for your convenience in discovering information on what's new -for g77-0.5.18 without having to immediately plunge into the new -Info documentation.] - -Please read all of this information before using (especially before -complaining about) g77. - -Contents: - *WHAT IS GNU FORTRAN?* - *IMPORTANT GENERAL INFORMATION* - *PORTING INFORMATION* - *USING THE g77 COMMAND* - *SUMMARY OF FORTRAN-SPECIFIC COMMAND-LINE OPTIONS* - *SUMMARY OF COMPILATION OPTIONS USEFUL TO FORTRAN USERS* - *SUMMARY OF OVERLY CONVENIENT COMMAND-LINE OPTIONS* - *USER-VISIBLE CHANGES DURING 0.5.x* - *WHAT IS AND ISN'T SUPPORTED* - *BLOCK DATA AND LIBRARIES* - *FORTRAN 90* - *SOURCE CODE FORM* - *TYPES, SIZES, PRECISIONS, AND CONSTANTS* - *VAX FORTRAN VERSUS FORTRAN 90* - *LIBRARY AND PROCEDURE-CALLING INTERFACE* - *OPTIONS FOR POTENTIALLY BUGGY PROGRAMS* - *OPTIONS FOR SPEEDING UP PROGRAMS* - *PEDANTIC COMPILATION* - *UGLY FEATURES* - *CASE SENSITIVITY IN SOURCE CODE* - *INTRINSIC GROUPS* - *TROUBLE (BUGS, ETC.)* - *ADVANTAGES OVER f2c* - *DISAPPOINTMENTS AND MISUNDERSTANDINGS* - *OPEN QUESTIONS* - *INTERFACING, DEBUGGING, ETC.* - -*WHAT IS GNU FORTRAN?* - -GNU Fortran is designed initially as a free replacement for, or alternative -to, the Unix `f77' command. It consists of several components: - -- A modified version of the `gcc' command, which also might be installed as - the system's `cc' - -- The `g77' command, which also might be installed as the system's `f77' - -- The `libf2c' library - -- The compiler itself, internally named `f771' - -The `gcc' command is provided as part of the GNU CC compiler, designed -initially as a free replacement for, or alternative to, the Unix `cc' -command. - -`gcc' is often thought of as "the C Compiler" only, but it does more -than that. Based on command-line options and the names given for files -on the command line, `gcc' determines which actions to perform, including -preprocessing, compiling (in a variety of possible languages), assembling, -and linking. For example, the command `gcc foo.c' "drives" the file -`foo.c' through the preprocessor, then the C compiler (internally named -`cc1'), then the assembler (usually `as'), then the linker (usually named -`ld'), producing an executable program named `a.out' (on UNIX systems). -As another example, the command `gcc foo.cc' would do much the same as -`gcc foo.c', but instead of using the C compiler named `cc1', `gcc' would -use the C++ compiler (named `cc1plus'). - -When GNU Fortran is included and built with the GNU CC source tree, the -resulting version of `gcc' recognizes Fortran source files by name just -like it does C and C++ source files. It knows to use the Fortran compiler -named `f771' instead of `cc1' or `cc1plus' to compile Fortran files. - -Fortran source files are recognized by their file name suffixes: - - *.f, *.for: Fortran source files (no preprocessing) - *.F, *.fpp: Fortran source files (preprocessed via `cpp') - -UNIX users typically use the *.f and *.F nomenclature. Users of other -operating systems, especially those that cannot distinguish upper-case -letters from lower-case letters in their file names, typically use -the *.for and *.fpp nomenclature. Use of the preprocessor `cpp' allows -use of C-like constructs such as "#define" and "#include", but can -lead to unexpected, even mistaken, results due to Fortran's source file -format. Limiting use of the preprocessor to "#include" and, in -conjunction with "#define" only "#if" and related directives, thus -avoiding in-line macro expansion entirely, is recommended, especially -when using the traditional fixed source form. (With free source form, -fewer unexpected transformations are likely to happen, but use of -Hollerith and things like continued character constants can nevertheless -present problems.) - -The `g77' command is essentially just a front-end for the `gcc' command. -Fortran users will normally use `g77' instead of `gcc', because `g77' -knows how to specify the libraries needed to link with Fortran programs -(`libf2c' and `lm'). `g77' can still compile and link programs and -source files written in other languages. The command `g77 -v' is a quick -way to display lots of version information for the various programs -used to compile a typical preprocessed Fortran source file -- this -produces much more output than `gcc -v'. - -The `libf2c' library is distributed with GNU Fortran for the convenience -of its users, but is not part of GNU Fortran. It contains the procedures -needed by Fortran programs while they are running. Things like trigonometric -functions and doing I/O are compiled by the `f771' compiler (invoked by -`g77' when compiling Fortran code) into calls to procedures in `libf2c', -so `libf2c' must be linked with almost every program with any component -compiled by GNU Fortran. (As mentioned above, the `g77' command takes -care of all this for you.) - -The `f771' compiler represents most of what is unique to GNU Fortran. -While the `libf2c' component is really part of f2c, a free Fortran-to- -C converter distributed by Bellcore (AT&T), and the `g77' command is -just a small front-end to `gcc', `f771' is a combination of two rather -large chunks of code. One chunk is the so-called "GNU Back End", or GBE, -which knows how to generate fast code for a wide variety of processors. -The same GBE is used by the C, C++, and Fortran compiler programs `cc1', -`cc1plus', and `f771', plus others. The other chunk of `f771' is the -majority of what is unique about GNU Fortran -- the code that knows how -to interpret Fortran programs to determine what they are intending to -do, and then communicate that knowledge to the GBE for actual compilation -of those programs. This chunk is called the Fortran Front End (FFE). -The `cc1' and `cc1plus' programs have their own Front Ends, for the -C and C++ languages, respectively. - -Because so much is shared among the compilers for various languages, -much of the behavior and many of the user-selectable options for these -compilers are similar. For example, diagnostics (error messages and -warnings) have a general similarity in appearance; command-line -options like `-Wall' have generally similar effects; and the quality -of generated code (in terms of speed and size) is roughly similar -(since that work is done by the shared GBE). - -*IMPORTANT GENERAL INFORMATION* - -1. g77 currently is implemented as a replacement for the f2c+gcc - combination, and its implementation is designed so it can, in - most cases, generate object files that are link-compatible with - those generated by f2c+gcc using the identical combination (which - includes a similar/identical copy of f2c.h). Therefore, the - g77-gcc C-Fortran interface ought to work in a way that is - consistent with f2c. For instance, a Fortran string subroutine - argument will become two arguments on the C side: a char * and an int - length. Much of this compatibility results from the fact that - g77 uses the same run-time library, libf2c, used by f2c+gcc. - - However, it is expected that a future version of g77 will not - by default generate object files compatible with f2c+gcc and not - use libf2c. If you expect to depend on this compatibility in the - long term, use the options "-ff2c -ff2c-library" when compiling - all of the applicable code (which should at the very least trigger - compiler warning messages, if not enable f2c compatibility compilation, - in future versions of g77). - -2. Due to #1 above, object files compiled by g77 are not expected to work - well with objects compiled by the native compiler. Libraries compiled - with the native compiler will probably have to be recompiled with - g77 to be used with g77. There are two reasons for this: (1) there - may be subtle type mismatches which cause subroutine arguments - and function return values to get corrupted; (2) native compilers - use libraries of private I/O routines which will not be available - at link time unless you have the native compiler -- and you would - have to explicitly ask for them. For instance, on the Sun you - would have to add "-L/usr/lang/SCx.x -lF77 -lV77" to the link - command. - -3. On some systems, perhaps just those with out-of-date (shared?) libraries, - unresolved-reference errors happen when linking g77-compiled programs - (which should be done using g77). If this happens to you, try appending - `-lc' to the command you use to link the program, i.e. `g77 foo.f -lc'. - g77 already specifies `-lf2c -lm' when it calls the linker, but it - cannot also specify `-lc' because not all systems have a libc.a. - -*PORTING INFORMATION* - -During the private alpha test phase, which lasted about 2.5 years, -g77 was tested by a small number of people worldwide on a fairly -wide variety of machines. - -Some improvements have been made in g77 in version 0.5.17 that -make it easier for g77 to be configured as a cross-compiler. -There is still one known bug (a design bug to be fixed in 0.6) -that prevents configuration of g77 as a cross-compiler under some -circumstances, though there are assumptions made during configuration -that probably make doing non-self-hosting builds a hassle, requiring -manual intervention. - -Generally, g77 can be ported to any configuration to which gcc and -f2c+libf2c can be ported, aside from some of the known problems -in g77 that are scheduled to be fixed for version 0.6. - -But, if you are unable to port gcc and f2c (or at least the libF77 -and liI77 libraries) to a particular configuration, don't bother -asking the g77 maintainer about a g77 port -- the feasability of -that project depends largely on a gcc port first being done, so -talk to the gcc maintainers about that (e.g. look in the gcc/SERVICE -file for information on people who might be willing to do such a port). - -*USING THE g77 COMMAND* - -The `g77' command is designed to make compiling and linking Fortran -programs somewhat easier than using the `gcc' command. It does this -by analyzing the command line somewhat and changing it appropriately -before submitting it to the `gcc' command. Use the `-v' option with `g77' -to see what is going on -- the first line of output is the invocation -of the `gcc' command. Use `--driver=true' to disable actual invocation -of `gcc' (since `true' is the name of a UNIX command that simply returns -success status). - -In addition to supporting all the options supported by the `gcc' command, -the `g77' command also supports this option: - ---driver=COMMAND - Specifies that COMMAND, rather than `gcc', is to be invoked by `g77' - to do its job. Example: Within the gcc build directory after - building GNU Fortran (but without having to install it), - `g77 --driver=./xgcc foo.f'. - -*SUMMARY OF FORTRAN-SPECIFIC COMMAND-LINE OPTIONS* - -These options are supported both by `g77' and by `gcc' as -modified (and reinstalled) by the `g77' distribution. `*' -indicates defaults, where appropriate. - --fversion - Ensure that the g77-specific version of the compiler phase is reported, - if run. (This is supplied by default when `-v' or `--version' is specified - when invoking `g77' or `gcc' to compile one or more Fortran source files.) - --fident * --fno-ident - Specify whether to process #ident directives. - --ff90 --fno-f90 * - Specify whether to allow certain F90 constructs. - - NOTE: This also changes the interpretation of `REAL(Z)', where Z - is type DOUBLE COMPLEX. With -fno-f90 in force, that expression - is defined to return type REAL, to conform to apparent industry - convention for the DOUBLE COMPLEX extension to FORTRAN 77. With - -ff90 in force, that expression is defined to return type DOUBLE - PRECISION. - - In other words, with -fno-f90, REAL(Z) is the same as REAL(REAL(Z)). - With -ff90, it is the same as DBLE(Z). - --fautomatic * --fno-automatic - Specify whether to assume that unSAVEd variables and arrays are intentionally - left unSAVEd. - --fdollar-ok --fno-dollar-ok * - Specify whether `$' is a valid character in a symbol name. - --ff2c * --fno-f2c - Specify whether compatibility with f2c-compiled code (other than that - in libf2c) is desired. -fno-f2c can generate faster code for things like - COMPLEX functions. THE SAME OPTION MUST BE USED FOR COMPILING ALL - FORTRAN CODE IN A PARTICULAR PROGRAM!! - - Note that f2c compatibility is a fairly static target to achieve, - though not necessarily perfectly so. However, disabling f2c - compatibility definitely causes g77 to generate code that might - well be incompatible with future versions of g77 when the same - option is in force. - - Therefore, if you are using g77 to compile libraries and other - object files for possible future use and you don't want to require - recompilation for future use with subsequent versions of g77, you - might want to stick with f2c compatibility for now, and carefully - watch for any announcements about changes to the f2c/libf2c interface - that might affect existing programs. - --ff2c-library * --fno-f2c-library - Specify whether use of `libf2c' is desired (it is currently not - valid to specify -fno-f2c-library). - --ffree-form --fno-free-form * --ffixed-form * --fno-fixed-form - Specify whether fixed (traditional) or free (new with Fortran 90) form - is used in the source file. - --fpedantic --fno-pedantic * - Like -pedantic, but applies only to Fortran constructs (while - -pedantic applies to C constructs, such as use of `\e' in a - character constant within a directive like `#include', and - Fortran constructs as well). - --fvxt-not-f90 --ff90-not-vxt * - Specify whether Fortran 90 or popular `VXT' extensions such as the - TYPE statement are to be assumed for ambiguous constructs -- e.g. with - -ff90-not-vxt, `PRINT *,"double-quoted string"' is valid, while with - -fvxt-not-f90, `PRINT *,"2000' is valid. There is no way to allow - both constructs in the general case, since statements like - `PRINT *,"2000 !comment?"' would be ambiguous. - --fugly --fno-ugly * - Specify whether certain `ugly' constructs are to be quietly accepted - by the compiler. Implies the appropriate `ugly-args' and `ugly-init' - options. For example, with -fno-ugly, CALL FOO(,) means to pass one - null argument, whereas with -fugly, it means to pass two null - arguments. - --fugly-args * --fno-ugly-args - Specify whether passing hollerith and typeless constants as actual - arguments is supported (e.g. CALL FOO(4HABCD)). - --fugly-init * --fno-ugly-init - Specify whether using hollerith and typeless constants as initial - values (PARAMETER and DATA), and using character constants to - initialize numeric types and vice versa, are supported. (For example, - "DATA I/'F'/, CHRVAR/65/, J/4HABCD/" is allowed by -fugly-init.) - --finit-local-zero --fno-init-local-zero * - Specify whether variables and arrays that are local to a program unit - (not in COMMON and not passed as an argument) are to be initialized - to binary zeros. Since there is a run-time penalty for such - initialization of stack-based (non-SAVEd) variables, it might be a - good idea to also use -fno-automatic with -finit-local-zero. - --fbackslash * --fno-backslash - Specify whether `\' is specially interpreted in character and hollerith - constants a la C and some Fortran compilers. For example, with - -fbackslash in effect, 'A\nB' specifies three characters, with - the second one being newline; with -fno-backslash, it specifies - four characters, the second and third being backslash and the letter - `n', respectively. - - Note that making -fbackslash the default is a concession to the community - of UNIX `f77' users. This feature is an unfortunate carry-over from - the C language, as it contradicts the spirit (though not the letter) - of the ANSI FORTRAN 77 standard. At the time the feature was added to - f77, it was probably difficult to come up with a better way to provide - the ability to specify arbitrary characters wherever they might be - needed without doing a lot more work on the compiler, however. - - Also note that g77's implementation of the feature seems to be more - general than that offered by some Fortran compilers such as f2c. - g77's implementation basically parallels gcc's, while other compilers - might not support '\003' as a single character, for example, resulting - in differing interpretations of constants such as 'A\003B'. - --funderscoring * --fno-underscoring - With -funderscoring in effect, g77 appends two underscores to names with - underscores and one underscore to external names with no underscores. - Use of -fno-underscoring is not recommended unless you are experimenting - with issues such as integration of (GNU) Fortran into existing - system environments (vis-a-vis existing libraries, tools, etc.). - - For example, with -funderscoring, and assuming other defaults like - -fcase-lower and that j() and max_count() are external functions - while my_var is a local variable, a statement like - - I = J() + MAX_COUNT (MY_VAR) - - is implemented as something akin to: - - i = j_() + max_count__(my_var__); - - With -fno-underscoring, the same statement is implemented as: - - i = j() + max_count(my_var); - - Use of -fno-underscoring allows direct specification of user-defined names - while debugging and when interfacing g77-compiled code with other languages. - (Note that just because the names match does not mean that the interface - implemented by g77 for an external name matches the interface implemented - by some other language for that same name! Also note that, with - -fno-underscoring, the lack of appended underscores introduces the very - real possibility that a user-defined external name will conflict with a - name in a system library, which could make finding unresolved-reference bugs - quite difficult in some cases -- they might occur at program run time, - and show up only as buggy behavior.) - - In future versions of g77, we hope to improve naming and linking - issues so that debugging always involves using the names as they appear - in the source, even if the names as seen by the linker are mangled to - prevent accidental linking between procedures with incompatible - interfaces. - --fsecond-underscore * --fno-second-underscore - Controls whether to append a second underscore to names of - entities specified in the Fortran source file. - - This option has no effect if -funderscoring is in effect. - - Otherwise, with -fno-second-underscore, an external name such as - `MAX_COUNT' is implemented as a reference to the link-time external - symbol `max_count_', isntead of `max_count__'. - --fintrin-case-initcap --fintrin-case-upper --fintrin-case-lower * --fintrin-case-any - Specify expected case for intrinsic names. - --fmatch-case-initcap --fmatch-case-upper --fmatch-case-lower * --fmatch-case-any - Specify expected case for keywords. - --fsource-case-upper --fsource-case-lower * --fsource-case-preserve - Specify whether source text other than character and hollerith constants - is to be translated to uppercase, to lowercase, or preserved as is. - --fsymbol-case-initcap --fsymbol-case-upper --fsymbol-case-lower --fsymbol-case-any * - Specify valid cases for user-defined symbol names. - --fcase-strict-upper - Same as `-fintrin-case-upper -fmatch-case-upper -fsource-case-preserve - -fsymbol-case-upper'. (Requires all pertinent source to be in - uppercase.) - --fcase-strict-lower - Same as `-fintrin-case-lower -fmatch-case-lower -fsource-case-preserve - -fsymbol-case-lower'. (Requires all pertinent source to be in - lowercase.) - --fcase-initcap - Same as `-fintrin-case-initcap -fmatch-case-initcap -fsource-case-preserve - -fsymbol-case-initcap'. (Requires all pertinent source to be in - initial capitals, as in `Print *,SqRt(Value)'.) - --fcase-upper - Same as `-fintrin-case-any -fmatch-case-any -fsource-case-upper - -fsymbol-case-any'. (Maps all pertinent source to uppercase.) - --fcase-lower - Same as `-fintrin-case-any -fmatch-case-any -fsource-case-lower - -fsymbol-case-any'. (Maps all pertinent source to lowercase.) - --fcase-preserve - Same as `-fintrin-case-any -fmatch-case-any -fsource-case-preserve - -fsymbol-case-any'. (Preserves all case in user-defined symbols, - while allowing any-case matching of intrinsics and keywords. For - example, `call Foo(i,I)' would pass two different variables named - `i' and `I' to a procedure named `Foo'.) - --fdcp-intrinsics-delete --fdcp-intrinsics-hide --fdcp-intrinsics-disable --fdcp-intrinsics-enable * - Specify status of DEC's COMPLEX-related intrinsics. - --ff2c-intrinsics-delete --ff2c-intrinsics-hide --ff2c-intrinsics-disable --ff2c-intrinsics-enable * - Specify status of f2c-specific intrinsics. - --ff90-intrinsics-delete * --ff90-intrinsics-hide --ff90-intrinsics-disable --ff90-intrinsics-enable - Specify status of F90-specific intrinsics. - --fmil-intrinsics-delete --fmil-intrinsics-hide --fmil-intrinsics-disable --fmil-intrinsics-enable * - Specify status of MIL-STD-1753-specific intrinsics. - --funix-intrinsics-delete --funix-intrinsics-hide --funix-intrinsics-disable --funix-intrinsics-enable * - Specify status of UNIX intrinsics. E.g. if your code invokes FLUSH() as - a library function and thus worked at 0.5.15 or earlier, or with f2c or - other f77 compilers, either add the EXTERNAL FLUSH statement or, perhaps - more convenient for you, compile with the -funix-intrinsics-hide or - -funix-intrinsics-delete option. - - Note that ABORT, EXIT, FLUSH, SIGNAL, and SYSTEM are intrinsic subroutines, - not functions (since they have side effects), so to get the return values - from SIGNAL and SYSTEM, append a final argument specifying an INTEGER - variable or array element to receive the returned status. (For example, - "CALL SYSTEM('rm foo',ISTAT)".) - - FLUSH() accepts an optional single INTEGER argument, since many Fortran - implementations allow or require a unit number. Currently, since libf2c - does not flush a given unit number, this argument is not used -- all - units are flushed by libf2c's implementation of FLUSH(). Do not - depend on this behavior -- if you want to flush all units, CALL FLUSH - with no arguments. - - EXIT() accepts an optional single INTEGER argument. If omitted, zero - is the default (as in CALL EXIT(0)). The default might change on - configurations where the "normal return status" is not zero, however. - If you want to return a "success" status, it is best to CALL EXIT with - no arguments in your code, and let g77 choose the appropriate default. - --fvxt-intrinsics-delete * --fvxt-intrinsics-hide --fvxt-intrinsics-disable --fvxt-intrinsics-enable - Specify status of VXT intrinsics. - --ffixed-line-length-N - Set column after which characters are ignored in typical fixed-form - lines in the source file. Popular values for N include 72 (the - standard and the default), 80 (card image), and 132 (corresponds - to `extended-source' options in some popular compilers). N may - be `none', meaning that the entire line is meaningful and that - continued character constants never have implicit spaces appended - to them to fill out the line. -ffixed-line-length-0 means the - same thing as -ffixed-line-length-none. - --Wsurprising - Warn about "suspicious" constructs. These constructs typically mean - something different to a standard-conforming Fortran compiler, such - as g77, than the programmer who uses them expects, and these differences - can result in subtle, compiler-dependent (even machine-dependent) - behavioral differences. The constructs warned about include: - - - Expressions having two arithmetic operators in a row, such as - "X*-Y". Such a construct is nonstandard, and can produce - unexpected results in more complicated situations such as - "X**-Y*Z". g77, and many other compilers, interpret this - example differently than programmers, and a few other compilers, - in that they interpret it as "X**(-(Y*Z))" instead of "(X**(-Y))*Z". - The difference is notable in examples like "2**-2*1.", which g77 - and other compilers evaluate to ".25", but a programmer might - expect to evaluate to "0.", due to the way the precedence affects - the type promotion. (The -fpedantic option also warns about - expressions having two arithmetic operators in a row.) - - - Expressions with a unary minus followed by an operand and then - a binary operator other than plus or minus. For example, "-2**2" - produces a warning, because the precedence is "-(2**2)", yielding - "-4", not "(-2)**2" (yielding "4") as a programmer might expect. - - - DO loops with REAL or DOUBLE PRECISION DO variables (including - implied-DO loops in I/O and DATA statements), since the implementation - required by the standard, combined with the vagaries of floating-point - arithmetic on most machines, will likely result in terminating - conditions not meeting the programmer's expectations (with regard - to the terminal value for the loop). - -*SUMMARY OF COMPILATION OPTIONS USEFUL TO FORTRAN USERS* - -Using the gcc info documentation as a reference, here are categories -of options that g77 and gcc support when compiling and linking Fortran -programs: - - *Overall Options* - *Debugging Options* (though support for -g is incomplete) - *Optimization Options* - *Preprocessor Options* (some do not affect Fortran's INCLUDE statement) - *Assembler Option* - *Linker Options* - *Directory Options* - *Target Options* - *Machine Dependent Options* (some might not work for Fortran, however) - *Code Generation Options* (beware -fno-common, however) - -g77 supports many other options supported by gcc that apply to code -generation and preprocessing, but does not support options that apply -to interpreting C or C++ programs. g77 also does not yet support some -options such as `-Wid-clash-N', nor does it yet support `-g' fully -(as noted above). - -Here are some options that are more generally applicable to gcc than -just the g77 environment, but which might nevertheless be particularly -interesting to g77 users. See the explanations for these options in -the gcc documentation, in addition to whatever explanations have -been cobbled together below. - --ffast-math --ffloat-store --fsyntax-only --fmove-all-movables --freduce-all-givs --frerun-loop-opt - See the gcc documentation. - --pedantic --pedantic-errors - These options imply -fpedantic, described in this documentation. - See the gcc documentation for more information on their general meaning. - --mieee-fp (i386 and similar configurations only) - See the gcc documentation. - --w --W --Werror --Wimplicit --Wuninitialized --Wunused - g77 has code to support these gcc options. See the gcc documentation. - Note that for -Wuninitialized to work, optimization must be specified - (via `-O', for example). `-Wimplicit' has the effect of using - the IMPLICIT NONE statement in every program unit, and as such is - g77's version of what f77 traditionally provides via the `-u' option. - --Wall - Currently the same as `-Wunused' and, if optimization is enabled, - `-Wuninitialized' as well. Future versions of g77 might add more - warnings that are also enabled via `-Wall', using the same general - policy used to make these decisions for gcc. - --I- --Idir - See gcc documentation for information on the `-I' option. When compiling - Fortran source files, `-I' affects not only preprocessor interpretation - of #include, but compiler-phase interpretation of the INCLUDE statement - as well. Note that `-Idir' must be specified _without_ any spaces between - -I and the directory name -- that is, `-Idir' is valid, but `-I dir' - is rejected by the g77 compiler (though the preprocessor supports - the latter form). Also note that the general behavior of -I and - INCLUDE is pretty much the same as of -I with #include in gcc's C - preprocessor, with regard to looking for `header.gcc' files and other - such things - -*SUMMARY OF OVERLY CONVENIENT COMMAND-LINE OPTIONS* - -These options should be used only as a quick-and-dirty way to determine -how well your program will run under different compilation models -without having to change the source. Some are more problematic -than others, depending on how portable and maintainable you want the -program to be (and, of course, whether you are allowed to change it -at all is crucial). - -You should not continue to use these command-line options to compile -a given program, but rather should make changes to the source code: - --finit-local-zero - Use explicit DATA (or other initial-value-setting) statements - to initialize local variables and arrays to zero. Consider using - -Wuninitialized (which requires -O) to find likely candidates, but - do not specify -finit-local-zero or -fno-automatic, or this technique - won't work. --fno-automatic - Use SAVE statements in the appropriate places instead. Consider using - -Wuninitialized (which requires -O) to find likely candidates, but - do not specify -finit-local-zero or -fno-automatic, or this technique - won't work. --fugly* - Fix the source code so that -fno-ugly (the default) will work. - Note that, for many programs, it is difficult to practically - avoid using the features enabled via -fugly-init, and these - features pose the lowest risk of writing nonportable code of the - various "ugly" features. --fxxx-intrinsics-hide - Change the source code to use EXTERNAL for any external procedure - that might be the name of an intrinsic. It is easy to find these - using -fxxx-intrinsics-disable. - -*USER-VISIBLE CHANGES DURING 0.5.x* - -In 0.5.18: - -- The BYTE and WORD statements now are supported, to a limited - extent. - -- INTEGER*1, INTEGER*2, INTEGER*8, and their LOGICAL equivalents, - now are supported to a limited extent. Among the missing elements - are complete intrinsic and constant support. - -- Support automatic arrays in procedures. For example, - `REAL A(N)', where `A' is not a dummy argument, specifies that - `A' is an automatic array. The size of `A' is calculated from - the value of `N' each time the procedure is called, that amount - of space is allocated, and that space is freed when the procedure - returns to its caller. - -- Add `-fno-zeros' option, enabled by default, to reduce compile-time - CPU and memory usage for code that provides initial zero values - for variables and arrays. - -- Introduce three new options that apply to all compilations by - g77-aware GNU compilers -- -fmove-all-movables, -freduce-all-givs, - and -frerun-loop-opt -- which can improve the run-time performance - of some programs. - -- Replace much of the existing documentation (including the file you - are reading right now) with a single Info document. - -- New option -fno-second-underscore. - -In 0.5.17: - -- ERF() and ERFC() intrinsics are now generic intrinsics, mapping to - ERF/DERF and ERFC/DERFC, respectively -- NOTE: use INTRINSIC ERF,ERFC - in any code that might reference these as generic intrinsics, to - improve the likelihood of diagnostics (instead of subtle run-time - bugs) when using compilers that don't support these as intrinsics - -- New option -Wsurprising - -- DO loops with non-INTEGER variables now diagnosed only when -Wsurprising - specified (previously diagnosed unless -fpedantic or -fugly specified) - -In 0.5.16: - -- libf2c changed to output a leading zero (0) digit for floating-point - values output via list-directed and formatted output (to bring g77 - more in line with many existing Fortran implementations -- the - ANSI FORTRAN 77 standard leaves this choice to the implementation) - -- libf2c no longer built with debugging info intact, making it much - smaller - -- Automatic installation of `g77' command now works - -- Diagnostic messages from compiler now more informative, a la gcc, - including messages like "In function `foo':" and "In file included - from...:" - -- New group of intrinsics called `unix', including ABORT, DERF, DERFC, - ERF, ERFC, EXIT, FLUSH, GETARG, GETENV, SIGNAL, and SYSTEM - -- -funix-intrinsics-{delete,hide,disable,enable} options introduced - -- -fno-underscoring option introduced - -- --driver=COMMAND option introduced to the g77 command - -- Support for gcc's -fident and -fno-ident options extended to g77 - -- `g77 -v' returns much more version info, for submitting better bug - reports easily (for example -- assuming there are still any bugs left - in g77 ;-) - -- Many improvements to the g77 command to better fulfill its role as - a front-end to the gcc driver (e.g. recognition of both `-v' and - `--version' instead of just `-v') - -- Compiling preprocessed (*.F) files now results in better diagnostics - and debugging information, as the source-location info now is passed - all the way through the compilation process instead of being lost - -In 0.5.15: - -- -ffixed-line-length-N option introduced - -In 0.5.14: - -- Support for gcc's -I option extended to g77 - -- -fbackslash option introduced - -- -fugly-args option enabled by default (allows CALL FOO(4HABCD)) - -- -fugly-init option introduced - -- -finit-local-zero option introduced - -- Support for gcc's -Wimplicit option extended to g77 - -- -Wall now implies -Wunused and, when -O is specified, -Wuninitialized - -- Hollerith constants as actual arguments now are passed by reference - instead of by value -- so CALL FOO(4HABCD) is now compiled exactly - the same as CALL FOO(%REF('ABCD')), instead of as CALL FOO(%VAL('ABCD')) - -- Hollerith constants converted to larger types now are padded on the - right with spaces; converted to smaller types, warnings are issued - if non-spaces are truncated on the right - -- Format specifications of arrays of types other than CHARACTER are - allowed in I/O statements, such as when they contain Hollerith - data - -- Typeless constants as actual arguments now are passed by reference - to a INTEGER version of the constant instead of by value - -- Typeless constants converted to larger types are padded on the left - with zeros; converted to smaller types, warnings are issued if non-zero - bits are truncated on the left - -- %DESCR() of a non-CHARACTER expression treats the expression as if - it were CHARACTER, passing both a pointer to the expression and the - length of the type of the expression in bytes, by value, in the - "hidden" list of lengths used for CHARACTER arguments - -- The ICHAR(), IACHAR(), and LEN() intrinsics now accept character - expressions involving concatenation of assumed-length dummy arguments - -- BLOCK DATA program units now can contain NAMELIST, EXTERNAL, INTRINSIC, - and VOLATILE statements - -- Zero-length character expressions now supported - -- f2c's IMAG() intrinsic now supported - -- INCLUDE statement restrictions, such as no continuation lines allowed, - now lifted - -*WHAT IS AND ISN'T SUPPORTED* - -This release supports ANSI FORTRAN 77 with the following caveats: - -- No passing of an external procedure as an actual argument if the procedure's - type is declared CHARACTER*(*) (because it isn't clear the standard - really considers this standard-conforming, but it should be fairly easy - to support if someone gets an RFI showing it is standard-conforming). - -- No passing of a dummy procedure as an actual argument if the procedure's - type is declared CHARACTER*(*) (again, because it isn't clear the - standard considers this conformant). - -- The DO variable for an implied-DO construct in a DATA statement may - not be used as the DO variable for an outer implied-DO construct (this - is also disallowed by Fortran 90, as it offers no additional capabilities). - Note that it is very unlikely that any existing Fortran code - tries to use this unsupported construct. - -- An array element initializer in an implied-DO construct in a DATA - statement must contain at least one reference to the DO variables of - each outer implied-DO construct (this is also required by Fortran 90, - as FORTRAN 77's more permissive requirements offer no additional - capabilities). However, g77 doesn't necessarily diagnose all cases - where this requirement is not met. Note that in any case it is - very unlikely that any existing Fortran code tries to use this - unsupported construct. - -This release supports ANSI FORTRAN 77 plus: - -- -g for local variables and external names; COMMON variables, local - EQUIVALENCE variables, labels, and so on aren't supported yet. - -- LOC(), if -funix-intrinsics-enable is in force. - -- %LOC, %VAL, %REF, and %DESCR -- where %DESCR currently means the same thing - as passing the argument as if it was type CHARACTER. - -- MIL-STD 1753 features (IAND, IOR, MVBITS, DO WHILE, END DO, etc). - -- NAMELIST. - -- Most f2c/f77 intrinsics (AND, OR, LSHIFT, RSHIFT, and so on). - -- DOUBLE COMPLEX and related intrinsics (standard and f2c varieties). - -- Various Fortran 90 features. - -- Various DEC VAX/VMS FORTRAN v4.0 features. - -- Various f2c features. - -- Source files that are uppercase-only (enforced), lowercase-only - (enforced), caseless, and various other combinations as chosen via - command-line options. - -- Arbitrary (limited only by available memory) number of continuation - lines. - -- Use of '&' in column 1 to indicate a continuation line a la f2c. - -- Dollar signs ('$') in identifiers (other than as the first character) - when the command-line option -fdollar-ok is specified. - -*BLOCK DATA AND LIBRARIES* - -To ensure that BLOCK DATA program units are linked, especially a concern -when they are put into libraries, give each one a name (as in -BLOCK DATA FOO) and make sure there is an EXTERNAL FOO statement -in every program unit that uses any COMMON area initialized by the -corresponding BLOCK DATA. g77 currently compiles a BLOCK DATA as -if it were a SUBROUTINE, that is, it generates an actual procedure -having the appropriate name. The procedure does nothing but return -immediately if it happens to be called. For EXTERNAL FOO, where FOO -is not otherwise referenced in the same program unit, g77 assumes -it is a BLOCK DATA and generates a reference to it so the linker will -make sure it is present. (Specifically, g77 outputs in the data -section a static pointer to the external name FOO.) - -The implementation g77 currently uses to make this work is -one of the few things not compatible with f2c as currently -shipped. f2c currently does nothing with EXTERNAL FOO except -issue a warning that FOO is not otherwise referenced, and for -BLOCK DATA FOO, f2c doesn't generate a dummy procedure with the -name FOO. The upshot is that you shouldn't mix f2c and g77 in -this particular case. If you use f2c to compile BLOCK DATA FOO, -then any g77-compiled program unit that says EXTERNAL FOO will -result in an unresolved reference when linked. If you do the -opposite, then FOO might not be linked in under various -circumstances (such as when FOO is in a library, or you're -using a "clever" linker). - -The changes you make to your code to make g77 handle this -situation, however, appear to be a widely portable way to handle -it. That is, many systems permit it (as they should, since the -FORTRAN 77 standard permits EXTERNAL FOO when FOO is a BLOCK DATA -program unit), and of the ones that might not link BLOCK DATA FOO -under some circumstances, most of them appear to do so once -EXTERNAL FOO is present in the appropriate program units. - -*FORTRAN 90* - -The -ff90 and -fno-f90 command-line options control whether certain -Fortran 90 constructs are recognized. (Other Fortran 90 constructs -might or might not be recognized depending on other options such as --fvxt-not-f90, -ff90-intrinsics-enable, and the current level of support -for Fortran 90.) - -When -ff90 is specified, the following constructs are accepted: - - - REAL(Z), where Z is DOUBLE COMPLEX, as meaning DBLE(Z) instead - of the canonical F77 meaning of REAL(REAL(Z)) - - Zero-length CHARACTER entities even when -fpedantic specified - - Zero-size array dimensions (as in INTEGER I(10,20,4:2)) (not supported - by run-time code, so diagnostics are produced for g77 nevertheless). - - DOUBLE COMPLEX (explicit or implicit) even when -fpedantic specified. - - Substrings of constants (as in "'hello'(3:5)") even when -fpedantic - specified. - - DATA statements allowed to precede executable statements even when - -fpedantic specified (note that this is not the same as whether - "DATA I/1/" is permitted before other specifications for I, such as - "INTEGER I" -- it does allow, however, "DATA I/1/" before "INTEGER J"). - - Semicolon as statement separator even when -fpedantic specified - (so "CALL FOO; CALL BAR" works). - - Underscores are not accepted as the first character of a - symbol name, since F90 provides a different interpretation - for certain cases where that would occur (though g77 does not - yet support that interpretation). - -If -fpedantic is specified, the following constructs result in diagnostics: - - - Use of semicolons on line with INCLUDE statement. - -*SOURCE CODE FORM* - -The -ffree-form (aka -fno-fixed-form) and -ffixed-form (aka -fno-free-form) -command-line options govern how the source file is interpreted. Fixed form -corresponds to classic ANSI FORTRAN 77 (plus popular extensions, such as -allowing tabs) and Fortran 90's fixed form. Free form corresponds to -Fortran 90's free form (though possibly not entirely up-to-date, and -without complaining about some things that for which Fortran 90 requires -diagnostics, such as "R = 3 . 1"). - -The way a Fortran compiler views source files depends entirely on the -implementation choices made for the compiler. GNU Fortran currently -tries to be somewhat like a few popular compilers (f2c, DEC Fortran, -and so on), though a cleaner default definition along with more -flexibility offered by command-line options is likely to be offered -with g77-0.6. - -Here are some facts regarding the way g77 interprets source lines: - -- Carriage returns ('\r') in source lines are ignored. This is somewhat - different from f2c, which seems to treat them as spaces outside - character/hollerith constants, and encodes them as '\r' inside such - constants. - -- A source line with a TAB character anywhere in it is treated as - entirely significant -- however long it is -- instead of ending - in column 72 (for fixed-form source) or 132 (for free-form source). - This also is different from f2c, which encodes tabs as '\t' inside - character and hollerith constants, but nevertheless seems to treat - the column position as if it had been affected by any tab. g77 - effectively translates tabs to the appropriate number of spaces - (a la the default for the UNIX `expand' command) before doing any - other processing, other than (currently) noting whether a tab - was found on a line and using this info to decide how to interpret - the length of the line and continued constants. - - NOTE: this default behavior probably will change for 0.6, when - it will presumably be available via a command-line option. The - default as of 0.6 is expected to be a "pure visual" model, where - tabs are immediately converted to spaces and otherwise have no - effect, so the way a typical user sees source lines produces a - consistent result no matter how the spacing in those source lines - is actually implemented via tabs, spaces, and trailing tabs/spaces - before newline. Command-line options are likely to be added to - specify whether all or just-tabbed lines are to be extended to - 132 or full input-line length, and perhaps even an option will be - added to specify the truncated-line behavior to which Digital compilers - default. - -- Source lines shorter than the applicable fixed length are treated - as if they were padded with spaces to that length. This affects - only continued character and hollerith constants, and is a different - interpretation than provided by some other popular compilers (although - a bit more consistent with the traditional punched-card basis of - Fortran and the way the Fortran standard expressed fixed source form). - g77 might someday offer an option to warn about cases where differences - might be seen as a result of this treatment, and perhaps an option to - specify the alternate behavior as well. - - Note that this padding does not apply to lines that are effectively - of infinite length -- such lines are specified using command-line - options like -ffixed-line-length-none, for example. - -*TYPES, SIZES, PRECISIONS, AND CONSTANTS* - -Fortran implementations have a fair amount of freedom given them by the -standard as far as how much storage space is used and how much precision -is offered by the various types such as LOGICAL, INTEGER, REAL, DOUBLE -PRECISION, COMPLEX, and CHARACTER. Further, many compilers offer so-called -"*N" notation, but the meaning of N varies across compilers and target -architectures. - -The standard requirements are that LOGICAL, INTEGER, and REAL occupy -the same amount of storage space, and that COMPLEX and DOUBLE PRECISION -take twice as much storage space as REAL. Further, it requires that -COMPLEX entities be ordered such that when a COMPLEX variable is -EQUIVALENCE'd with a two-element REAL array named R, R(1) corresponds -to the real element and R(2) to the imaginary element of the COMPLEX -variable. No particular requirements as to precision of any of these -are placed on the implementation, nor is the relationship of storage -sizes of these types to the CHARACTER type specified by the standard. - -g77 follows the above requirements to the letter, warning when compiling -a program requires placement of items in memory that contradict the -requirements of the target architecture. (For example, a program can -require placement of a DOUBLE PRECISION on a boundary that is not an -even multiple of its size, but still an even multiple of the size of -a REAL variable. On some target architectures, using the canonical -mapping of Fortran types to underlying architectural types, such -placement is prohibited by the machine definition. g77 warns about -such situations when it encounters them.) - -g77 follows consistent rules for configuring the mapping between -Fortran types, including the "*N" notation, and the underlying -architectural types as accessed by a similarly-configured applicable -version of the gcc compiler. These rules offer a widely portable, -consistent Fortran/C environment, although they might well conflict -with the expectations of users of Fortran compilers designed and -written for particular architectures. - -These rules are based on the configuration that is in force for the -version of gcc built in the same release as g77: - - REAL: same size as whatever gcc calls a "float" - DOUBLE PRECISION: same size as whatever floating-point type gcc provides - that is twice the size of a "float" (usually a "double") - INTEGER: a gcc integral type that is the same storage size as "float" - LOGICAL: same size as INTEGER - COMPLEX: two REALs - DOUBLE COMPLEX: two DOUBLE PRECISIONs - - numeric-type*N (any type other than CHARACTER, such as INTEGER*2): - is N times the size of whatever gcc calls a "char" - - numeric-type(KIND=N): N=1 for REAL, INTEGER, LOGICAL, COMPLEX; - N=2 for DOUBLE PRECISION, DOUBLE COMPLEX, char INTEGER/LOGICAL (*1); - N=3 for short INTEGER/LOGICAL (*2); - N=4 for long long INTEGER/LOGICAL (*8). - [These proposed values might change in the future.] - -Regarding constants, g77 strictly assigns types to all constants not -documented as "typeless" (the typeless constants include things like -"Z'1'"). Context is never a determining factor for the type, and hence -the interpretation, of a typed constant. Examples: "1" is always type -INTEGER, "3.141592653545256234" is always type REAL (even if the -additional precision specified is lost, and even when used in a -DOUBLE PRECISION context), "1E0" is always type REAL, and "1D0" is -always type DOUBLE PRECISION. - -Many other Fortran compilers attempt to assign types to typed constants -based on their context. This results in hard-to-find bugs, nonportable -code, and is not in the spirit (though it strictly follows the letter) -of the 77 and 90 standards. g77 will not support these dangerous -semantics, but might offer, in a future release, explicit constructs -by which a wider variety of typeless constants may be specified, and/or -user-requested warnings indicating places where g77 might well be doing -something different than other compilers in this regard. - -*VAX FORTRAN VERSUS FORTRAN 90* - -The -fvxt-not-f90 and -ff90-not-vxt command-line options control how -g77 interprets certain tokens and constructs that are have different -meanings in VAX FORTRAN and Fortran 90. - -When -ff90-not-vxt is specified, the following interpretations are -made: - - - Double-quote character (") delimits character constant just as does - apostrophe ('), rather than beginning an octal constant of INTEGER type. - - Exclamation point in column 5 of fixed-form source file treated as - a continuation character rather than the beginning of a comment (as it - does in any other column). - - "TYPE <symbol-name>" and "TYPE (<symbol-name>), <...>" - statements recognized as the Fortran 90 variety, not I/O statements. - (However, the F90 variety is _not_ supported, so this really just - ensures that g77 will produce a diagnostic instead of trying to - implement the VXT TYPE statement -- which currently is not supported - as well.) - -*LIBRARY AND PROCEDURE-CALLING INTERFACE* - -Currently, -ff2c and -ff2c-library are defaults and -ff2c-library must be -in force for g77 to work properly. - -The -ff2c option specifies that g77 is to generate code that is -link-time and run-time compatible with code generated by an -version of f2c built to be generally compatible with g77. (This -will normally be the case, but it is possible that with older or -perhaps even newer versions of f2c, or with certain configuration -changes to f2c internals, incompatibilities will nevertheless -result.) - -Specifying -fno-f2c allows g77 to generate, in some cases, faster code. -For example, how REAL and [DOUBLE] COMPLEX FUNCTIONs are called is -governed by the -ff2c command-line option. With -fno-f2c, they -are compiled as returning the appropriate type (float, __complex__ float, -__complex__ double), whereas with -ff2c, they are compiled differently -(with perhaps slower run-time performance) to accommodate the restrictions -inherent in f2c's use of K&R C as an intermediate language -- REAL -functions return double, while [DOUBLE] COMPLEX functions return void -but have an extra argument pointing to a place for the functions to -return their values. (It is possible that in some cases -ff2c might -produce faster code. Experiment and enjoy.) - -An example of the effect of -ff2c-library, which is the default (and -currently must be in force, since g77 compiles code for use only -with libf2c), is that diagnostics are issued for some features -unsupported by the f2c library, such as NAMELIST in combination with -source case preservation. - -*OPTIONS FOR POTENTIALLY BUGGY PROGRAMS* - -The -finit-local-zero option tells g77 to initialize all local variables -and arrays (that are not otherwise explicitly initialized) to binary -zeros. Many other compilers do this, which means lots of Fortran code -developed with those compilers depends on it. It is safer (and probably -would produce a faster program) to find the variables and arrays that -need such initialization and provide it explicitly via DATA, so that --finit-local-zero is not needed. Use the -Wuninitialized option (which -requires -O as well) to find some such cases. - -The -fno-automatic command-line option tells g77 to assume, in essence, that -a SAVE statement is present in every program unit. The effect of this -is that all variables and arrays are made static, i.e. not placed on -the stack or in heap storage. This might cause a buggy program to appear -to work better -- if so, rather than relying on this command-line -option (and hoping all compilers provide the equivalent one), add SAVE -statements to some or all program unit sources, as appropriate. The -default is -fautomatic, which tells g77 to try and put variables and -arrays on the stack where possible and reasonable. Use the -Wuninitialized -option (which requires -O as well), _without_ specifying -fno-automatic, -to find some cases where SAVE is erroneously omitted as an attribute -for variables and arrays. - -The -W options tell g77 to warn about various suspicious constructs. -In particular, the -Wimplicit, `-O -Wuninitialized', and -Wsurprising -options can sometimes identify bugs in programs that appear to work -when compiled by other Fortran compilers but do not work when compiled -by g77 (or vice versa). - -*OPTIONS FOR SPEEDING UP PROGRAMS* - -Aside from the usual gcc options, such as -O, -ffast-math, and so on -(see the gcc documentation), consider trying: - - -fno-f2c, if you aren't linking with any f2c-produced code (other - than libf2c) - -If you're using -fno-automatic already, you probably should change -your code to allow compilation with -fautomatic, because the program -should run faster. Similarly, you should be able to use --fno-init-local-zero instead of -finit-local-zero. This is because -it is rare that every variable affected by these options in a given -program actually needs to be so affected. For example, --fno-automatic, which effectively SAVEs every local variable and -array, affects even things like DO iteration variables, which rarely -need to be SAVEd, and this often reduces run-time performances. -Similarly, -fno-init-local-zero forces such variables to be -initialized to zero -- when SAVEd (e.g. via -fno-automatic), this -by itself generally affects only startup time for a program, but -when not SAVEd, it can slow down the procedure every time it is called. - -See *SUMMARY OF OVERLY CONVENIENT COMMAND-LINE OPTIONS* for information -on the -fno-automatic and -finit-local-zero options and how to convert -their use into selective changes in your own code. - -*PEDANTIC COMPILATION* - -The -fpedantic and -fno-pedantic command-line options control whether -certain non-standard constructs elicit diagnostics (usually in the form -of warnings) from g77. The -fpedantic option is useful for finding -some extensions g77 accepts that other compilers might not accept. -(Note that the -pedantic and -pedantic-errors options always imply --fpedantic.) - -With -ff90 in force along with -fpedantic, some constructs are -accepted that result in diagnostics when -fno-f90 and -fpedantic are -both in force. See *FORTRAN 90* for information on those constructs. - -The constructs for which g77 issues diagnostics when -fpedantic is -specified (and -fno-f90 is in force) are: - - - "READ (<cilist>), <iolist>" -- the standard disallows the comma - here, while allowing it in "READ <f>[, <iolist>]", but many - compilers (including f2c) support the superfluous comma. - - DOUBLE COMPLEX, either explicitly (via explicit or IMPLICIT statement) - or implicitly (as in "C*D", where C is COMPLEX and D is DOUBLE - PRECISION, which is prohibited by the standard because it should - produce a non-standard DOUBLE COMPLEX result). - - Automatic conversion of LOGICAL, REAL, DOUBLE PRECISION, and COMPLEX - expressions to INTEGER in contexts such as: array-reference indexes; - alternate-RETURN values; computed GOTO; FORMAT run-time expressions - (not yet supported); dimension lists in specification statements; - numbers for I/O statements (such as "READ (UNIT=3.2, <...>)"); sizes - of CHARACTER entities in specification statements; kind types in - specification entities (a Fortran 90 feature); initial, terminal, - and incrementation parameters for implied-DO constructs in DATA - statements. - - Automatic conversion of LOGICAL expressions to INTEGER in context - such as: arithmetic IF (where COMPLEX expressions are completely - disallowed). - - Substring operators applied to character constants and named - constants (such as "PRINT *,'hello'(3:5)", which would print "llo"). - - Null argument passed to statement function (as in "PRINT *,FOO(,3)"). - - Differences between program units regarding whether a given COMMON - area is SAVEd (for targets where program units in a single source - file are "glued" together as they typically are for UNIX development - environments). - - Differences between named-COMMON-block sizes between program units. - - Specification statements following first DATA statement (normally - "DATA I/1/" may be followed by "INTEGER J", though not "INTEGER I", - but -fpedantic complains about both cases). - - Semicolon as statement separator (as in "CALL FOO; CALL BAR"). - - Comma before list of I/O items in WRITE, ENCODE, DECODE, REWRITE - statements (kind of strange, since ENCODE/DECODE/REWRITE should yield - diagnostics with -fpedantic???), as with READ (as explained above). - - Use of '&' in column 1 of fixed-form source (indicates continuation). - - Use of CHARACTER constants to initialize numeric entities, and vice - versa. - - Expressions having two arithmetic operators in a row, such as - "X*-Y". - -*UGLY FEATURES* - -The -fugly and -fno-ugly command-line options determine whether certain -features supported by VAX FORTRAN and other such compilers, but considered -too ugly to be in code that can be changed to use safer and/or more -portable constructs, are accepted. - -The constructs enabled via -fugly include: - - - Automatic conversion between INTEGER and LOGICAL as dictated by - context (typically implies nonportable dependencies on how a - particular implementation encodes .TRUE. and .FALSE.). - - Use of typeless and hollerith constants in non-standard places - (the "standard" here being the appendix in ANSI FORTRAN 77 and - the descriptions in MIL-STD 1753), plus in places controlled - by -fugly-args and -fugly-init. - - Use of LOGICAL variable in ASSIGN and assigned-GOTO statements. - - Single trailing comma meaning "pass extra trailing null argument" in - list of actual arguments to procedure other than statement function - (e.g. "CALL FOO(,)" meaning "pass two null arguments" rather than - "pass one null argument"). - -As of 0.5.11, the -fugly-args and -fno-ugly-args options are available. -The construct enabled via -fugly-args is one of those enabled via --fugly, and is: - - - Passing of typeless and hollerith constants as actual arguments - in procedure invocations - -As of 0.5.14, the -fugly-init and -fno-ugly-init options are available. -The set of constructs enabled via -fugly-init is a subset of those -enabled via -fugly, and is: - - - Use of hollerith and typeless constants in contexts where they - set initial (compile-time) values for variables, arrays, and - named constants -- i.e. DATA and PARAMETER statements, plus - type-declaration statements specifying initial values - - In the same contexts as above, use of character constants to - initialize numeric items and vice versa (one constant per item) - - Use of hollerith and typeless constants on the right-hand side - of assignment statements to numeric types - -The defaults are "-fugly-args -fugly-init". Note that specifying --fugly or -fno-ugly affects all related options, so that "-fugly-args --fno-ugly -fugly-init" would leave only -fugly-init in effect. - -*CASE SENSITIVITY IN SOURCE CODE* - -There are 66 useful settings that affect case sensitivity, plus 10 -settings that are nearly useless, with the remaining 116 settings -being either redundant or useless. - -None of these settings have any effect on the contents of comments -(the text after a "c" or "C" in Column 1, for example) or of character -or Hollerith constants. Note that things like the "E" in the statement -"CALL FOO(3.2E10)" and the "TO" in "ASSIGN 10 TO LAB" are considered -built-in keywords. - -Low-level switches are identified in this discussion thusly: - -A: Source Case Conversion: - 0: Preserve (see Note 1) - 1: Convert to Upper Case - 2: Convert to Lower Case - -B: Built-in Keyword Matching: - 0: Match Any Case (per-character basis) - 1: Match Upper Case Only - 2: Match Lower Case Only - 3: Match InitialCaps Only (see tables for spellings) - -C: Built-in Intrinsic Matching: - 0: Match Any Case (per-character basis) - 1: Match Upper Case Only - 2: Match Lower Case Only - 3: Match InitialCaps Only (see tables for spellings) - -D: User-defined Symbol Possibilities (warnings only) - 0: Allow Any Case (per-character basis) - 1: Allow Upper Case Only - 2: Allow Lower Case Only - 3: Allow InitialCaps Only (see Note 2) - -Note 1: g77 will eventually support NAMELIST in a manner that is -coordinate with these source switches, in that input will be -expected to meet the same requirements as source code in terms -of matching symbol names and keywords (for the exponent letters). -Currently, however, NAMELIST is supported via the f2c library, -which uppercases NAMELIST input and symbol names for matching. -This means not only that NAMELIST output currently shows symbol -(and keyword) names in uppercase even if lower-case source -conversion (option A2) is selected, but that NAMELIST cannot be -adequately supported when source case preservation (option A0) -is selected. If A0 is selected, a warning message will be -output for each NAMELIST statement to this effect. The behavior -of the program is undefined at run time if two or more symbol names -appear in a given NAMELIST such that the names are identical -when converted to upper case (e.g. "NAMELIST /X/ VAR, Var, var"). -For complete and total elegance, perhaps there should be a warning -when option A2 is selected, since the output of NAMELIST is currently -in uppercase but will someday be lowercase (when a g77lib is written), -but that seems to be overkill for a product in alpha (or even beta) -test. - -Note 2: Rules for InitialCaps names are: - - Must be a single uppercase letter OR - - Must start with an uppercase letter and contain at least one - lowercase letter -So A, Ab, ABc, AbC, and Abc are valid InitialCaps names, but AB, A2, and -ABC are not. Note that most, but not all, built-in names meet these -requirements -- the exceptions are some of the two-letter FORMAT -specifiers, such as BN and BZ. - -Here are the names of the corresponding command-line options for -the stand-alone front end (ffe): - -A0: -fsource-case-preserve -A1: -fsource-case-upper -A2: -fsource-case-lower - -B0: -fmatch-case-any -B1: -fmatch-case-upper -B2: -fmatch-case-lower -B3: -fmatch-case-initcap - -C0: -fintrin-case-any -C1: -fintrin-case-upper -C2: -fintrin-case-lower -C3: -fintrin-case-initcap - -D0: -fsymbol-case-any -D1: -fsymbol-case-upper -D2: -fsymbol-case-lower -D3: -fsymbol-case-initcap - -Useful combinations of the above settings, along with abbreviated -option names that set some of these combinations all at once: - - 1: A0-- B0--- C0--- D0--- -fcase-preserve - 2: A0-- B0--- C0--- D-1-- - 3: A0-- B0--- C0--- D--2- - 4: A0-- B0--- C0--- D---3 - 5: A0-- B0--- C-1-- D0--- - 6: A0-- B0--- C-1-- D-1-- - 7: A0-- B0--- C-1-- D--2- - 8: A0-- B0--- C-1-- D---3 - 9: A0-- B0--- C--2- D0--- -10: A0-- B0--- C--2- D-1-- -11: A0-- B0--- C--2- D--2- -12: A0-- B0--- C--2- D---3 -13: A0-- B0--- C---3 D0--- -14: A0-- B0--- C---3 D-1-- -15: A0-- B0--- C---3 D--2- -16: A0-- B0--- C---3 D---3 -17: A0-- B-1-- C0--- D0--- -18: A0-- B-1-- C0--- D-1-- -19: A0-- B-1-- C0--- D--2- -20: A0-- B-1-- C0--- D---3 -21: A0-- B-1-- C-1-- D0--- -22: A0-- B-1-- C-1-- D-1-- -fcase-strict-upper -23: A0-- B-1-- C-1-- D--2- -24: A0-- B-1-- C-1-- D---3 -25: A0-- B-1-- C--2- D0--- -26: A0-- B-1-- C--2- D-1-- -27: A0-- B-1-- C--2- D--2- -28: A0-- B-1-- C--2- D---3 -29: A0-- B-1-- C---3 D0--- -30: A0-- B-1-- C---3 D-1-- -31: A0-- B-1-- C---3 D--2- -32: A0-- B-1-- C---3 D---3 -33: A0-- B--2- C0--- D0--- -34: A0-- B--2- C0--- D-1-- -35: A0-- B--2- C0--- D--2- -36: A0-- B--2- C0--- D---3 -37: A0-- B--2- C-1-- D0--- -38: A0-- B--2- C-1-- D-1-- -39: A0-- B--2- C-1-- D--2- -40: A0-- B--2- C-1-- D---3 -41: A0-- B--2- C--2- D0--- -42: A0-- B--2- C--2- D-1-- -43: A0-- B--2- C--2- D--2- -fcase-strict-lower -44: A0-- B--2- C--2- D---3 -45: A0-- B--2- C---3 D0--- -46: A0-- B--2- C---3 D-1-- -47: A0-- B--2- C---3 D--2- -48: A0-- B--2- C---3 D---3 -49: A0-- B---3 C0--- D0--- -50: A0-- B---3 C0--- D-1-- -51: A0-- B---3 C0--- D--2- -52: A0-- B---3 C0--- D---3 -53: A0-- B---3 C-1-- D0--- -54: A0-- B---3 C-1-- D-1-- -55: A0-- B---3 C-1-- D--2- -56: A0-- B---3 C-1-- D---3 -57: A0-- B---3 C--2- D0--- -58: A0-- B---3 C--2- D-1-- -59: A0-- B---3 C--2- D--2- -60: A0-- B---3 C--2- D---3 -61: A0-- B---3 C---3 D0--- -62: A0-- B---3 C---3 D-1-- -63: A0-- B---3 C---3 D--2- -64: A0-- B---3 C---3 D---3 -fcase-initcap -65: A-1- B01-- C01-- D01-- -fcase-upper -66: A--2 B0-2- C0-2- D0-2- -fcase-lower - -Number 22 is the "strict" ANSI FORTRAN 77 model whereas all input -(except comments, character constants, and hollerith strings) must -be entered in uppercase. Use -fcase-strict-upper to specify this -combination. - -Number 43 is like Number 22 except all input must be lowercase. Use --fcase-strict-lower to specify this combination. - -Number 65 is the "classic" ANSI FORTRAN 77 model as implemented on many -non-UNIX machines whereby all the source is translated to uppercase. -Use -fcase-upper to specify this combination. - -Number 66 is the "canonical" UNIX model whereby all the source is -translated to lowercase. Use -fcase-lower to specify this -combination. - -There are a few nearly useless combinations: - -67: A-1- B01-- C01-- D--2- -68: A-1- B01-- C01-- D---3 -69: A-1- B01-- C--23 D01-- -70: A-1- B01-- C--23 D--2- -71: A-1- B01-- C--23 D---3 -72: A--2 B01-- C0-2- D-1-- -73: A--2 B01-- C0-2- D---3 -74: A--2 B01-- C-1-3 D0-2- -75: A--2 B01-- C-1-3 D-1-- -76: A--2 B01-- C-1-3 D---3 - -The above allow some programs to be compiled but with restrictions that -make most useful programs impossible: Numbers 67 and 72 warn about -_any_ user-defined symbol names (such as "SUBROUTINE FOO"); Numbers -68 and 73 warn about any user-defined symbol names longer than one -character that don't have at least one non-alphabetic character after -the first; Numbers 69 and 74 disallow any references to intrinsics; and -Numbers 70, 71, 75, and 76 are combinations of the restrictions in -67+69, 68+69, 72+74, and 73+74, respectively. - -All redundant combinations are shown in the above tables anyplace -where more than one setting is shown for a low-level switch. For -example, "B0-2-" means either setting 0 or 2 is valid for switch B. -The "proper" setting in such a case is the one that copies the setting -of switch A -- any other setting might slightly reduce the speed of -the compiler, though possibly to an unmeasurable extent. - -All remaining combinations are useless in that they prevent successful -compilation of non-null source files (source files with something other -than comments). - -*INTRINSIC GROUPS* - -A given specific intrinsic belongs in one or more groups. Each group -is deleted, disabled, hidden, or enabled by default or a command-line -option. If a group is deleted, no intrinsics will be recognized as -belonging to that group; if it is disabled, intrinsics will be recognized -as belonging to the group but cannot be referenced (other than via -the INTRINSIC statement) through that group; if hidden, intrinsics -in that group are recognized and enabled (if implemented) only if -the first mention of the actual name of an intrinsic is in an INTRINSIC -statement; if enabled, intrinsics in that group are recognized and -enabled (if implemented). - -The distinction between deleting and disabling a group is illustrated -by the following example. Assume intrinsic FOO belongs only to group -FGR. If group FGR is deleted, the following program unit will successfully -compile, because FOO() will be seen as a reference to an external -function named FOO: - - PRINT *, FOO() - END - -If group FGR is disabled, the above program unit will be compiled with -errors, either because the FOO intrinsic is improperly invoked or, if -properly invoked, it is not enabled. To change the above program so it -references an external function FOO instead of the disabled FOO intrinsic, -add the following line to the top: - - EXTERNAL FOO - -So, deleting a group tells g77 to pretend as though the intrinsics in -that group do not exist at all, whereas disabling it tells g77 to -recognize them as (disabled) intrinsics in intrinsic-like contexts. - -Hiding a group is like enabling it, but the intrinsic must be first -named in an INTRINSIC statement to be considered a reference to the -intrinsic rather than to an external procedure. This might be the -"safest" way to treat a new group of intrinsics when compiling old -code, because it allows the old code to be generally written as if -those new intrinsics never existed, but to be changed to use them -by inserting INTRINSIC statements in the appropriate places. However, -it should be the goal of development to use EXTERNAL for all names -of external procedures that might be intrinsic names. - -If an intrinsic is in more than one group, it is enabled if any of its -containing groups are enabled; if not so enabled, it is hidden if -any of its containing groups are hidden; if not so hidden, it is disabled -if any of its containing groups are disabled; if not so disabled, it is -deleted. This extra complication is necessary because some intrinsics, -such as IBITS, belong to more than one group, and hence should be -enabled if any of the groups to which they belong are enabled, etc. - -The groups are: - -DCP -- DOUBLE COMPLEX intrinsics from the standards (F77, F90) -F2C -- Intrinsics supported by AT&T's f2c converter and/or libf2c -F90 -- Fortran 90 intrinsics -MIL -- MIL-STD 1753 intrinsics (MVBITS, IAND, BTEST, and so on) -UNIX -- UNIX intrinsics (IARGC, EXIT, ERF, and so on) -VXT -- VAX/VMS FORTRAN (as of V4) intrinsics - -The command-line options are: - --fdcp-intrinsics-delete -- Delete DCP intrinsics --fdcp-intrinsics-hide -- Hide DCP intrinsics --fdcp-intrinsics-disable -- Disable DCP intrinsics --fdcp-intrinsics-enable -- Enable DCP intrinsics --ff2c-intrinsics-delete -- Delete F2C intrinsics --ff2c-intrinsics-hide -- Hide F2C intrinsics --ff2c-intrinsics-disable -- Disable F2C intrinsics --ff2c-intrinsics-enable -- Enable F2C intrinsics --ff90-intrinsics-delete -- Delete F90 intrinsics --ff90-intrinsics-hide -- Hide F90 intrinsics --ff90-intrinsics-disable -- Disable F90 intrinsics --ff90-intrinsics-enable -- Enable F90 intrinsics --fmil-intrinsics-delete -- Delete MIL intrinsics --fmil-intrinsics-hide -- Hide MIL intrinsics --fmil-intrinsics-disable -- Disable MIL intrinsics --fmil-intrinsics-enable -- Enable MIL intrinsics --funix-intrinsics-delete -- Delete UNIX intrinsics --funix-intrinsics-hide -- Hide UNIX intrinsics --funix-intrinsics-disable -- Disable UNIX intrinsics --funix-intrinsics-enable -- Enable UNIX intrinsics --fvxt-intrinsics-delete -- Delete VXT intrinsics --fvxt-intrinsics-hide -- Hide VXT intrinsics --fvxt-intrinsics-disable -- Disable VXT intrinsics --fvxt-intrinsics-enable -- Enable VXT intrinsics - -*TROUBLE (BUGS, ETC.)* - -First, read the documentation provided with gcc on bugs. -In particular, read the sections entitled "Trouble" and "Bugs". -Follow this information along with the information listed below. - -Send bug reports for GNU Fortran to `fortran@gnu.ai.mit.edu'. - -If you want quicker response to bugs or other needs you have -regarding g77, look in the service directory for someone who -might help you for a fee. The service directory is found in -the file named `SERVICE' in the GNU CC distribution. - -To find out about existing bugs and ongoing plans for GNU -Fortran, on Internet do `finger -l fortran@gnu.ai.mit.edu' -or whatever is the equivalent on your system. (You might need -to use the address `fortran@gate-1.gnu.ai.mit.edu' instead, -or use gate-2, gate-3, gate-4, etc. instead of gate-1.) - -Alternatively, retrieve `gnu.ai.mit.edu:/g77.plan' via -anonymous ftp, or if you cannot do that, email -`fortran@gnu.ai.mit.edu' asking for a recent copy of the -GNU Fortran .plan file. (The `finger' command shown above -obtains the most recent copy of all these methods.) - -For all g77 bug reports, enclose the version and configuration -info for g77. As of version 0.5.16, an easy way to do this -is to issue the command `g77 -v' and include the output with the -bug report -- ignore any error messages that are displayed when -the linker is run. (Prior to version 0.5.16, an actual Fortran source -file needed to be compiled to get the various Fortran-specific -portions of the g77 product to be invoked and thus display their -version numbers. 0.5.16 has changes to the g77 command to make -this process automatic when `-v' is specified without additional -options specifying actions other than displaying the version info. -NOTE: Version 0.5.16 had a bug in `g77 -v' that resulted in the -removal of the system's `/dev/null' file if the command was issued -while logged in as `root'. Version 0.5.17 fixes this bug. You -might want to use `ls -l /dev/null /dev/zero' to make sure the -entry for `null' is similar to that for `zero' and, if not, contact -your system administrator about using `mknod' to recreate `/dev/null'.) - -Note that you should include with your bug report any files -INCLUDEd by the source file you send, and any files they INCLUDE, -and so on. This is just an extension of the explanation the -gcc documentation offers about having to provide the contents -of #include'd files. - -Diagnostics produced by g77 that you do not understand or expect -are not necessarily g77 bugs. They might indicate problems with -your code that, perhaps, no other compiler has found. Please check -out your code thoroughly, and read applicable g77 documentation, -before assuming g77 has a bug in this area. - -If your program doesn't link, due to unresolved references to names -like "_main", make sure you're using the `g77' command to do the -link, since this command ensures that the necessary libraries are -loaded by specifying `-lf2c -lm' when it invokes the `gcc' -command to do the actual link. (Use the `-v' option to discover -more about what actually happens when you use the `g77' and `gcc' -commands.) Also, try specifying `-lc' as the last item on the g77 -command line, because some systems need it and g77 doesn't do it -automatically. - -If your program successfully compiles and links, but doesn't work, -either producing incorrect results or crashing, there are various -things you can try. Among the things you should try with your code -before giving up, or assuming g77 or libf2c must have a bug, are -the following: - -- Compile all your Fortran code with `-O -W -Wall -Wimplicit' - and make sure all the resulting warnings are ones you expect and - understand. - -- Try using f2c instead of g77 to compile all your code, using the - -C option with f2c (which checks array bounds -- g77 doesn't have - such an option yet, which is why you have to use f2c), and link - and run the resulting program trying to reproduce the bug. - -If a run-time bug occurs both when your program is compiled with g77 -and when compiled with f2c, that suggests (but does not prove) that -the bug is not in g77, rather that it is either in your own code -(quite likely), in libf2c, in gcc, or elsewhere. Probably 99% of the -time the bug is in your own code, EVEN IN CASES WHERE YOUR OWN CODE -"WORKS" WITH OTHER COMPILERS. Please follow the instructions above -to try and find bugs in your code before submitting bug reports. - -Some causes for run-time problems that might be invisible in the code -when using g77: - -- It is possible that combining code compiled with f2c and with g77 - results in misbehaving programs. This can happen if, for example, - f2c's view of the system configuration, and especially if the - copy of f2c.h used when compiling the output of f2c, don't agree - with g77's configuration and the f2c.h used when compiling its - version of libf2c. - - Another way bugs might happen is if you don't use the same, or a similar - enough, version of gcc to compile f2c's output as is integrated - with the version of g77 you're using. - - The solution is to try compiling all Fortran code in your program - with the exact same compiler configuration. Try using f2c with gcc - exclusively, for example. Then try using g77 exclusively. See - what works and what doesn't, and perhaps that'll help you identify - the source of the problem. - - Note that "Fortran code" includes not only your own Fortran code, - but any libraries you are using that were either written in Fortran - or were designed to interface to some Fortran system. A third- - party Fortran library might not have been compiled with a - version of g77 compatible with the one you're using, for example -- - to fix this, you need to obtain an appropriate version of the library. - -- If you use -fno-f2c when compiling some, but not all, code, there - could easily be run-time errors. If functions returning REAL, - COMPLEX, or DOUBLE COMPLEX are compiled and invoked from different - "sets" of code (where one "set" is compiled with -fno-f2c, and the - other set isn't), there almost certainly will be run-time bugs. - -(If you want to try running gdb on the g77 compiler itself, named f771, -note that the global variables lineno and input_filename usually are -accurate for most kinds of crashes, and the presence of an invocation -of ffestd_exec_end() on the stack indicates that f771 was in the second -pass of processing a program unit instead of the first pass. This might -help you fix the bug or find a temporary workaround -- the fix and the -information should be sent in addition to the bug report.) - -*ADVANTAGES OVER f2c* - -Without f2c, g77 would have taken much longer to do and probably not -been as good for quite a while. Sometimes people who notice how -much g77 depends on, and documents encouragement to use, f2c ask -why g77 was created if f2c already existed. This section gives some -basic answers to these questions, though it is not intended to -be comprehensive. - -Language Extensions -------------------- - -g77 offers several extensions to the Fortran language that f2c -doesn't. - -However, f2c offers a few that g77 doesn't, like INTEGER*2. It -is expected that g77 will offer some or all of these missing -features at some time in the future. - -Compiler Options ----------------- - -g77 offers a whole bunch of compiler options that f2c doesn't. - -However, f2c offers a few that g77 doesn't, like an option to generate -code to check array subscripts at run time. It is expected that -g77 will offer some or all of these missing options at some time -in the future. - -Compiler Speed --------------- - -Saving the steps of writing and then rereading C code is a big reason -why g77 should be able to compile code much faster than using f2c -in conjunction with the equivalent invocation of gcc. - -However, due to g77's youth, lots of self-checking is still being -performed. As a result, this improvement is as yet unrealized -(though the potential seems to be there for quite a big speedup -in the future). It is possible that, as of version 0.5.18, g77 -is noticably faster compiling many Fortran source files than using -f2c in conjunction with gcc. - -Optimization (Program Speed) ----------------------------- - -g77 has the potential to better optimize code than f2c, even when -gcc is used to compile the output of f2c, because f2c must necessarily -translate Fortran into a somewhat lower-level language (C) that cannot -preserve all the information that is potentially useful for optimization, -while g77 can gather, preserve, and transmit that information directly -to the GBE. - -For example, g77 implements ASSIGN and assigned GOTO using direct -assignment of pointers to labels and direct jumps to labels, whereas -f2c maps the assigned labels to integer values and then uses a C -`switch' statement to encode the assigned GOTO statements. - -However, as is typical, theory and reality don't quite match, at least -not in all cases, so it is still the case that f2c|gcc can generate -code that is faster than g77. - -Debugging ---------- - -Because g77 compiles directly to assembler code like gcc, instead -of translating to an intermediate language (C) as does f2c, support -for debugging can be better for g77 than f2c. - -However, although g77 might be somewhat more "native" in terms of -debugging support than f2c+gcc, there still are a lot of things -"not quite right". Many of the important ones should be resolved -in the near future. - -For example, g77 doesn't have to worry about reserved names -like f2c does. Given "FOR = WHILE", f2c must necessarily -translate this to something _other_ than "for = while;" since C reserves -those words. - -However, g77 does still uses things like an extra level of indirection -for ENTRY-laden procedures -- in this case, because the back end doesn't -yet support multiple entry points. - -Another example is that, given - - COMMON A,B - EQUIVALENCE (B,C) - -the g77 user should be able to access the variables directly, by name, -without having to traverse C-like structures and unions, while f2c -is unlikely to ever offer this ability (due to limitations in the -C language). - -However, due to apparent bugs in the back end, g77 currently doesn't -take advantage of this facility at all -- it doesn't emit any debugging -information for COMMON and EQUIVALENCE areas, other than information -on the array of `char' it creates (and, in the case of local EQUIVALENCE, -names) for each such area. - -Yet another example is arrays. g77 represents them to the debugger -using the same "dimensionality" as in the source code, while f2c -must necessarily convert them all to one-dimensional arrays to fit -into the confines of the C language. However, the level of support -offered by debuggers for interactive Fortran-style access to arrays -as compiled by g77 can vary widely; in some cases, it can actually -be an advantage that f2c converts everything to widely supported -C semantics. - -Character And Hollerith Constants ---------------------------------- - -To avoid the extensive hassle that would be needed to avoid this, -f2c uses C character constants to encode character and hollerith -constants. That means a constant like 'HELLO' is translated to -"hello" in C, which further means that an extra null byte is -present at the end of the constant. This null byte is superfluous. - -g77 does not generate such null bytes. This represents significant -savings of resources, such as on systems where /dev/null or -/dev/zero represent bottlenecks in the systems' performance, because -g77 simply asks for fewer zeros from the operating system than f2c. - -*DISAPPOINTMENTS AND MISUNDERSTANDINGS* - -(Make sure you've read the same-titled section in the gcc docs first!) - -- g77 does not allow REAL and other weird types for arguments to - intrinsics like AND, OR, and SHIFT. - -- g77 rejects some particularly nonportable, silent data-type conversions - such as LOGICAL to REAL (as in "A=.FALSE." where A is REAL) that other - compilers might quietly accept. Some such conversions are accepted - when various forms of the -fugly option are specified, however. - -- g77 defaults to specially processing backslashes (\) in character and - hollerith constants a la the C language. Despite not being within the - spirit (though emphatically within the letter) of the ANSI FORTRAN 77 - standard, g77 defaults to this because that is what f77 defaults to, and - apparently lots of code depends on this feature. You can always specify - -fno-backslash to turn off this processing. Because of this, and because - of other limitations g77 currently has (like not accepting - "PARAMETER (C=CHAR(7))"), the g77 default will remain -fbackslash, and - as the expectation of ongoing compatibility is likely to increase, this - is likely to never change (unless popular competing implementations - of UNIX `f77' commands change their defaults first). - -- g77 rejects things other compilers accept, like "INTRINSIC SIN,SIN". - As time permits in the future, some of these things that are easy for - humans to read and write and unlikely to be intended to mean something - else will be accepted by g77 (unless -fpedantic is specified). In the - meantime, you might as well fix your code to be more standard-conforming - and portable. - -- g77 disallows IMPLICIT CHARACTER*(*). This is not standard-conforming, - and there are some very good reasons for that. When I next remember - any, I'll try to write them down. - -- g77 doesn't accept "PARAMETER I=1". Supporting this obsolete form of - the PARAMETER statement would not be particularly hard, as most of the - parsing code is already in place and working. Until time/money is - spent implementing it, you might as well fix your code to use the - standard form, "PARAMETER (I=1)" (possibly needing "INTEGER I" preceding - the PARAMETER statement as well). - -- g77 doesn't support pointers or allocatable objects. This stuff - is probably considered just behind INTEGER*2 on the list of large, - important things to add to g77. - -- g77 doesn't support the I/O statements TYPE and ACCEPT. These are - common extensions that should be easy to support, but also are fairly - easy to work around in user code. - -- g77 doesn't support STRUCTURE, UNION, RECORD, MAP. This set of extensions - is quite a bit lower on the list of large, important things to add to g77, - and in particular requires a great deal of work either upgrading or - replacing libf2c. - -- g77 doesn't support various OPEN, CLOSE, and INQUIRE keywords such - as "DISP='DELETE'". These extensions are easy to add to g77 itself - but require work upgrading or replacing libf2c. - -- g77 doesn't allow a COMMON block and an external procedure or BLOCK DATA - to have the same name. Some systems allow this, but g77 does not, - to be compatible with f2c. g77 could special-case the way it handles - BLOCK DATA, since it is not compatible with f2c in this particular - area (necessarily, since g77 offers an important feature here), but - it is likely that such special-casing would be very annoying to people - with programs that use "EXTERNAL FOO", with no other mention of FOO - in the same program unit, to refer to external procedures, since the - result would be that g77 would treat these references as requests to - force-load BLOCK DATA program units. In that case, if g77 modified - names of BLOCK DATA so they could have the same names as COMMON, users - would find that their programs wouldn't link because the FOO procedure - didn't have its name translated the same way. (Strictly speaking, - g77 could emit a null-but-externally-satisfying definition of FOO - with its name transformed as if it had been a BLOCK DATA, but that - probably invites more trouble than it's worth.) - -- g77 doesn't allow, e.g., "CALL IFIX". g77 knows about intrinsic - subroutines, not just functions, and is able to support both having - the same names, for example. As a result of this, g77 rejects calls - to intrinsics that are not subroutines, and function invocations - of intrinsics that are not functions, just as it (and most compilers) - rejects invocations of intrinsics with the wrong number (or types) - of arguments. Use "EXTERNAL IFIX" to call a user-written IFIX - subroutine. - -- g77 doesn't allow intrinsics in PARAMETER statements. See gcc/f/PROJECTS. - This is a feature I consider to be absolutely vital, even though it - is not standard-conforming. - -- g77 doesn't allow non-integral exponentiation in PARAMETER statements, - such as "PARAMETER (R=2**.25)". It is unlikely g77 will ever support - this feature, as doing it properly requires complete emulation of - a target computer's floating-point facilities when building g77 - as a cross-compiler. But if the gcc back end is enhanced to provide - such a facility, g77 will likely follow suit by adding this feature. - -- g77 doesn't support "FORMAT(I<J>)" and the like. See the answer for - not supporting STRUCTURE, UNION, RECORD, and MAP. - -*OPEN QUESTIONS* - -Please consider offering useful answers to these! - -- g77 treats constants like Z'ABCD' and 'ABCD'Z as typeless. It seems - like maybe the prefix-letter form, Z'ABCD', should be INTEGER - instead. Perhaps this will be changed for 0.6. - -- LOC() and other intrinsics are probably somewhat misclassified. Is - the a need for more precise classification of intrinsics, and if so, - what are the appropriate groupings? Is there a need to individually - enable/disable/delete/hide intrinsics from the command line? - -*INTERFACING, DEBUGGING, ETC.* - -GNU Fortran currently generates code that is object-compatible with -the f2c converter. Also, it avoids limitations in the current GNU -Back End (GBE), such as the inability to generate a procedure with -multiple entry points, by generating code that is structured -differently (in terms of procedure names, scopes, arguments, and -so on) than might be expected. - -As a result, writing code in other languages that calls on, is -called by, or shares in-memory data with g77-compiled code generally -requires some understanding of the way g77 compiles code for -various constructs. Similarly, using a debugger to debug g77-compiled -code, even if that debugger supports native Fortran debugging, generally -requires this sort of information. - -This section describes some of the basic information on how -g77 compiles code for constructs involving interfaces to other -languages and to debuggers. - -NOTE: Much or all of this information pertains to only the current -release of g77, sometimes even to using certain compiler options -with g77 (such as -fno-f2c). Do not write code that depends on this -information without clearly marking said code as nonportable and -subject to review for every new release of g77. This information -is provided primarily to make debugging of code generated by this -particular release of g77 easier for the user, and partly to make -writing (generally nonportable) interface code easier. Both of these -activities require tracking changes in new version of g77 as they -are installed, because new versions can change the behaviors -described in this section. - -Names ------ - -Fortran permits each implementation to decide how to represent -names as far as how they're seen in other contexts, such as debuggers -and when interfacing to other languages, and especially as far -as how casing is handled. - -External names -- names of entities that are public, i.e. accessible -to all modules in a program -- normally have an underscore (_) -appended by g77, to generate code that is compatible with f2c. -External names include names of Fortran things like common blocks, -external procedures (subroutines and functions, but not including -statement functions, which are internal procedures), and entry point -names. However, use of the -fno-underscoring command-line option -disables this kind of transformation of external names (though inhibiting -the transformation certainly improves the chances of colliding with -incompatible externals written in other languages -- but that -might be intentional). - -When -funderscoring is in force, any name (external or local) that already -has at least one underscore in it is implemented by g77 by appending two -underscores. External names are changed this way for f2c compatibility. -Local names are changed this way to avoid collisions with external names -that are different in the source code -- f2c does the same thing, but -there's no compatibility issue there except for user expectations while -debugging. - -Therefore, given - - Max_Cost = 0 - -a user would, in the debugger, refer to this variable using the -name `max_cost__' (or `MAX_COST__' or `Max_Cost__', as described -below). (We hope to improve g77 in this regard in the future -- -don't write scripts depending on this behavior! Also, consider -experimenting with the `-fno-underscoring' option to try out -debugging without having to massage names by hand like this.) - -g77 provides a number of command-line options that allow the user -to control how case mapping is handled for source files. The default -is the traditional UNIX model -- names are mapped to lower case. -Other command-line options can be specified to map names to upper -case, or to leave them exactly as written in the source file. - -For example, given the statement - - Foo = 3.14159 - -it is normally the case that the variable assigned will be named -`foo'. This would be the name to enter when using a debugger to -access the variable, for example. - -However, depending on the command-line options specified, the -name implemented by g77 might instead be `FOO' or even `Foo', -thus affecting how debugging is done. - -Also, - - Call Foo - -would normally call a procedure that, if it were in a separate C program, -be defined starting with the line: - - void foo_() - -However, g77 command-line options could be used to change the casing -of names, resulting in the name `FOO_' or `Foo_' being given to the -procedure instead of `foo_', and the -fno-underscoring option could be used -to inhibit the appending of the underscore to the name. - -Main Program Unit (The PROGRAM Statement) ------------------------------------------ - -When g77 compiles a main program unit, it gives it the public -procedure name `MAIN__'. The libf2c library has the actual -`main()' procedure as is typical of C-based environments, and -it is this procedure that performs some initial start-up -activity and then calls MAIN__. - -Generally, g77 and libf2c are designed so that you need not -include a main program unit written in Fortran in your program -- -it can be written in C or some other language. Especially for -I/O handling, this is the case, although g77-0.5.16 includes -a bug fix for libf2c that solved a problem with using the -OPEN statement as the first Fortran I/O activity in a program -without a Fortran main program unit. - -However, if you don't intend to use g77 (or f2c) to compile your -main program unit -- that is, if you intend to compile a `main()' -procedure using some other language -- you should carefully -examine the code for main() in libf2c, found in the source -file gcc/f/runtime/libF77/main.c, to see what kinds of things -might need to be done by your main() in order to provide the -Fortran environment your Fortran code is expecting. - -For example, libf2c's main() sets up the information used by -the IARGC() and GETARG() intrinsics. Bypassing libf2c's main() -without providing a substitute for this activity would mean -that invoking IARGC() and GETARG() would produce undefined -results. - -When debugging, one implication of the fact that main(), which -is the place where the debugged program "starts" from the -debugger's point of view, is in libf2c is that you won't be -starting your Fortran program at a point you recognize as your -Fortran code. - -The standard way to get around this problem is to set a break -point (a one-time, or temporary, break point will do) at -the entrance to MAIN__, and then run the program. - -After doing this, the debugger will see the current execution -point of the program as at the beginning of the main program -unit of your program. - -Of course, if you really want to set a break point at some -other place in your program and just start the program -running, without first breaking at MAIN__, that should work fine. - -Arrays (The DIMENSION Statement) --------------------------------- - -Fortran uses "column-major ordering" in its arrays. This differs -from other languages, such as C, which use "row-major ordering". -The difference is that, with Fortran, array elements ajacent to -each other in memory differ in the _first_ subscript instead of -the last; A(5,10,20) immediately follows A(4,10,20), whereas with -row-major ordering it would follow A(5,10,19). This consideration -affects not only interfacing with and debugging Fortran code, -it can greatly affect how code is designed and written, especially -when code speed and size is a concern. - -Fortran also differs from C, a popular language for interfacing and -to support directly in debuggers, in the way arrays are treated. -In C, arrays are single-dimensional and have interesting relationships -to pointers, neither of which is true for Fortran. As a result, -dealing with Fortran arrays from within an environment limited to -C concepts can be challenging. - -For example, accessing the array element A(5,10,20) is easy enough -in Fortran (use `A(5,10,20)'), but in C some difficult machinations -are needed. First, C would treat the A array as a single-dimension -array. Second, C does not understand low bounds for arrays as -does Fortran. Third, C assumes a low bound of zero (0), while Fortran -defaults to a low bound of one (1). Therefore, calculations must be done -to determine what the C equivalent of A(5,10,20) would be, and these -calculations require knowing the dimensions of A. - -For DIMENSION A(2:11,21,0:29), the calculation of the offset of -A(5,10,20) would be: - - (5-2) - + (10-1)*(11-2+1) - + (20-0)*(11-2+1)*(21-1+1) - = 4293 - -So the C equivalent in this case would be a[4293]. - -When using a debugger directly on Fortran code, the C equivalent -might not work, because some debuggers cannot understand the notion -of low bounds other than zero. However, unlike f2c, g77 does -inform the GBE that a multi-dimensional array (like A in the above -example) is really multi-dimensional, rather than a single- -dimensional array, so at least the dimensionality of the array -is preserved. - -Debuggers that understand Fortran should have no trouble with -non-zero low bounds, but for non-Fortran debuggers, especially -C debuggers, the above example might have a C equivalent of -a[4305]. This calculation is arrived at by eliminating the subtraction -of the lower bound in the first parenthesized expression on each -line -- that is, for (5-2) substitute (5), for (10-1) substitute -(10), and for (20-0) substitute (20). Actually, the implication of -this can be that the expression `*(&a[2][1][0] + 4293)' works fine, but -that `a[20][10][5]' produces the equivalent of `*(&a[0][0][0] + 4305)' -because of the missing lower bounds. Come to think of it, perhaps -the behavior is due to the debugger internally compensating for -the lower bounds by offsetting the base address of a, leaving -`&a' set lower, in this case, than `&a[2][1][0]' (the address of -its first element as identified by subscripts equal to the -corresponding lower bounds). - -You know, maybe nobody really needs to use arrays. - -Procedures (The SUBROUTINE, FUNCTION, and ENTRY Statements) ------------------------------------------------------------ - -Procedures that accept CHARACTER arguments are implemented by -g77 so that each CHARACTER argument has two actual arguments. -The first argument occupies the expected position in the -argument list and has the user-specified name. This argument -is a pointer to an array of characters, passed by the caller. -The second argument is appended to the end of the user-specified -calling sequence and is named `__g77_length_X', where X is -the user-specified name. This argument is of the C type `ftnlen' -(see gcc/f/runtime/f2c.h.in for information on that type) and -is the number of characters the caller has allocated in the -array pointed to by the first argument. (A procedure will -ignore the `__g77_length_X' argument if X is not declared -CHARACTER*(*), because for other declarations, it knows the -length. Not all callers necessarily know this, however, which -is why they all pass the extra argument.) - -The contents of the CHARACTER argument are specified by the -address passed in the first argument (named after it). The -procedure can read or write these contents as appropriate. - -When more than one CHARACTER argument is present in the argument -list, the `__g77_length_X' arguments are appended in the order -they appear. So "CALL FOO('HI','THERE')" is implemented in -C as `foo("hi","there",2,5);', ignoring the fact that g77 -does not provide the trailing null bytes on the constant -strings (f2c does provide them, but they are unnecessary in -a Fortran environment, and you should not expect them to be -there). - -Note that this discussion applies to CHARACTER variables and -arrays _only_. It does _not_ apply to external CHARACTER -functions or to intrinsic CHARACTER functions. That is, no -second `__g77_length_X' argument is passed to FOO in this case: - - CHARACTER X - EXTERNAL X - CALL FOO(X) - -Nor does FOO expect such an argument in this case: - - SUBROUTINE FOO(X) - CHARACTER X - EXTERNAL X - -Because of this implementation detail, if a program has a bug -such that there is disagreement as to whether an argument is -a procedure, and the type of the argument is CHARACTER, subtle -symptoms might appear. - -Adjustable Arrays (The DIMENSION Statement) -------------------------------------------- - -Adjustable and automatic arrays in Fortran require the implementation -(in this case, the g77 compiler) to "memorize" the expressions that -dimension the arrays each time the procedure is invoked. -This is so that subsequent changes to variables used in those -expressions, made during execution of the procedure, do not -have any effect on the dimensions of those arrays. - -For example, given - - REAL ARRAY(5) - DATA ARRAY/5*2/ - CALL X(ARRAY,5) - END - SUBROUTINE X(A,N) - DIMENSION A(N) - N = 20 - PRINT *,N,A - END - -the implementation should, when running the program, print something -like: - - 20 2. 2. 2. 2. 2. - -Note that this shows that while the value of N was successfully -changed, the size of the A array remained at 5 elements. - -To support this, g77 generates code that executes before any user -code (and before the internally generated computed GOTO to handle -alternate entry points, as described below) that evaluates each -(nonconstant) expression in the list of subscripts for an -array, and saves the result of each such evaluation to be used when -determining the size of the array (instead of re-evaluating the -expressions). - -So, in the above example, when X is first invoked, code is -executed that copies the value of N to a temporary. And that -same temporary serves as the actual high bound for the single -dimension of the A array (the low bound being the constant 1). -Since the user program cannot (legitimately) change the value -of the temporary during execution of the procedure, the size -of the array remains constant during each invocation. - -For alternate entry points, the code g77 generates takes into -account the possibility that the adjustable array is not actually -passed to the actual entry point being invoked at that time. -In that case, the public procedure implementing the entry point -passes to the master private procedure implementing all the -code for the entry points a NULL pointer where a pointer to that -adjustable array would be expected. The g77-generated code -doesn't attempt to evaluate any of the expressions in the subscripts -for an array if the pointer to that array is NULL at run time in -such cases. (Don't depend on this particular implementation -by writing code that purposely passes NULL pointers where the -callee expects adjustable arrays, even if you know the callee -won't reference the arrays -- nor should you pass NULL pointers -for any dummy arguments used in calculating the bounds of such -arrays or leave undefined any values used for that purpose in -COMMON -- because the way g77 implements these things might -change in the future!) - -Subroutines (The SUBROUTINE and ENTRY Statements) -------------------------------------------------- - -Subroutines with alternate returns (e.g. "SUBROUTINE X(*)" and -"CALL X(*50)") are implemented by g77 as functions returning -the C `int' type. The actual alternate-return arguments are -omitted from the calling sequence. Instead, the caller uses -the return value to do a rough equivalent of the Fortran -computed-GOTO statement, as in "GOTO (50), X()" in the -example above (where X is quietly declared as an INTEGER -function), and the callee just returns whatever integer -is specified in the RETURN statement for the subroutine -(e.g. "RETURN 1" is implemented as "X = 1" followed by "RETURN" -in C, and "RETURN" by itself is "X = 0" and "RETURN"). - -Functions (The FUNCTION and ENTRY Statements) ---------------------------------------------- - -g77 handles in a special way functions that return the following -types: - -- CHARACTER -- COMPLEX (and DOUBLE COMPLEX) -- REAL - -For CHARACTER, g77 implements a subroutine (a C function returning `void') -with two arguments prepended: `__g77_result', which the caller passes -as a pointer to a `char' array expected to hold the return value, -and `__g77_length', which the caller passes as an `ftnlen' value -specifying the length of the return value as declared in the calling -program. For CHARACTER*(*), the called function uses `__g77_length' -to determine the size of the array that `__g77_result' points to; -otherwise, it ignores that argument. - -For COMPLEX and DOUBLE COMPLEX, when -ff2c is in force, g77 implements -a subroutine with one argument prepended: `__g77_result', which the -caller passes as a pointer to a variable of the type of the function. -The called function writes the return value into this variable instead -of returning it as a function value. When -fno-f2c is in force, -g77 implements gcc's `__complex__ float /* or double */' function, -returning the result of the function in the same way as gcc would. - -For REAL, when -ff2c is in force, g77 implements a function that actually -returns DOUBLE PRECISION (usually C's `double' type). When -fno-f2c -is in force, REAL functions return `float'. - -Common Blocks (The COMMON Statement) ------------------------------------- - -g77 names and lays out COMMON areas the same way f2c does, -for compatibility with f2c. - -Currently, g77 does not emit any debugging information for -items in a COMMON area, due to an apparent bug in the GBE. - -Moreover, g77 will implement a COMMON area such that its -type will be an array of the C `char' data type. - -So, when debugging, you must know the offset into a COMMON area -for a particular item in that area, and you have to take into -account the appropriate multiplier for the respective sizes -of the types (as declared in your code) for the items preceding -the item in question as compared to the size of the `char' type. - -For example, using default implicit typing, the statement - - COMMON I(15),R(20),T - -will result in a public 144-byte `char' array named `_BLNK__' -with I placed at _BLNK__[0], R at _BLNK__[60], and T at -_BLNK__[140]. (This is assuming that the target machine for -the compilation has 4-byte INTEGER and REAL types.) - -Local Equivalence Areas (The EQUIVALENCE Statement) ---------------------------------------------------- - -g77 treats equivalence areas involving a COMMON block as explained -in the section on common blocks. - -A local EQUIVALENCE area is a collection of variables and arrays -connected to each other in any way via EQUIVALENCE, none of which are -listed in a COMMON statement. - -Currently, g77 does not emit any debugging information for -items in a local EQUIVALENCE area, due to an apparent bug in the GBE. - -Moreover, g77 will implement a local EQUIVALENCE area such that its -type will be an array of the C `char' data type. - -The name g77 gives this array of `char' type is `__g77_equiv_X', -where X is the name of the first item listed in the EQUIVALENCE -statements for that area that is placed at the beginning (offset 0) -of this array. - -When debugging, you must therefore access members of EQUIVALENCE -areas by specifying the appropriate __g77_equiv_X array section with -the appropriate offset. See the explanation of debugging COMMON blocks -for info applicable to debugging local EQUIVALENCE areas. - -(NOTE: g77 version 0.5.16 fixed a bug in how certain EQUIVALENCE cases -were handled. The bug caused the debugger to not know the size of the -array if any variable or array in the EQUIVALENCE was given an initial -value via DATA or similar.) - -Alternate Entry Points (The ENTRY Statement) --------------------------------------------- - -The GNU Back End (GBE) does not understand the general concept of -alternate entry points as Fortran provides via the ENTRY statement. -g77 gets around this by using an approach to compiling procedures -having at least one ENTRY statement that is almost identical to the -approach used by f2c. (An alternate approach could be used that -would probably generate faster, but larger, code that would also -be a bit easier to debug.) - -Information on how g77 implements ENTRY is provided for those -trying to debug such code. The choice of implementation seems -unlikely to affect code (compiled in other languages) that interfaces -to such code. - -g77 compiles exactly one public procedure for the primary entry -point of a procedure plus each ENTRY point it specifies, as usual. -That is, in terms of the public interface, there is no difference -between - - SUBROUTINE X - END - SUBROUTINE Y - END - -and: - - SUBROUTINE X - ENTRY Y - END - -The difference between the above two cases lies in the code compiled -for the X and Y procedures themselves, plus the fact that for the -second case an extra internal procedure is compiled. - -For every Fortran procedure with at least one ENTRY statement, g77 -compiles an extra procedure named `__g77_masterfun_X', where X is -the name of the primary entry point (which, in the above case, -using the standard compiler options, would be `x'). - -This extra procedure is compiled as a private procedure -- that is, -a procedure not accessible by name to separately compiled modules. -It contains all the code in the program unit, including the code -for the primary entry point plus for every entry point. (The code -for each public procedure is quite short, and explained later.) - -The extra procedure has some other interesting characteristics. - -The argument list for this procedure is invented by g77. It contains -a single integer argument named `__g77_which_entrypoint', -passed by value (as in Fortran's %VAL() intrinsic), specifying the -entry point index -- 0 for the primary entry point, 1 for the -first entry point (the first ENTRY statement encountered), 2 for -the second entry point, and so on. - -It also contains, for functions returning CHARACTER and (when -ff2c -is in effect) COMPLEX functions, and for functions returning -different types among the ENTRY statements (e.g. REAL FUNCTION R() -containing ENTRY I()), an argument named `__g77_result' that -is expected at run time to contain a pointer to where to store -the result of the entry point. For CHARACTER functions, this -storage area is an array of the appropriate number of characters; -for COMPLEX functions, it is the appropriate area for the return -type (currently either COMPLEX or DOUBLE COMPLEX); for multiple- -return-type functions, it is a union of all the supported return -types (which cannot include CHARACTER, since combining CHARACTER -and non-character return types via ENTRY in a single function -is not supported by g77). - -For CHARACTER functions, the `__g77_result' argument is followed -by yet another argument named `__g77_length' that, at run time, -specifies the caller's expected length of the returned value. -Note that only CHARACTER*(*) functions and entry points actually -make use of this argument, even though it is always passed by -all callers of public CHARACTER functions (since the caller does not -generally know whether such a function is CHARACTER*(*) or whether -there are any other callers that don't have that information). - -The rest of the argument list is the union of all the arguments -specified for all the entry points (in their usual forms, e.g. -CHARACTER arguments have extra length arguments, all appended at -the end of this list). This is considered the "master list" of -arguments. - -The code for this procedure has, before the code for the first -executable statement, code much like that for the following Fortran -statement: - - GOTO (100000,100001,100002), __g77_which_entrypoint -100000 ...code for primary entry point... -100001 ...code immediately following first ENTRY statement... -100002 ...code immediately following second ENTRY statement... - -(Note that invalid Fortran statement labels and variable names -are used in the above example to highlight the fact that it -represents code generated by the g77 internals, not code to be -written by the user.) - -It is this code that, when the procedure is called, picks which -entry point to start executing. - -Getting back to the public procedures (X and Y in the original -example), those procedures are fairly simple. Their interfaces -are just like they would be if they were self-contained procedures -(without ENTRY), of course, since that is what the callers -expect. Their code consists of simply calling the private -procedure, described above, with the appropriate extra arguments -(the entry point index, and perhaps a pointer to a multiple-type- -return variable, local to the public procedure, that contains -all the supported returnable non-character types). For arguments -that are not listed for a given entry point that are listed for -other entry points, and therefore that are in the "master list" -for the private procedure, null pointers (in C, the NULL macro) -are passed. Also, for entry points that are part of a multiple-type- -returning function, code is compiled after the call of the private -procedure to extract from the multi-type union the appropriate result, -depending on the type of the entry point in question, returning -that result to the original caller. - -When debugging a procedure containing alternate entry points, you -can either set a break point on the public procedure itself (e.g. -a break point on X or Y) or on the private procedure that -contains most of the pertinent code (e.g. __g77_masterfun_x). -If you do the former, you should use the debugger's command to -"step into" the called procedure to get to the actual code; with -the latter approach, the break point leaves you right at the -actual code, skipping over the public entry point and its call -to the private procedure (unless you have set a break point there -as well, of course). - -Further, the list of dummy arguments that is visible when the -private procedure is active is going to be the expanded version -of the list for whichever particular entry point is active, -as explained above, and the way in which return values are -handled might well be different from how they would be handled -for an equivalent single-entry FUNCTION. - -Assigned Statement Labels (The ASSIGN and GOTO Statements) ----------------------------------------------------------- - -For portability to machines where a pointer (such as to a label, -which is how g77 implements ASSIGN and its cousin, the assigned -GOTO) is wider (bitwise) than an INTEGER, g77 does not necessarily -use the same memory location to hold the ASSIGNed value of an -variable as it does the numerical value in that variable unless the -variable is wide enough (can hold enough bits). - -In particular, while g77 will implement - - I = 10 - -as, in C notation, "i = 10;", it might implement - - ASSIGN 10 TO I - -as, in GNU's extended C notation (for the label syntax), -"__g77_ASSIGN_I = &&L10;" (where L10 is just a massaging -of the Fortran label 10 to make the syntax C-like; g77 doesn't -actually generate the name "L10" or any other name like that, -since debuggers cannot access labels anyway). - -While this currently means that an ASSIGN statement might not -overwrite the numeric contents of its target variable, _do not_ -write any code depending on this feature. g77 has already -changed this implementation across versions and might do so -in the future. This information is provided only to make debugging -Fortran programs compiled with the current version of g77 somewhat -easier. If there's no debugger-visible variable named "__g77_ASSIGN_I" -in a program unit that does "ASSIGN 10 TO I", then g77 has decided -it can store the pointer to the label directly into "I" itself. - -(Currently g77 always chooses to make the separate variable, to -improve the likelihood that `-O -Wuninitialized' will diagnose -failures to do things like "GOTO I" without "ASSIGN 10 TO I" -despite doing "I=5".) diff --git a/gnu/usr.bin/gcc/f/INSTALL b/gnu/usr.bin/gcc/f/INSTALL index 01fefceae0d..e95420a101f 100644 --- a/gnu/usr.bin/gcc/f/INSTALL +++ b/gnu/usr.bin/gcc/f/INSTALL @@ -38,20 +38,20 @@ follow the `g77' installation instructions: available--in fact, a complete GNU UNIX system can be put together on most systems, if desired. -`gcc-2.7.2.tar.gz' +`gcc-2.7.2.2.tar.gz' You need to have this, or some other applicable, version of `gcc' on your system. The version should be an exact copy of a distribution from the FSF. It is approximately 7MB large. - If you've already unpacked `gcc-2.7.2.tar.gz' into a directory - (named `gcc-2.7.2') called the "source tree" for `gcc', you can + If you've already unpacked `gcc-2.7.2.2.tar.gz' into a directory + (named `gcc-2.7.2.2') called the "source tree" for `gcc', you can delete the distribution itself, but you'll need to remember to skip any instructions to unpack this distribution. Without an applicable `gcc' source tree, you cannot build `g77'. You can obtain an FSF distribution of `gcc' from the FSF. -`g77-0.5.19.tar.gz' +`g77-0.5.20.tar.gz' You probably have already unpacked this distribution, or you are reading an advanced copy of this manual, which is contained in this distribution. This distribution approximately 1MB large. @@ -142,61 +142,90 @@ information on installation problems that can afflict either `gcc' or General Problems ---------------- - * On SunOS systems, linking the `f771' program produces an error - message concerning an undefined symbol named `_strtoul'. - - This is not a `g77' bug. *Note Patching GNU Fortran::, for - information on a workaround provided by `g77'. - - The proper fix is either to upgrade your system to one that - provides a complete ANSI C environment, or improve `gcc' so that - it provides one for all the languages and configurations it - supports. - - *Note:* In earlier versions of `g77', an automated workaround for - this problem was attempted. It worked for systems without - `_strtoul', substituting the incomplete-yet-sufficient version - supplied with `g77' for those systems. However, the automated - workaround failed mysteriously for systems that appeared to have - conforming ANSI C environments, and it was decided that, lacking - resources to more fully investigate the problem, it was better to - not punish users of those systems either by requiring them to work - around the problem by hand or by always substituting an incomplete - `strtoul()' implementation when their systems had a complete, - working one. Unfortunately, this meant inconveniencing users of - systems not having `strtoul()', but they're using obsolete (and - generally unsupported) systems anyway. - - * It'd be helpful if `g77''s `Makefile.in' or `Make-lang.in' would - create the various `stageN' directories and their subdirectories, - so expert installers wouldn't have to reconfigure after cleaning - up. + These problems can occur on most or all systems. - * Improvements to the way `libf2c' is built could make building - `g77' as a cross-compiler easier--for example, passing and using - `LD' and `AR' in the appropriate ways. - - * `g77' currently requires application of a patch file to the gcc - compiler tree. The necessary patches should be folded in to the - mainline gcc distribution. - - Some combinations of versions of `g77' and `gcc' might actually - *require* no patches, but the patch files will be provided anyway - as long as there are more changes expected in subsequent releases. - These patch files might contain unnecessary, but possibly helpful, - patches. As a result, it is possible this issue might never be - resolved, except by eliminating the need for the person - configuring `g77' to apply a patch by hand, by going to a more - automated approach (such as configure-time patching). +GNU C Required +.............. - * It should be possible to build the runtime without building `cc1' - and other non-Fortran items, but, for now, an easy way to do that - is not yet established. + Compiling `g77' requires GNU C, not just ANSI C. Fixing this +wouldn't be very hard (just tedious), but the code using GNU extensions +to the C language is expected to be rewritten for 0.6 anyway, so there +are no plans for an interim fix. + + This requirement does not mean you must already have `gcc' installed +to build `g77'. As long as you have a working C compiler, you can use a +bootstrap build to automate the process of first building `gcc' using +the working C compiler you have, then building `g77' and rebuilding +`gcc' using that just-built `gcc', and so on. + +Patching GNU CC Necessary +......................... + + `g77' currently requires application of a patch file to the gcc +compiler tree. The necessary patches should be folded in to the +mainline gcc distribution. + + Some combinations of versions of `g77' and `gcc' might actually +*require* no patches, but the patch files will be provided anyway as +long as there are more changes expected in subsequent releases. These +patch files might contain unnecessary, but possibly helpful, patches. +As a result, it is possible this issue might never be resolved, except +by eliminating the need for the person configuring `g77' to apply a +patch by hand, by going to a more automated approach (such as +configure-time patching). + +Building GNU CC Necessary +......................... + + It should be possible to build the runtime without building `cc1' +and other non-Fortran items, but, for now, an easy way to do that is +not yet established. + +Missing strtoul +............... - * Compiling `g77' requires GNU C, not just ANSI C. Fixing this - wouldn't be very hard (just tedious), but the code using GNU - extensions to the C language is expected to be rewritten for 0.6 - anyway, so there are no plans for an interim fix. + On SunOS4 systems, linking the `f771' program produces an error +message concerning an undefined symbol named `_strtoul'. + + This is not a `g77' bug. *Note Patching GNU Fortran::, for +information on a workaround provided by `g77'. + + The proper fix is either to upgrade your system to one that provides +a complete ANSI C environment, or improve `gcc' so that it provides one +for all the languages and configurations it supports. + + *Note:* In earlier versions of `g77', an automated workaround for +this problem was attempted. It worked for systems without `_strtoul', +substituting the incomplete-yet-sufficient version supplied with `g77' +for those systems. However, the automated workaround failed +mysteriously for systems that appeared to have conforming ANSI C +environments, and it was decided that, lacking resources to more fully +investigate the problem, it was better to not punish users of those +systems either by requiring them to work around the problem by hand or +by always substituting an incomplete `strtoul()' implementation when +their systems had a complete, working one. Unfortunately, this meant +inconveniencing users of systems not having `strtoul()', but they're +using obsolete (and generally unsupported) systems anyway. + +Object File Differences +....................... + + A comparison of object files after building Stage 3 during a +bootstrap build will result in `gcc/f/zzz.o' being flagged as different +from the Stage 2 version. That is because it contains a string with an +expansion of the `__TIME__' macro, which expands to the current time of +day. It is nothing to worry about, since `gcc/f/zzz.c' doesn't contain +any actual code. It does allow you to override its use of `__DATE__' +and `__TIME__' by defining macros for the compilation--see the source +code for details. + +Cleanup Kills Stage Directories +............................... + + It'd be helpful if `g77''s `Makefile.in' or `Make-lang.in' would +create the various `stageN' directories and their subdirectories, so +developers and expert installers wouldn't have to reconfigure after +cleaning up. Cross-compiler Problems ----------------------- @@ -232,12 +261,178 @@ reasons. combinations of machines. For example, it might not know how to handle floating-point constants. + * Improvements to the way `libf2c' is built could make building + `g77' as a cross-compiler easier--for example, passing and using + `LD' and `AR' in the appropriate ways. + * There are still some challenges putting together the right run-time libraries (needed by `libf2c') for a target system, depending on the systems involved in the configuration. (This is a general problem with cross-compilation, and with `gcc' in particular.) +Changing Settings Before Building +================================= + + Here are some internal `g77' settings that can be changed by editing +source files in `gcc/f/' before building. + + This information, and perhaps even these settings, represent +stop-gap solutions to problems people doing various ports of `g77' have +encountered. As such, none of the following information is expected to +be pertinent in future versions of `g77'. + +Larger File Unit Numbers +------------------------ + + As distributed, whether as part of `f2c' or `g77', `libf2c' accepts +file unit numbers only in the range 0 through 99. For example, a +statement such as `WRITE (UNIT=100)' causes a run-time crash in +`libf2c', because the unit number, 100, is out of range. + + If you know that Fortran programs at your installation require the +use of unit numbers higher than 99, you can change the value of the +`MXUNIT' macro, which represents the maximum unit number, to an +appropriately higher value. + + To do this, edit the file `f/runtime/libI77/fio.h' in your `g77' +source tree, changing the following line: + + #define MXUNIT 100 + + Change the line so that the value of `MXUNIT' is defined to be at +least one *greater* than the maximum unit number used by the Fortran +programs on your system. + + (For example, a program that does `WRITE (UNIT=255)' would require +`MXUNIT' set to at least 256 to avoid crashing.) + + Then build or rebuild `g77' as appropriate. + + *Note:* Changing this macro has *no* effect on other limits your +system might place on the number of files open at the same time. That +is, the macro might allow a program to do `WRITE (UNIT=100)', but the +library and operating system underlying `libf2c' might disallow it if +many other files have already been opened (via `OPEN' or implicitly via +`READ', `WRITE', and so on). Information on how to increase these +other limits should be found in your system's documentation. + +Always Flush Output +------------------- + + Some Fortran programs require output (writes) to be flushed to the +operating system (under UNIX, via the `fflush()' library call) so that +errors, such as disk full, are immediately flagged via the relevant +`ERR=' and `IOSTAT=' mechanism, instead of such errors being flagged +later as subsequent writes occur, forcing the previously written data +to disk, or when the file is closed. + + Essentially, the difference can be viewed as synchronous error +reporting (immediate flagging of errors during writes) versus +asynchronous, or, more precisely, buffered error reporting (detection +of errors might be delayed). + + `libf2c' supports flagging write errors immediately when it is built +with the `ALWAYS_FLUSH' macro defined. This results in a `libf2c' that +runs slower, sometimes quite a bit slower, under certain +circumstances--for example, accessing files via the networked file +system NFS--but the effect can be more reliable, robust file I/O. + + If you know that Fortran programs requiring this level of precision +of error reporting are to be compiled using the version of `g77' you +are building, you might wish to modify the `g77' source tree so that +the version of `libf2c' is built with the `ALWAYS_FLUSH' macro defined, +enabling this behavior. + + To do this, find this line in `f/runtime/configure.in' in your `g77' +source tree: + + dnl AC_DEFINE(ALWAYS_FLUSH) + + Remove the leading `dnl ', so the line begins with `AC_DEFINE(', and +run `autoconf' in that file's directory. (Or, if you don't have +`autoconf', you can modify `f2c.h.in' in the same directory to include +the line `#define ALWAYS_FLUSH' after `#define F2C_INCLUDE'.) + + Then build or rebuild `g77' as appropriate. + +Maximum Stackable Size +---------------------- + + `g77', on most machines, puts many variables and arrays on the stack +where possible, and can be configured (by changing +`FFECOM_sizeMAXSTACKITEM' in `gcc/f/com.c') to force smaller-sized +entities into static storage (saving on stack space) or permit +larger-sized entities to be put on the stack (which can improve +run-time performance, as it presents more opportunities for the GBE to +optimize the generated code). + + *Note:* Putting more variables and arrays on the stack might cause +problems due to system-dependent limits on stack size. Also, the value +of `FFECOM_sizeMAXSTACKITEM' has no effect on automatic variables and +arrays. *Note But-bugs::, for more information. + +Floating-point Bit Patterns +--------------------------- + + The `g77' build will crash if an attempt is made to build it as a +cross-compiler for a target when `g77' cannot reliably determine the +bit pattern of floating-point constants for the target. Planned +improvements for g77-0.6 will give it the capabilities it needs to not +have to crash the build but rather generate correct code for the target. +(Currently, `g77' would generate bad code under such circumstances if +it didn't crash during the build, e.g. when compiling a source file +that does something like `EQUIVALENCE (I,R)' and `DATA R/9.43578/'.) + +Initialization of Large Aggregate Areas +--------------------------------------- + + A warning message is issued when `g77' sees code that provides +initial values (e.g. via `DATA') to an aggregate area (`COMMON' or +`EQUIVALENCE', or even a large enough array or `CHARACTER' variable) +that is large enough to increase `g77''s compile time by roughly a +factor of 10. + + This size currently is quite small, since `g77' currently has a +known bug requiring too much memory and time to handle such cases. In +`gcc/f/data.c', the macro `FFEDATA_sizeTOO_BIG_INIT_' is defined to the +minimum size for the warning to appear. The size is specified in +storage units, which can be bytes, words, or whatever, on a +case-by-case basis. + + After changing this macro definition, you must (of course) rebuild +and reinstall `g77' for the change to take effect. + + Note that, as of version 0.5.18, improvements have reduced the scope +of the problem for *sparse* initialization of large arrays, especially +those with large, contiguous uninitialized areas. However, the warning +is issued at a point prior to when `g77' knows whether the +initialization is sparse, and delaying the warning could mean it is +produced too late to be helpful. + + Therefore, the macro definition should not be adjusted to reflect +sparse cases. Instead, adjust it to generate the warning when densely +initialized arrays begin to cause responses noticeably slower than +linear performance would suggest. + +Alpha Problems Fixed +-------------------- + + `g77' used to warn when it was used to compile Fortran code for a +target configuration that is not basically a 32-bit machine (such as an +Alpha, which is a 64-bit machine, especially if it has a 64-bit +operating system running on it). That was because `g77' was known to +not work properly on such configurations. + + As of version 0.5.20, `g77' is believed to work well enough on such +systems. So, the warning is no longer needed or provided. + + However, support for 64-bit systems, especially in areas such as +cross-compilation and handling of intrinsics, is still incomplete. The +symptoms are believed to be compile-time diagnostics rather than the +generation of bad code. It is hoped that version 0.6 will completely +support 64-bit systems. + Quick Start =========== @@ -258,16 +453,14 @@ is assumed that the source distributions themselves already reside in `/usr/FSF', a naming convention used by the author of `g77' on his own system: - /usr/FSF/gcc-2.7.2.tar.gz - /usr/FSF/g77-0.5.19.tar.gz + /usr/FSF/gcc-2.7.2.2.tar.gz + /usr/FSF/g77-0.5.20.tar.gz Users of the following systems should not blindly follow these quick-start instructions, because of problems their systems have coping with straightforward installation of `g77': - * SunOS - - * Alpha + * SunOS4 Instead, see *Note Complete Installation::, for detailed information on how to configure, build, and install `g77' for your particular @@ -284,49 +477,49 @@ of some of the steps. These explanations follow this list of steps. sh[ 1]# cd /usr/src - sh[ 2]# gunzip -c < /usr/FSF/gcc-2.7.2.tar.gz | tar xf - - + sh[ 2]# gunzip -c < /usr/FSF/gcc-2.7.2.2.tar.gz | tar xf - [Might say "Broken pipe"...that is normal on some systems.] - sh[ 3]# gunzip -c < /usr/FSF/g77-0.5.19.tar.gz | tar xf - + sh[ 3]# gunzip -c < /usr/FSF/g77-0.5.20.tar.gz | tar xf - ["Broken pipe" again possible.] - sh[ 4]# ln -s gcc-2.7.2 gcc - sh[ 5]# ln -s g77-0.5.19 g77 + sh[ 4]# ln -s gcc-2.7.2.2 gcc - sh[ 6]# mv -i g77/* gcc + sh[ 5]# ln -s g77-0.5.20 g77 + sh[ 6]# mv -i g77/* gcc [No questions should be asked by mv here; or, you made a mistake.] - sh[ 7]# patch -p1 -V t -d gcc-2.7.2 < gcc-2.7.2/f/gbe/2.7.2.diff + sh[ 7]# patch -p1 -V t -d gcc < gcc/f/gbe/2.7.2.2.diff [Unless patch complains about rejected patches, this step worked.] + sh[ 8]# cd gcc sh[ 9]# touch f77-install-ok - [Do not do the above if your system already has an f77 command, unless you've checked that overwriting it is okay.] - sh[10]# touch f2c-install-ok + sh[10]# touch f2c-install-ok [Do not do the above if your system already has an f2c command, unless you've checked that overwriting it is okay. Else, touch f2c-exists-ok.] - sh[11]# ./configure --prefix=/usr + sh[11]# ./configure --prefix=/usr [Do not do the above if gcc is not installed in /usr/bin. You might need a different --prefix=..., as described below.] - sh[12]# make bootstrap + sh[12]# make bootstrap [This takes a long time, and is where most problems occur.] + sh[13]# rm -fr stage1 sh[14]# make -k install - [The actual installation.] - sh[15]# g77 -v + sh[15]# g77 -v [Verify that g77 is installed, obtain version info.] + sh[16]# *Note Updating Your Info Directory: Updating Documentation, for @@ -342,8 +535,16 @@ Step 1: `cd /usr/src' your system knew where to look for the source code for the installed version of `g77' and `gcc' in any case. -Step 4: `ln -s gcc-2.7.2 gcc' -Step 5: `ln -s g77-0.5.19 g77' +Step 3: `gunzip -d < /usr/FSF/g77-0.5.20.tar.gz | tar xf -' + It is not always necessary to obtain the latest version of `g77' + as a complete `.tar.gz' file if you have a complete, earlier + distribution of `g77'. If appropriate, you can unpack that earlier + version of `g77', and then apply the appropriate patches to + achieve the same result--a source tree containing version 0.5.20 + of `g77'. + +Step 4: `ln -s gcc-2.7.2.2 gcc' +Step 5: `ln -s g77-0.5.20 g77' These commands mainly help reduce typing, and help reduce visual clutter in examples in this manual showing what to type to install `g77'. @@ -353,7 +554,7 @@ Step 5: `ln -s g77-0.5.19 g77' Step 6: `mv -i g77/* gcc' After doing this, you can, if you like, type `rm g77' and `rmdir - g77-0.5.19' to remove the empty directory and the symbol link to + g77-0.5.20' to remove the empty directory and the symbol link to it. But, it might be helpful to leave them around as quick reminders of which version(s) of `g77' are installed on your system. @@ -407,7 +608,7 @@ Step 11: `./configure --prefix=/usr' it does not fully replace the existing installation of `gcc' is likely to result in the inability to compile Fortran programs. - *Note Where in the World Does Fortran (and GNU C) Go?: Where to + *Note Where in the World Does Fortran (and GNU CC) Go?: Where to Install, for more information on determining where to install `g77'. *Note Configuring gcc::, for more information on the configuration process triggered by invoking the `./configure' @@ -434,6 +635,46 @@ Step 14: `make -k install' information on entering this manual into your system's list of texinfo manuals. +Step 15: `g77 -v' + If this command prints approximately 25 lines of output, including + the GNU Fortran Front End version number (which should be the same + as the version number for the version of `g77' you just built and + installed) and the version numbers for the three parts of the + `libf2c' library (`libF77', `libI77', `libU77'), and those version + numbers are all in agreement, then there is a high likelihood that + the installation has been successfully completed. + + You might consider doing further testing. For example, log in as + a non-privileged user, then create a small Fortran program, such + as: + + PROGRAM SMTEST + DO 10 I=1, 10 + PRINT *, 'Hello World #', I + 10 CONTINUE + END + + Compile, link, and run the above program, and, assuming you named + the source file `smtest.f', the session should look like this: + + sh# g77 -o smtest smtest.f + sh# ./smtest + Hello World # 1 + Hello World # 2 + Hello World # 3 + Hello World # 4 + Hello World # 5 + Hello World # 6 + Hello World # 7 + Hello World # 8 + Hello World # 9 + Hello World # 10 + sh# + + After proper installation, you don't need to keep your gcc and g77 + source and build directories around anymore. Removing them can + free up a lot of disk space. + Complete Installation ===================== @@ -462,10 +703,10 @@ generally only the documentation is immediately usable. A sequence of commands typically used to unpack `gcc' and `g77' is: sh# cd /usr/src - sh# gunzip -d < /usr/FSF/gcc-2.7.2.tar.gz | tar xf - - sh# gunzip -d < /usr/FSF/g77-0.5.19.tar.gz | tar xf - - sh# ln -s gcc-2.7.2 gcc - sh# ln -s g77-0.5.19 g77 + sh# gunzip -d < /usr/FSF/gcc-2.7.2.2.tar.gz | tar xf - + sh# gunzip -d < /usr/FSF/g77-0.5.20.tar.gz | tar xf - + sh# ln -s gcc-2.7.2.2 gcc + sh# ln -s g77-0.5.20 g77 sh# mv -i g77/* gcc *Notes:* The commands beginning with `gunzip...' might print `Broken @@ -484,7 +725,7 @@ and the top level of just the `g77' source tree (prior to issuing the All three entries should be moved (or copied) into a `gcc' source tree (typically named after its version number and as it appears in the -FSF distributions--e.g. `gcc-2.7.2'). +FSF distributions--e.g. `gcc-2.7.2.2'). `g77/f' is the subdirectory containing all of the code, documentation, and other information that is specific to `g77'. The @@ -529,7 +770,7 @@ fact that there are some differences. version of a distribution is newer or older than some other version of that distribution. The format is, generally, MAJOR.MINOR.PATCH, with each field being a decimal number. (You can safely ignore leading -zeros; for example, 1.5.3 is the same as 1.5.03.) The MAJOR field only +zeros; for example, 1.5.3 is the same as 1.5.03.) The MAJOR field only increases with time. The other two fields are reset to 0 when the field to their left is incremented; otherwise, they, too, only increase with time. So, version 2.6.2 is newer than version 2.5.8, and version @@ -697,21 +938,22 @@ and change the definition of the `F2CLIBOK' macro appropriately. Patching GNU Fortran -------------------- - If you're using a SunOS system, you'll need to make the following + If you're using a SunOS4 system, you'll need to make the following change to `gcc/f/proj.h': edit the line reading #define FFEPROJ_STRTOUL 1 ... by replacing the `1' with `0'. Or, you can avoid editing the source by adding - CFLAGS='-DFFEPROJ_STRTOUL=0 -g' + CFLAGS='-DFFEPROJ_STRTOUL=0 -g -O' to the command line for `make' when you invoke it. (`-g' is the default for `CFLAGS'.) This causes a minimal version of `strtoul()' provided as part of the `g77' distribution to be compiled and linked into whatever `g77' -programs need it, since some systems (like SunOS) do not provide this -function in their system libraries. +programs need it, since some systems (like SunOS4 with only the bundled +compiler and its runtime) do not provide this function in their system +libraries. Similarly, a minimal version of `bsearch()' is available and can be enabled by editing a line similar to the one for `strtoul()' above in @@ -727,8 +969,8 @@ provide one to all `gcc'-based compilers in future `gcc' distributions. comes up missing and on approaches to dealing with this problem that have already been tried. -Where in the World Does Fortran (and GNU C) Go? ------------------------------------------------ +Where in the World Does Fortran (and GNU CC) Go? +------------------------------------------------ Before configuring, you should make sure you know where you want the `g77' and `gcc' binaries to be installed after they're built, because @@ -745,7 +987,7 @@ the system. Sometimes people make the mistake of installing `gcc' as `/usr/local/bin/gcc', leaving an older, non-Fortran-aware version in -`/usr/bin/gcc'. (Or, the opposite happens.) This can result in `g77' +`/usr/bin/gcc'. (Or, the opposite happens.) This can result in `g77' being unable to compile Fortran source files, because when it calls on `gcc' to do the actual compilation, `gcc' complains that it does not recognize the language, or the file name suffix. @@ -891,16 +1133,13 @@ large number of object files to ensure they're identical). you can type `rm -fr stage1' to remove the binaries built during Stage 1. - *Note:* If you do build Stage 3 and you compare the object files -produced by various stages, the file `gcc/f/zzz.o' *will* be different. -That is because it contains a string with an expansion of the -`__TIME__' macro, which expands to the current time of day. It is -nothing to worry about, since `gcc/f/zzz.c' doesn't contain any actual -code. It does allow you to override its use of `__DATE__' and -`__TIME__' by defining macros for the compilation--see the source code -for details. + *Note:* *Note Object File Differences::, for information on expected +differences in object files produced during Stage 2 and Stage 3 of a +bootstrap build. These differences will be encountered as a result of +using the `make compare' or similar command sequence recommended by the +GNU CC installation documentation. - *Note Installing GNU CC: (gcc)Installation, for important + Also, *Note Installing GNU CC: (gcc)Installation, for important information on building `gcc' that is not described in this `g77' manual. For example, explanations of diagnostic messages and whether they're expected, or indicate trouble, are found there. @@ -951,43 +1190,51 @@ them when they work: sh# cd /usr/src/gcc sh# ./g77 --driver=./xgcc -B./ -v - ./xgcc -B./ -v -fnull-version -o /tmp/gfa03648 ... + g77 version 0.5.20 + ./xgcc -B./ -v -fnull-version -o /tmp/gfa18047 ... Reading specs from ./specs - gcc version 2.7.1 + gcc version 2.7.2.2.f.2 ./cpp -lang-c -v -isystem ./include -undef ... - GNU CPP version 2.7.1 (80386, BSD syntax) + GNU CPP version 2.7.2.2.f.2 (Linux/Alpha) #include "..." search starts here: #include <...> search starts here: ./include - /usr/include - /usr/i486-unknown-linuxaout/include - /usr/lib/gcc-lib/i486-unknown-linuxaout/2.7.1/include + /usr/local/include + /usr/alpha-unknown-linux/include + /usr/lib/gcc-lib/alpha-unknown-linux/2.7.2.2.f.2/include /usr/include End of search list. - ./f771 /tmp/cca03648.i -quiet -dumpbase null.F -version ... - GNU F77 version 2.7.1 (80386, BSD syntax) compiled ... - GNU Fortran Front End version 0.5.19 compiled: ... - as -o /tmp/cca036481.o /tmp/cca03648.s - ld -m i386linux -o /tmp/gfa03648 /usr/lib/crt0.o -L. ... - /usr/lib/crt0.o(.text+0x35): undefined reference to `main' + ./f771 /tmp/cca18048.i -fset-g77-defaults -quiet -dumpbase ... + GNU F77 version 2.7.2.2.f.2 (Linux/Alpha) compiled ... + GNU Fortran Front End version 0.5.20-970224 compiled: ... + as -nocpp -o /tmp/cca180481.o /tmp/cca18048.s + ld -G 8 -O1 -o /tmp/gfa18047 /usr/lib/crt0.o -L. ... + __G77_LIBF77_VERSION__: 0.5.20 + @(#)LIBF77 VERSION 19960619 + __G77_LIBI77_VERSION__: 0.5.20 + @(#) LIBI77 VERSION pjw,dmg-mods 19961209 + __G77_LIBU77_VERSION__: 0.5.20 + @(#) LIBU77 VERSION 19970204 sh# ./xgcc -B./ -v -o /tmp/delete-me -xc /dev/null -xnone Reading specs from ./specs - gcc version 2.7.1 + gcc version 2.7.2.2.f.2 ./cpp -lang-c -v -isystem ./include -undef ... - GNU CPP version 2.7.1 (80386, BSD syntax) + GNU CPP version 2.7.2.2.f.2 (Linux/Alpha) #include "..." search starts here: #include <...> search starts here: ./include - /usr/include - /usr/i486-unknown-linuxaout/include - /usr/lib/gcc-lib/i486-unknown-linuxaout/2.7.1/include + /usr/local/include + /usr/alpha-unknown-linux/include + /usr/lib/gcc-lib/alpha-unknown-linux/2.7.2.2.f.2/include /usr/include End of search list. - ./cc1 /tmp/cca03659.i -quiet -dumpbase null.c -version ... - GNU C version 2.7.1 (80386, BSD syntax) compiled ... - as -o /tmp/cca036591.o /tmp/cca03659.s - ld -m i386linux -o /tmp/delete-me /usr/lib/crt0.o -L. ... - /usr/lib/crt0.o(.text+0x35): undefined reference to `main' + ./cc1 /tmp/cca18063.i -quiet -dumpbase null.c -version ... + GNU C version 2.7.2.2.f.2 (Linux/Alpha) compiled ... + as -nocpp -o /tmp/cca180631.o /tmp/cca18063.s + ld -G 8 -O1 -o /tmp/delete-me /usr/lib/crt0.o -L. ... + /usr/lib/crt0.o: In function `__start': + crt0.S:110: undefined reference to `main' + /usr/lib/crt0.o(.lita+0x28): undefined reference to `main' sh# (Note that long lines have been truncated, and `...' used to @@ -995,13 +1242,11 @@ indicate such truncations.) The above two commands test whether `g77' and `gcc', respectively, are able to compile empty (null) source files, whether invocation of -the C preprocessor works, whether libraries can be linked (even though -there is an undefined reference due to there being no main program -unit), and so on. +the C preprocessor works, whether libraries can be linked, and so on. If the output you get from either of the above two commands is -noticably different, especially if it is shorter or longer in ways that -do not look consistent with the above sample output, you probably +noticeably different, especially if it is shorter or longer in ways +that do not look consistent with the above sample output, you probably should not install `gcc' and `g77' until you have investigated further. For example, you could try compiling actual applications and seeing @@ -1049,7 +1294,7 @@ the above command.) Note that using the `-k' option tells `make' to continue after some installation problems, like not having `makeinfo' installed on your -system. It might not be necessary. +system. It might not be necessary for your system. Updating Your Info Directory ---------------------------- @@ -1063,7 +1308,9 @@ the top-level file in the `info' directory on your system (perhaps * g77: (g77). The GNU Fortran programming language. If the menu in `dir' is organized into sections, `g77' probably -belongs in a section with a name such as the following: +belongs in a section with a name such as one of the following: + + * Fortran Programming * Writing Programs @@ -1175,7 +1422,9 @@ binaries you distribute include: not get overwritten. `info/g77.info*' - This is the documentation for `g77'. + This is the documentation for `g77'. If it is not included, users + will have trouble understanding diagnostics messages and other + such things, and will send you a lot of email asking questions. Please edit this documentation (by editing `gcc/f/*.texi' and doing `make doc' from the `/usr/src/gcc' directory) to reflect any @@ -1190,7 +1439,8 @@ binaries you distribute include: Documentation. `man/man1/g77.1' - This is the short man page for `g77'. + This is the short man page for `g77'. It is out of date, but you + might as well include it for people who really like man pages. `man/man1/f77.1' In installations where `f77' is the same as `g77', this is the @@ -1226,92 +1476,9 @@ general) are broken, at least for their system. until you're sure your distribution is widely used and has been well tested. This especially goes for those of you making any changes to the `g77' sources to port `g77', e.g. to OS/2. -`fortran@gnu.ai.mit.edu' has received a fair amount of bug reports that +<fortran@gnu.ai.mit.edu> has received a fair number of bug reports that turned out to be problems with other peoples' ports and distributions, about which nothing could be done for the user. Once you are quite certain a bug report does not involve your efforts, you can forward it to us. -Changing Settings Before Building -================================= - - Here are some internal `g77' settings that can be changed by editing -source files in `gcc/f/' before building. - - This information, and perhaps even these settings, represent -stop-gap solutions to problems people doing various ports of `g77' have -encountered. As such, none of the following information is expected to -be pertinent in future versions of `g77'. - -Maximum Stackable Size ----------------------- - - `g77', on most machines, puts many variables and arrays on the stack -where possible, and can be configured (by changing -`FFECOM_sizeMAXSTACKITEM' in `gcc/f/com.c') to force smaller-sized -entities into static storage (saving on stack space) or permit -larger-sized entities to be put on the stack (which can improve -run-time performance, as it presents more opportunities for the GBE to -optimize the generated code). - - *Note:* Putting more variables and arrays on the stack might cause -problems due to system-dependent limits on stack size. Also, the value -of `FFECOM_sizeMAXSTACKITEM' has no effect on automatic variables and -arrays. *Note But-bugs::, for more information. - -Floating-point Bit Patterns ---------------------------- - - The `g77' build will crash if an attempt is made to build it as a -cross-compiler for a target when `g77' cannot reliably determine the -bit pattern of floating-point constants for the target. Planned -improvements for g77-0.6 will give it the capabilities it needs to not -have to crash the build but rather generate correct code for the target. -(Currently, `g77' would generate bad code under such circumstances if -it didn't crash during the build, e.g. when compiling a source file -that does something like `EQUIVALENCE (I,R)' and `DATA R/9.43578/'.) - -Initialization of Large Aggregate Areas ---------------------------------------- - - A warning message is issued when `g77' sees code that provides -initial values (e.g. via `DATA') to an aggregate area (`COMMON' or -`EQUIVALENCE', or even a large enough array or `CHARACTER' variable) -that is large enough to increase `g77''s compile time by roughly a -factor of 10. - - This size currently is quite small, since `g77' currently has a -known bug requiring too much memory and time to handle such cases. In -`gcc/f/data.c', the macro `FFEDATA_sizeTOO_BIG_INIT_' is defined to the -minimum size for the warning to appear. The size is specified in -storage units, which can be bytes, words, or whatever, on a -case-by-case basis. - - After changing this macro definition, you must (of course) rebuild -and reinstall `g77' for the change to take effect. - - Note that, as of version 0.5.18, improvements have reduced the scope -of the problem for *sparse* initialization of large arrays, especially -those with large, contiguous uninitialized areas. However, the warning -is issued at a point prior to when `g77' knows whether the -initialization is sparse, and delaying the warning could mean it is -produced too late to be helpful. - - Therefore, the macro definition should not be adjusted to reflect -sparse cases. Instead, adjust it to generate the warning when densely -initialized arrays begin to cause responses noticably slower than -linear performance would suggest. - -Alpha Problems --------------- - - `g77' might warn when it is used to compile Fortran code for a -target configuration that is not basically a 32-bit machine (such as an -Alpha, which is a 64-bit machine, especially if it has a 64-bit -operating system running on it). This is because `g77' is known to not -work properly on such configurations. This is expected to be -completely fixed at 0.6, at which point the warning would be dropped. - - (Version 0.5.20 is expected to solve most of these problems, though, -as of this writing, work is still progressing in this area.) - diff --git a/gnu/usr.bin/gcc/f/Make b/gnu/usr.bin/gcc/f/Make deleted file mode 100644 index af29add2383..00000000000 --- a/gnu/usr.bin/gcc/f/Make +++ /dev/null @@ -1,244 +0,0 @@ -# Makefile for GNU F77 stand-alone front end. -# Copyright (C) 1995 Free Software Foundation, Inc. -# Contributed by James Craig Burley (burley@gnu.ai.mit.edu). - -#This file is part of GNU Fortran. - -#GNU Fortran is free software; you can redistribute it and/or modify -#it under the terms of the GNU General Public License as published by -#the Free Software Foundation; either version 2, or (at your option) -#any later version. - -#GNU Fortran is distributed in the hope that it will be useful, -#but WITHOUT ANY WARRANTY; without even the implied warranty of -#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -#GNU General Public License for more details. - -#You should have received a copy of the GNU General Public License -#along with GNU Fortran; see the file COPYING. If not, write to -#the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -#02111-1307, USA. - -objs=\ -parse.o \ -bad.o \ -bit.o \ -bld.o \ -com.o \ -data.o \ -equiv.o \ -expr.o \ -global.o \ -implic.o \ -info.o \ -intrin.o \ -lab.o \ -lex.o \ -malloc.o \ -name.o \ -proj.o \ -src.o \ -st.o \ -sta.o \ -stb.o \ -stc.o \ -std.o \ -ste.o \ -storag.o \ -stp.o \ -str.o \ -sts.o \ -stt.o \ -stu.o \ -stv.o \ -stw.o \ -symbol.o \ -target.o \ -top.o \ -where.o \ -zzz.o - -# Use appropriate compiler and options. -Wall will produce complaints about -# certain "fuzzy" (but hand-checked) uses of uninitialized variables, and -# other annoying warnings about uses of assert if assert.h doesn't specify -# it as volatile (effectively). -DNO_STDLIB is needed only on systems where -# including <stdlib.h> won't work (not found or doesn't contain the good -# stuff ANSI says it must). Similarly, -DLAME_STDIO is needed only on -# systems where the varying-args functions aren't prototyped and you want to -# catch references to non-prototyped functions. And -DLAME_ASSERT is needed -# if the assert macro is not defined as volatile, effectively, but you -# want to catch certain other warnings. -DFFE_STANDALONE is what builds -# the front end in stand-alone mode; otherwise it tries to build as GNU -# Fortran (i.e. with the GNU back end). - -CC=gcc -CFLAGS=-O6 -g -Wall - -ffe: cktyps.out $(objs) - $(CC) $(CFLAGS) -DFFE_STANDALONE -o ffe $(objs) - -cktyps.out: cktyps - ./cktyps > cktyps.out - -cktyps: cktyps.o proj.o - $(CC) $(CFLAGS) -DFFE_STANDALONE -o cktyps cktyps.o proj.o - -# Begin results obtained from "make -f Make deps-kinda". -# Note that this command uses the host C compiler; use CC="./xgcc -B./" to -# use GCC in the build directory, for example. - -bad.o : bad.c proj.h malloc.h bad.h bad.def where.h top.h com.h bld.h bld-op.def \ - bit.h info.h info-b.def info-k.def info-w.def target.h lex.h intrin.h intrin.def \ - lab.h symbol.h symbol.def equiv.h storag.h global.h name.h -bit.o : bit.c proj.h malloc.h bit.h -bld.o : bld.c proj.h malloc.h bld.h bld-op.def bit.h com.h info.h info-b.def \ - info-k.def info-w.def target.h bad.h bad.def where.h top.h lex.h lab.h storag.h \ - symbol.h symbol.def equiv.h global.h name.h intrin.h intrin.def -cktyps.o : cktyps.c proj.h malloc.h target.h bad.h bad.def where.h top.h info.h \ - info-b.def info-k.def info-w.def lex.h -com.o : com.c proj.h malloc.h com.h bld.h bld-op.def bit.h info.h info-b.def \ - info-k.def info-w.def target.h bad.h bad.def where.h top.h lex.h intrin.h intrin.def \ - lab.h symbol.h symbol.def equiv.h storag.h global.h name.h expr.h implic.h src.h \ - st.h -data.o : data.c proj.h malloc.h data.h bld.h bld-op.def bit.h com.h info.h info-b.def \ - info-k.def info-w.def target.h bad.h bad.def where.h top.h lex.h lab.h storag.h \ - symbol.h symbol.def equiv.h global.h name.h intrin.h intrin.def expr.h st.h -equiv.o : equiv.c proj.h malloc.h equiv.h bld.h bld-op.def bit.h com.h info.h \ - info-b.def info-k.def info-w.def target.h bad.h bad.def where.h top.h lex.h \ - lab.h storag.h symbol.h symbol.def global.h name.h intrin.h intrin.def data.h -expr.o : expr.c proj.h malloc.h expr.h bld.h bld-op.def bit.h com.h info.h info-b.def \ - info-k.def info-w.def target.h bad.h bad.def where.h top.h lex.h lab.h storag.h \ - symbol.h symbol.def equiv.h global.h name.h intrin.h intrin.def implic.h src.h \ - st.h -fini.o : fini.c proj.h malloc.h -g77.o : g77.c config.h -global.o : global.c proj.h malloc.h global.h lex.h top.h where.h name.h symbol.h \ - symbol.def bad.h bad.def bld.h bld-op.def bit.h com.h info.h info-b.def info-k.def \ - info-w.def target.h lab.h storag.h intrin.h intrin.def equiv.h -implic.o : implic.c proj.h malloc.h implic.h info.h info-b.def info-k.def info-w.def \ - target.h bad.h bad.def where.h top.h lex.h symbol.h symbol.def bld.h bld-op.def \ - bit.h com.h lab.h storag.h intrin.h intrin.def equiv.h global.h name.h src.h -info.o : info.c proj.h malloc.h info.h info-b.def info-k.def info-w.def target.h \ - bad.h bad.def where.h top.h lex.h -intrin.o : intrin.c proj.h malloc.h intrin.h intrin.def bld.h bld-op.def bit.h \ - com.h info.h info-b.def info-k.def info-w.def target.h bad.h bad.def where.h \ - top.h lex.h lab.h storag.h symbol.h symbol.def equiv.h global.h name.h src.h -lab.o : lab.c proj.h malloc.h lab.h com.h bld.h bld-op.def bit.h info.h info-b.def \ - info-k.def info-w.def target.h bad.h bad.def where.h top.h lex.h intrin.h intrin.def \ - symbol.h symbol.def equiv.h storag.h global.h name.h -lex.o : lex.c proj.h malloc.h top.h where.h bad.h bad.def lex.h src.h -malloc.o : malloc.c proj.h malloc.h -name.o : name.c proj.h malloc.h bad.h bad.def where.h top.h name.h global.h \ - lex.h symbol.h symbol.def bld.h bld-op.def bit.h com.h info.h info-b.def info-k.def \ - info-w.def target.h lab.h storag.h intrin.h intrin.def equiv.h src.h -parse.o : parse.c proj.h malloc.h top.h where.h com.h bld.h bld-op.def bit.h \ - info.h info-b.def info-k.def info-w.def target.h bad.h bad.def lex.h intrin.h \ - intrin.def lab.h symbol.h symbol.def equiv.h storag.h global.h name.h zzz.h -proj.o : proj.c proj.h malloc.h -src.o : src.c proj.h malloc.h src.h bad.h bad.def where.h top.h -st.o : st.c proj.h malloc.h st.h bad.h bad.def where.h top.h lex.h symbol.h \ - symbol.def bld.h bld-op.def bit.h com.h info.h info-b.def info-k.def info-w.def \ - target.h lab.h storag.h intrin.h intrin.def equiv.h global.h name.h sta.h stamp-str \ - stb.h expr.h stp.h stt.h stc.h std.h stv.h stw.h ste.h sts.h stu.h -sta.o : sta.c proj.h malloc.h sta.h bad.h bad.def where.h top.h lex.h stamp-str \ - symbol.h symbol.def bld.h bld-op.def bit.h com.h info.h info-b.def info-k.def \ - info-w.def target.h lab.h storag.h intrin.h intrin.def equiv.h global.h name.h \ - implic.h stb.h expr.h stp.h stt.h stc.h std.h stv.h stw.h -stb.o : stb.c proj.h malloc.h stb.h bad.h bad.def where.h top.h expr.h bld.h \ - bld-op.def bit.h com.h info.h info-b.def info-k.def info-w.def target.h lex.h \ - lab.h storag.h symbol.h symbol.def equiv.h global.h name.h intrin.h intrin.def \ - stp.h stt.h stamp-str src.h sta.h stc.h -stc.o : stc.c proj.h malloc.h stc.h bad.h bad.def where.h top.h bld.h bld-op.def \ - bit.h com.h info.h info-b.def info-k.def info-w.def target.h lex.h lab.h storag.h \ - symbol.h symbol.def equiv.h global.h name.h intrin.h intrin.def expr.h stp.h \ - stt.h stamp-str data.h implic.h src.h sta.h std.h stv.h stw.h -std.o : std.c proj.h malloc.h std.h bld.h bld-op.def bit.h com.h info.h info-b.def \ - info-k.def info-w.def target.h bad.h bad.def where.h top.h lex.h lab.h storag.h \ - symbol.h symbol.def equiv.h global.h name.h intrin.h intrin.def stp.h stt.h \ - stamp-str stv.h stw.h sta.h ste.h sts.h -ste.o : ste.c proj.h malloc.h ste.h bld.h bld-op.def bit.h com.h info.h info-b.def \ - info-k.def info-w.def target.h bad.h bad.def where.h top.h lex.h lab.h storag.h \ - symbol.h symbol.def equiv.h global.h name.h intrin.h intrin.def stp.h stt.h \ - stamp-str sts.h stv.h stw.h sta.h -storag.o : storag.c proj.h malloc.h storag.h bld.h bld-op.def bit.h com.h info.h \ - info-b.def info-k.def info-w.def target.h bad.h bad.def where.h top.h lex.h \ - lab.h symbol.h symbol.def equiv.h global.h name.h intrin.h intrin.def data.h -stp.o : stp.c proj.h malloc.h stp.h bld.h bld-op.def bit.h com.h info.h info-b.def \ - info-k.def info-w.def target.h bad.h bad.def where.h top.h lex.h lab.h storag.h \ - symbol.h symbol.def equiv.h global.h name.h intrin.h intrin.def stt.h -str.o : str.c proj.h malloc.h src.h bad.h bad.def where.h top.h stamp-str lex.h -sts.o : sts.c proj.h malloc.h sts.h com.h bld.h bld-op.def bit.h info.h info-b.def \ - info-k.def info-w.def target.h bad.h bad.def where.h top.h lex.h intrin.h intrin.def \ - lab.h symbol.h symbol.def equiv.h storag.h global.h name.h -stt.o : stt.c proj.h malloc.h stt.h top.h where.h bld.h bld-op.def bit.h com.h \ - info.h info-b.def info-k.def info-w.def target.h bad.h bad.def lex.h lab.h storag.h \ - symbol.h symbol.def equiv.h global.h name.h intrin.h intrin.def stp.h expr.h \ - sta.h stamp-str -stu.o : stu.c proj.h malloc.h bld.h bld-op.def bit.h com.h info.h info-b.def \ - info-k.def info-w.def target.h bad.h bad.def where.h top.h lex.h lab.h storag.h \ - symbol.h symbol.def equiv.h global.h name.h intrin.h intrin.def implic.h stu.h \ - sta.h stamp-str -stv.o : stv.c proj.h malloc.h stv.h lab.h com.h bld.h bld-op.def bit.h info.h \ - info-b.def info-k.def info-w.def target.h bad.h bad.def where.h top.h lex.h \ - intrin.h intrin.def symbol.h symbol.def equiv.h storag.h global.h name.h -stw.o : stw.c proj.h malloc.h stw.h bld.h bld-op.def bit.h com.h info.h info-b.def \ - info-k.def info-w.def target.h bad.h bad.def where.h top.h lex.h lab.h storag.h \ - symbol.h symbol.def equiv.h global.h name.h intrin.h intrin.def stv.h sta.h \ - stamp-str -symbol.o : symbol.c proj.h malloc.h symbol.h symbol.def bad.h bad.def where.h \ - top.h bld.h bld-op.def bit.h com.h info.h info-b.def info-k.def info-w.def target.h \ - lex.h lab.h storag.h intrin.h intrin.def equiv.h global.h name.h src.h st.h -target.o : target.c proj.h malloc.h target.h bad.h bad.def where.h top.h info.h \ - info-b.def info-k.def info-w.def lex.h -top.o : top.c proj.h malloc.h top.h where.h bad.h bad.def bit.h bld.h bld-op.def \ - com.h info.h info-b.def info-k.def info-w.def target.h lex.h lab.h storag.h \ - symbol.h symbol.def equiv.h global.h name.h intrin.h intrin.def data.h expr.h \ - implic.h src.h st.h -where.o : where.c proj.h malloc.h lex.h top.h where.h -zzz.o : zzz.c proj.h malloc.h zzz.h - -# The rest of this list (Fortran 77 language-specific files) is hand-generated. - -stamp-str: str-1t.h str-1t.j str-2t.h str-2t.j str-fo.h str-fo.j \ - str-io.h str-io.j str-nq.h str-nq.j str-op.h str-op.j str-ot.h str-ot.j - touch stamp-str - -str-1t.h str-1t.j: fini str-1t.fin - ./fini str-1t - -str-2t.h str-2t.j: fini str-2t.fin - ./fini str-2t - -str-fo.h str-fo.j: fini str-fo.fin - ./fini str-fo - -str-io.h str-io.j: fini str-io.fin - ./fini str-io - -str-nq.h str-nq.j: fini str-nq.fin - ./fini str-nq - -str-op.h str-op.j: fini str-op.fin - ./fini str-op - -str-ot.h str-ot.j: fini str-ot.fin - ./fini str-ot - -fini: fini.o proj.o - $(CC) $(CFLAGS) -DFFE_STANDALONE -o fini fini.o proj.o - -deps-kinda: str-1t.h str-1t.j str-2t.h str-2t.j \ - str-fo.h str-fo.j str-io.h str-io.j str-nq.h str-nq.j \ - str-op.h str-op.j str-ot.h str-ot.j - $(CC) $(CFLAGS) -DFFE_STANDALONE -DMAKING_DEPENDENCIES -MM *.c | \ - sed -e 's: \([.]/\)*str[.]h : stamp-str :g' - -.c.o: - $(CC) $(CFLAGS) -DFFE_STANDALONE -c $< - -clean: - -rm -f ffe fini cktyps cktyps.out stamp-str *.o str-*.h str-*.j - -.PHONY: clean deps-kinda - -force: diff --git a/gnu/usr.bin/gcc/f/Make-lang.in b/gnu/usr.bin/gcc/f/Make-lang.in index 92f2fa7b134..021d0e28762 100644 --- a/gnu/usr.bin/gcc/f/Make-lang.in +++ b/gnu/usr.bin/gcc/f/Make-lang.in @@ -1,5 +1,5 @@ # Top level makefile fragment for GNU Fortran. -*-makefile-*- -# Copyright (C) 1995, 1996 Free Software Foundation, Inc. +# Copyright (C) 1995-1997 Free Software Foundation, Inc. #This file is part of GNU Fortran. @@ -35,6 +35,8 @@ # - making any compiler driver (eg: g77) # - the compiler proper (eg: f771) # - define the names for selecting the language in LANGUAGES. +# +# $(srcdir) must be set to the gcc/ source directory (not gcc/f/). # Extra flags to pass to recursive makes (and to sub-configure). # Use different quoting rules compared with FLAGS_TO_PASS so we can use @@ -109,7 +111,7 @@ F77 f77: f771 f77-runtime f77.stage4 f77.distdir f77.rebuilt # Create the compiler driver for g77 (only if `f77' is in LANGUAGES). -g77: f/g77.c $(CONFIG_H) $(LIBDEPS) +g77: $(srcdir)/f/g77.c $(srcdir)/f/zzz.c $(CONFIG_H) $(LIBDEPS) case '$(LANGUAGES)' in \ *f77*) \ $(CC) $(ALL_CFLAGS) $(INCLUDES) $(LDFLAGS) \ @@ -118,7 +120,7 @@ g77: f/g77.c $(CONFIG_H) $(LIBDEPS) # Create a version of the g77 driver which calls the cross-compiler # (only if `f77' is in LANGUAGES). -g77-cross: f/g77.c version.o $(LIBDEPS) +g77-cross: $(srcdir)f/g77.c $(srcdir)/f/zzz.c version.o $(LIBDEPS) case '$(LANGUAGES)' in \ *f77*) \ $(CC) $(ALL_CFLAGS) $(INCLUDES) $(LDFLAGS) \ @@ -126,15 +128,6 @@ g77-cross: f/g77.c version.o $(LIBDEPS) -o $@ $(srcdir)/f/g77.c $(srcdir)/f/zzz.c $(LIBS) ;; \ esac -# g77 documentation. -$(build_infodir)/f/g77.info: f/g77.texi f/bugs.texi f/install.texi f/news.texi - $(MAKEINFO) -P$(srcdir)/f $(srcdir)/f/g77.texi \ - -o $(build_infodir)/f/g77.info - -# XXX OpenBSD What to do with dvi builds...? -$(srcdir)/f/g77.dvi: f/g77.texi f/bugs.texi f/install.texi f/news.texi - $(TEXI2DVI) $(srcdir)/f/g77.texi - F77_SRCS = \ $(srcdir)/f/assert.j \ $(srcdir)/f/bad.c \ @@ -240,7 +233,7 @@ F77_SRCS = \ $(srcdir)/f/zzz.h f771: $(P) $(F77_SRCS) $(LIBDEPS) stamp-objlist f/Makefile - $(MAKE) -f f/Makefile $(FLAGS_TO_PASS) VPATH=$(srcdir) srcdir=$(srcdir)/f f771 + $(MAKE) -f f/Makefile $(FLAGS_TO_PASS) VPATH=$(srcdir) srcdir=$(srcdir) f771 f/Makefile: $(srcdir)/f/Makefile.in $(srcdir)/configure $(SHELL) config.status @@ -254,7 +247,7 @@ f/Makefile: $(srcdir)/f/Makefile.in $(srcdir)/configure stmp-headers = stmp-headers # to be overrideable in unsafe version # Depend on stmp-headers, not stmp-int-hdrs, since libF77 needs float.h. f77-runtime: f/runtime/Makefile include/f2c.h $(stmp-headers) \ - f/runtime/libF77/Makefile f/runtime/libI77/Makefile + f/runtime/libF77/Makefile f/runtime/libI77/Makefile f/runtime/libU77/Makefile case "$(LANGUAGES)" in \ *f77*) top=`pwd`; \ cd f/runtime && $(MAKE) \ @@ -274,12 +267,19 @@ f77-runtime-unsafe: # configure, not a Cygnus-type one. It needs to be run *after* the # appropriate (cross-)compiler has been built, thus depend on GCC_PARTS. # NB, sh uses the *first* value of $a from `a=fred a=joe prog'. -include/f2c.h f/runtime/Makefile \ -f/runtime/libF77/Makefile f/runtime/libI77/Makefile: \ +include/f2c.h \ +f/runtime/Makefile \ +f/runtime/libF77/Makefile \ +f/runtime/libI77/Makefile \ +f/runtime/libU77/Makefile: \ $(srcdir)/f/runtime/f2c.h.in \ - $(srcdir)/f/com.h f/proj.h $(srcdir)/f/runtime/Makefile.in \ + $(srcdir)/f/com.h $(srcdir)/f/proj.h \ + $(srcdir)/f/runtime/Makefile.in \ $(srcdir)/f/runtime/libF77/Makefile.in \ $(srcdir)/f/runtime/libI77/Makefile.in \ + $(srcdir)/f/runtime/libU77/Makefile.in \ + $(srcdir)/f/runtime/configure \ + $(srcdir)/f/runtime/libU77/configure \ $(GCC_PARTS) # The make "stage?" in compiler spec. is fully qualified as above top=`pwd`; \ @@ -290,6 +290,14 @@ f/runtime/libF77/Makefile f/runtime/libI77/Makefile: \ *) echo '$(GCC_FOR_TARGET)';; esac`" \ $(F77_FLAGS_TO_PASS) CONFIG_SITE=/dev/null $(SHELL) \ $${src}/f/runtime/configure --srcdir=$${src}/f/runtime + top=`pwd`; \ + src=`cd $(srcdir); pwd`; \ + cd f/runtime/libU77; \ + CC="`case '$(GCC_FOR_TARGET)' in \ + './xgcc -B./') echo $${top}/xgcc -B$${top}/;; \ + *) echo '$(GCC_FOR_TARGET)';; esac`" \ + $(F77_FLAGS_TO_PASS) CONFIG_SITE=/dev/null $(SHELL) \ + $${src}/f/runtime/libU77/configure --srcdir=$${src}/f/runtime/libU77 #For now, omit f2c stuff. -- burley #f2c: stmp-headers f/f2c/Makefile @@ -311,26 +319,56 @@ f77.start.encap: g77 maybe-f2c f77.rest.encap: f77.info: $(build_infodir)/f/g77.info -# XXX OpenBSD What to do with dvi rules...? +# XXX OpenBSD - what to do with dvi rules ...? f77.dvi: $(srcdir)/f/g77.dvi -$(srcdir)/f/BUGS: f/bugs0.texi f/bugs.texi - cd $(srcdir)/f; $(MAKEINFO) -D BUGSONLY --no-header --no-split \ - --no-validate bugs0.texi -o BUGS +# XXX OpenBSD - these are the documentation rules for OpenBSD - for now +# we will only install the g77 info files - the original +# g77 documentation rules will follow then commented out +# g77 documentation. +$(build_infodir)/f/g77.info: f/g77.texi f/bugs.texi f/install.texi f/news.texi + $(MAKEINFO) -I$(srcdir)/f $(srcdir)/f/g77.texi \ + -o $(build_infodir)/f/g77.info -$(srcdir)/f/INSTALL: f/install0.texi f/install.texi - cd $(srcdir)/f; $(MAKEINFO) -D INSTALLONLY --no-header --no-split \ - --no-validate install0.texi -o INSTALL +# XXX OpenBSD - what to do with dvi rules ...? +$(srcdir)/f/g77.dvi: f/g77.texi f/bugs.texi f/install.texi f/news.texi + $(TEXI2DVI) $(srcdir)/f/g77.texi -$(srcdir)/f/NEWS: f/news0.texi f/news.texi - cd $(srcdir)/f; $(MAKEINFO) -D NEWSONLY --no-header --no-split \ - --no-validate news0.texi -o NEWS +# XXX OpenBSD - these are the original g77-0.5.20 documentation rules +# g77 documentation. +#$(srcdir)/f/g77.info: f/g77.texi f/bugs.texi f/install.texi f/news.texi f/intdoc.texi +# cd $(srcdir)/f; $(MAKEINFO) g77.texi +# +#$(srcdir)/f/g77.dvi: f/g77.texi f/bugs.texi f/install.texi f/news.texi f/intdoc.texi +# cd $(srcdir)/f; $(TEXI2DVI) g77.texi +# +#$(srcdir)/f/intdoc.texi: f/intdoc +# f/intdoc > $(srcdir)/f/intdoc.texi +# +#f/intdoc: f/intdoc.c f/intdoc.h f/intrin.def f/intrin.h +# $(HOST_CC) $(HOST_CFLAGS) -W -Wall $(HOST_LDFLAGS) \ +# `echo $(srcdir)/f/intdoc.c | sed 's,^\./,,'` -o f/intdoc +# +#$(srcdir)/f/BUGS: f/bugs0.texi f/bugs.texi +# cd $(srcdir)/f; $(MAKEINFO) -D BUGSONLY --no-header --no-split \ +# --no-validate bugs0.texi -o BUGS +# +#$(srcdir)/f/INSTALL: f/install0.texi f/install.texi +# cd $(srcdir)/f; $(MAKEINFO) -D INSTALLONLY --no-header --no-split \ +# --no-validate install0.texi -o INSTALL +# +#$(srcdir)/f/NEWS: f/news0.texi f/news.texi +# cd $(srcdir)/f; $(MAKEINFO) -D NEWSONLY --no-header --no-split \ +# --no-validate news0.texi -o NEWS -$(srcdir)/f/runtime/configure: f/runtime/configure.in - cd f/runtime && $(MAKE) rebuilt +$(srcdir)/f/runtime/configure: $(srcdir)/f/runtime/configure.in + cd f/runtime && $(MAKE) srcdir=../../$(srcdir)/f/runtime -f ../../$(srcdir)/f/runtime/Makefile.in rebuilt +$(srcdir)/f/runtime/libU77/configure: $(srcdir)/f/runtime/libU77/configure.in + cd f/runtime && $(MAKE) srcdir=../../$(srcdir)/f/runtime -f ../../$(srcdir)/f/runtime/Makefile.in rebuilt -f77.rebuilt: f/g77.info f/BUGS f/INSTALL f/NEWS f/runtime/configure - echo Fortran rebuildable files rebuilt. +f77.rebuilt: $(srcdir)/f/g77.info $(srcdir)/f/BUGS $(srcdir)/f/INSTALL \ + $(srcdir)/f/NEWS $(srcdir)/f/runtime/configure \ + $(srcdir)/f/runtime/libU77/configure maybe-f2c: #For now, omit f2c stuff. -- burley @@ -469,17 +507,16 @@ f77.uninstall: f77.mostlyclean: -rm -f f/*$(objext) - -rm -f f/fini f/f771 f/stamp-str f/str-*.h f/str-*.j - -cd f/runtime; $(MAKE) mostlyclean + -rm -f f/fini f/f771 f/stamp-str f/str-*.h f/str-*.j f/intdoc + -cd f/runtime; $(MAKE) -f ../../$(srcdir)/f/runtime/Makefile.in mostlyclean f77.clean: - -cd f/runtime; $(MAKE) mostlyclean - -$(MAKE) f77.mostlyclean + -cd f/runtime; $(MAKE) -f ../../$(srcdir)/f/runtime/Makefile.in clean f77.distclean: - -cd f/runtime; $(MAKE) distclean - -$(MAKE) f77.clean + -cd f/runtime; $(MAKE) -f ../../$(srcdir)/f/runtime/Makefile.in distclean -rm -f f/Makefile # like gcc's extraclean, which does clean f/ for us, but not f/gbe, -# f/runtime, f/runtime/libF77, and f/runtime/libI77, so do those. +# f/runtime, f/runtime/libF77, f/runtime/libI77, and f/runtime/libU77, +# so do those. f77.extraclean: f77.distclean -rm -f f/*/=* f/*/"#"* f/*/*~* -rm -f f/*/patch* f/*/*.orig f/*/*.rej @@ -493,37 +530,46 @@ f77.extraclean: f77.distclean -rm -f f/*/*/*lose f/*/*/*.s f/*/*/*.s[0-9] f/*/*/*.i # realclean is the pre-2.7.0 name for maintainer-clean f77.maintainer-clean f77.realclean: f77.distclean - -rm -f f/g77.info* f/g77.*aux f/TAGS f/BUGS f/INSTALL f/NEWS + -cd f/runtime; $(MAKE) -f ../../$(srcdir)/f/runtime/Makefile.in maintainer-clean + -$(MAKE) f77.maintainer-clean + -rm -f f/g77.info* f/g77.*aux f/TAGS f/BUGS f/INSTALL f/NEWS f/intdoc.texi # Stage hooks: # The main makefile has already created stage?/f. G77STAGESTUFF = f/*$(objext) f/fini f/stamp-str f/str-*.h f/str-*.j RUNTIMESTAGESTUFF = f/runtime/config.cache f/runtime/config.log \ - f/runtime/config.status f/runtime/Makefile + f/runtime/config.status f/runtime/Makefile LIBF77STAGESTUFF = f/runtime/libF77/*$(objext) f/runtime/libF77/Makefile LIBI77STAGESTUFF = f/runtime/libI77/*$(objext) f/runtime/libI77/Makefile +LIBU77STAGESTUFF = f/runtime/libU77/*$(objext) f/runtime/libU77/Makefile \ + f/runtime/libU77/config.cache f/runtime/libU77/config.log \ + f/runtime/libU77/config.status f77.stage1: -mv $(G77STAGESTUFF) stage1/f -mv $(RUNTIMESTAGESTUFF) stage1/f/runtime -mv $(LIBF77STAGESTUFF) stage1/f/runtime/libF77 -mv $(LIBI77STAGESTUFF) stage1/f/runtime/libI77 + -mv $(LIBU77STAGESTUFF) stage1/f/runtime/libU77 f77.stage2: -mv $(G77STAGESTUFF) stage2/f -mv $(RUNTIMESTAGESTUFF) stage2/f/runtime -mv $(LIBF77STAGESTUFF) stage2/f/runtime/libF77 -mv $(LIBI77STAGESTUFF) stage2/f/runtime/libI77 + -mv $(LIBU77STAGESTUFF) stage2/f/runtime/libU77 f77.stage3: -mv $(G77STAGESTUFF) stage3/f -mv $(RUNTIMESTAGESTUFF) stage3/f/runtime -mv $(LIBF77STAGESTUFF) stage3/f/runtime/libF77 -mv $(LIBI77STAGESTUFF) stage3/f/runtime/libI77 + -mv $(LIBU77STAGESTUFF) stage3/f/runtime/libU77 f77.stage4: -mv $(G77STAGESTUFF) stage4/f -mv $(RUNTIMESTAGESTUFF) stage4/f/runtime -mv $(LIBF77STAGESTUFF) stage4/f/runtime/libF77 -mv $(LIBI77STAGESTUFF) stage4/f/runtime/libI77 + -mv $(LIBU77STAGESTUFF) stage4/f/runtime/libU77 # Maintenance hooks: diff --git a/gnu/usr.bin/gcc/f/Makefile.in b/gnu/usr.bin/gcc/f/Makefile.in index fd29ecc10c5..a074f7b0327 100644 --- a/gnu/usr.bin/gcc/f/Makefile.in +++ b/gnu/usr.bin/gcc/f/Makefile.in @@ -1,5 +1,5 @@ # Makefile for GNU F77 compiler. -# Copyright (C) 1995 Free Software Foundation, Inc. +# Copyright (C) 1995-1997 Free Software Foundation, Inc. #This file is part of GNU Fortran. @@ -87,17 +87,12 @@ GCC_CFLAGS=$(INTERNAL_CFLAGS) $(X_CFLAGS) $(T_CFLAGS) $(CFLAGS) target= ... `configure' substitutes actual target name here. xmake_file= ... `configure' substitutes actual x- file name here. tmake_file= ... `configure' substitutes actual t- file name here. -#version=`sed -e 's/.*\"\([^ \"]*\)[ \"].*/\1/' < $(srcdir)/version.c` -#mainversion=`sed -e 's/.*\"\([0-9]*\.[0-9]*\).*/\1/' < $(srcdir)/version.c` -# Directory where sources are, from where we are. +# Directory where gcc sources are (gcc/), from where we are. # Note that this should be overridden when building f771, which happens # at the top level, not in f. Likewise for VPATH (if added). srcdir = . -# The following overriding of the VPATH inserted by configure (as well as -# the change to the standard srcdir above) is due to not building in the f -# directory as standard. -#VPATH = $(srcdir)../ +VPATH = . # Additional system libraries to link with. CLIB= @@ -142,7 +137,7 @@ ALL_CPPFLAGS = $(CPPFLAGS) $(X_CPPFLAGS) $(T_CPPFLAGS) # appropriate for the linker on AIX 4.1 and above. F771_LDFLAGS = `case "${target}" in\ m68k-next-nextstep*) echo -segaddr __DATA 6000000;;\ - *-*-aix[4-9]*) echo -Wl,-bbigtoc;; esac` + *-*-aix[4-9]*) \`$(CC) --print-prog-name=ld\` -v 2>&1 | grep BFD >/dev/null || echo -Wl,-bbigtoc;; esac` # Even if ALLOCA is set, don't use it if compiling with GCC. @@ -157,11 +152,8 @@ LIBS = $(SUBDIR_OBSTACK) $(SUBDIR_USE_ALLOCA) $(SUBDIR_MALLOC) $(CLIB) # Specify the directories to be searched for header files. # Both . and srcdir are used, in that order, # so that tm.h and config.h will be found in the compilation -# subdirectory rather than in the source directory. -INCLUDES = -If -I. -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../config - -#(Old way of doing things, new way being better for -g:) -#INCLUDES = -I. -I.. -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../config +# directory rather than in the source directory. +INCLUDES = -If -I$(srcdir)/f -I. -I$(srcdir) -I$(srcdir)/config # Flags_to_pass to recursive makes. # Note that we don't need to distinguish the `_FOR_TARGET' cross tools @@ -190,7 +182,6 @@ FLAGS_TO_PASS = \ "bindir=$(bindir)" \ "libsubdir=$(libsubdir)" -# Always use -I$(srcdir)/config when compiling. .c.o: $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< -o $@ @@ -245,7 +236,7 @@ OBJDEPS = stamp-objlist compiler: f771 # This is now meant to be built in the top level directory, not `f': f771: $(P) f/Makefile $(F77_OBJS) $(OBJDEPS) $(LIBDEPS) - rm -f ../f771$(exeext) + rm -f f771$(exeext) $(CC) $(ALL_CFLAGS) $(LDFLAGS) $(F771_LDFLAGS) -o $@ \ $(F77_OBJS) $(OBJS) $(LIBS) @@ -255,7 +246,7 @@ f/Makefile: then echo "Build f771 only at the top level." 2>&1; exit 1; \ else true; fi -Makefile: $(srcdir)/Makefile.in $(srcdir)/../configure +Makefile: $(srcdir)/f/Makefile.in $(srcdir)/configure native: f771 @@ -270,22 +261,22 @@ native: f771 # the gcc-source files involved (each file itself, plus whatever # files on which it depends, but without including stuff resulting # from configuration, since we can't guess at that). The files -# that live in a distclean'd gcc source directory have "$(srcdir)/../" +# that live in a distclean'd gcc source directory have "$(srcdir)/" # prefixes, while the others don't because they'll be created # only in the build directory. -ASSERT_H = $(srcdir)/assert.j $(srcdir)/../assert.h -CONFIG_H = $(srcdir)/config.j config.h -CONVERT_H = $(srcdir)/convert.j $(srcdir)/../convert.h -FLAGS_H = $(srcdir)/flags.j $(srcdir)/../flags.h -GLIMITS_H = $(srcdir)/glimits.j $(srcdir)/../glimits.h -HCONFIG_H = $(srcdir)/hconfig.j hconfig.h -INPUT_H = $(srcdir)/input.j $(srcdir)/../input.h -RTL_H = $(srcdir)/rtl.j $(srcdir)/../rtl.h $(srcdir)/../rtl.def \ - $(srcdir)/../machmode.h $(srcdir)/../machmode.def -TCONFIG_H = $(srcdir)/tconfig.j tconfig.h -TM_H = $(srcdir)/tm.j tm.h -TREE_H = $(srcdir)/tree.j $(srcdir)/../tree.h $(srcdir)/../real.h \ - $(srcdir)/../tree.def $(srcdir)/../machmode.h $(srcdir)/../machmode.def +ASSERT_H = $(srcdir)/f/assert.j $(srcdir)/assert.h +CONFIG_H = $(srcdir)/f/config.j config.h +CONVERT_H = $(srcdir)/f/convert.j $(srcdir)/convert.h +FLAGS_H = $(srcdir)/f/flags.j $(srcdir)/flags.h +GLIMITS_H = $(srcdir)/f/glimits.j $(srcdir)/glimits.h +HCONFIG_H = $(srcdir)/f/hconfig.j hconfig.h +INPUT_H = $(srcdir)/f/input.j $(srcdir)/input.h +RTL_H = $(srcdir)/f/rtl.j $(srcdir)/rtl.h $(srcdir)/rtl.def \ + $(srcdir)/machmode.h $(srcdir)/machmode.def +TCONFIG_H = $(srcdir)/f/tconfig.j tconfig.h +TM_H = $(srcdir)/f/tm.j tm.h +TREE_H = $(srcdir)/f/tree.j $(srcdir)/tree.h $(srcdir)/real.h \ + $(srcdir)/tree.def $(srcdir)/machmode.h $(srcdir)/machmode.def #Build the first part of this list with the command line: # cd gcc/; make deps-kinda -f f/Makefile.in @@ -471,36 +462,36 @@ f/stamp-str: f/str-1t.h f/str-1t.j f/str-2t.h f/str-2t.j \ touch f/stamp-str f/str-1t.h f/str-1t.j: f/fini f/str-1t.fin - ./f/fini `echo $(srcdir)/str-1t.fin | sed 's,^\./,,'` f/str-1t.j f/str-1t.h + ./f/fini `echo $(srcdir)/f/str-1t.fin | sed 's,^\./,,'` f/str-1t.j f/str-1t.h f/str-2t.h f/str-2t.j: f/fini f/str-2t.fin - ./f/fini `echo $(srcdir)/str-2t.fin | sed 's,^\./,,'` f/str-2t.j f/str-2t.h + ./f/fini `echo $(srcdir)/f/str-2t.fin | sed 's,^\./,,'` f/str-2t.j f/str-2t.h f/str-fo.h f/str-fo.j: f/fini f/str-fo.fin - ./f/fini `echo $(srcdir)/str-fo.fin | sed 's,^\./,,'` f/str-fo.j f/str-fo.h + ./f/fini `echo $(srcdir)/f/str-fo.fin | sed 's,^\./,,'` f/str-fo.j f/str-fo.h f/str-io.h f/str-io.j: f/fini f/str-io.fin - ./f/fini `echo $(srcdir)/str-io.fin | sed 's,^\./,,'` f/str-io.j f/str-io.h + ./f/fini `echo $(srcdir)/f/str-io.fin | sed 's,^\./,,'` f/str-io.j f/str-io.h f/str-nq.h f/str-nq.j: f/fini f/str-nq.fin - ./f/fini `echo $(srcdir)/str-nq.fin | sed 's,^\./,,'` f/str-nq.j f/str-nq.h + ./f/fini `echo $(srcdir)/f/str-nq.fin | sed 's,^\./,,'` f/str-nq.j f/str-nq.h f/str-op.h f/str-op.j: f/fini f/str-op.fin - ./f/fini `echo $(srcdir)/str-op.fin | sed 's,^\./,,'` f/str-op.j f/str-op.h + ./f/fini `echo $(srcdir)/f/str-op.fin | sed 's,^\./,,'` f/str-op.j f/str-op.h f/str-ot.h f/str-ot.j: f/fini f/str-ot.fin - ./f/fini `echo $(srcdir)/str-ot.fin | sed 's,^\./,,'` f/str-ot.j f/str-ot.h + ./f/fini `echo $(srcdir)/f/str-ot.fin | sed 's,^\./,,'` f/str-ot.j f/str-ot.h f/fini: f/fini.o f/proj-h.o $(HOST_CC) $(HOST_CFLAGS) -W -Wall $(HOST_LDFLAGS) -o f/fini f/fini.o f/proj-h.o f/fini.o: $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) \ - `echo $(srcdir)/fini.c | sed 's,^\./,,'` -o $@ + `echo $(srcdir)/f/fini.c | sed 's,^\./,,'` -o $@ f/proj-h.o: f/proj.o $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) \ - `echo $(srcdir)/proj.c | sed 's,^\./,,'` -o $@ + `echo $(srcdir)/f/proj.c | sed 's,^\./,,'` -o $@ # Other than str-*.j, the *.j files are dummy #include files # that normally just #include the corresponding back-end *.h @@ -542,7 +533,7 @@ deps-kinda: # Update the tags table. TAGS: force - cd $(srcdir) ; \ + cd $(srcdir)/f ; \ etags *.c *.h ; \ echo 'l' | tr 'l' '\f' >> TAGS ; \ echo 'parse.y,0' >> TAGS ; \ diff --git a/gnu/usr.bin/gcc/f/NEWS b/gnu/usr.bin/gcc/f/NEWS index 1ac6a81f94c..116b89a3012 100644 --- a/gnu/usr.bin/gcc/f/NEWS +++ b/gnu/usr.bin/gcc/f/NEWS @@ -6,6 +6,211 @@ notice and permission notice. News About GNU Fortran ********************** +In 0.5.20: +========== + + * The `-fno-typeless-boz' option is now the default. + + This option specifies that non-decimal-radix constants using the + prefixed-radix form (such as `Z'1234'') are to be interpreted as + `INTEGER' constants. Specify `-ftypeless-boz' to cause such + constants to be interpreted as typeless. + + (Version 0.5.19 introduced `-fno-typeless-boz' and its inverse.) + + * Options `-ff90-intrinsics-enable' and `-fvxt-intrinsics-enable' + now are the defaults. + + Some programs might use names that clash with intrinsic names + defined (and now enabled) by these options or by the new `libU77' + intrinsics. Users of such programs might need to compile them + differently (using, for example, `-ff90-intrinsics-disable') or, + better yet, insert appropriate `EXTERNAL' statements specifying + that these names are not intended to be names of intrinsics. + + * The `ALWAYS_FLUSH' macro is no longer defined when building + `libf2c', which should result in improved I/O performance, + especially over NFS. + + *Note:* If you have code that depends on the behavior of `libf2c' + when built with `ALWAYS_FLUSH' defined, you will have to modify + `libf2c' accordingly before building it from this and future + versions of `g77'. + + * Dave Love's implementation of `libU77' has been added to the + version of `libf2c' distributed with and built as part of `g77'. + `g77' now knows about the routines in this library as intrinsics. + + * New option `-fvxt' specifies that the source file is written in + VXT Fortran, instead of GNU Fortran. + + * The `-fvxt-not-f90' option has been deleted, along with its + inverse, `-ff90-not-vxt'. + + If you used one of these deleted options, you should re-read the + pertinent documentation to determine which options, if any, are + appropriate for compiling your code with this version of `g77'. + + * The `-fugly' option now issues a warning, as it likely will be + removed in a future version. + + (Enabling all the `-fugly-*' options is unlikely to be feasible, + or sensible, in the future, so users should learn to specify only + those `-fugly-*' options they really need for a particular source + file.) + + * The `-fugly-assumed' option, introduced in version 0.5.19, has + been changed to better accommodate old and new code. + + * Make a number of fixes to the `g77' front end and the `gcc' back + end to better support Alpha (AXP) machines. This includes + providing at least one bug-fix to the `gcc' back end for Alphas. + + * Related to supporting Alpha (AXP) machines, the `LOC()' intrinsic + and `%LOC()' construct now return values of integer type that is + the same width (holds the same number of bits) as the pointer type + on the machine. + + On most machines, this won't make a difference, whereas on Alphas, + the type these constructs return is `INTEGER*8' instead of the + more common `INTEGER*4'. + + * Emulate `COMPLEX' arithmetic in the `g77' front end, to avoid bugs + in `complex' support in the `gcc' back end. New option + `-fno-emulate-complex' causes `g77' to revert the 0.5.19 behavior. + + * Fix bug whereby `REAL A(1)', for example, caused a compiler crash + if `-fugly-assumed' was in effect and A was a local (automatic) + array. That case is no longer affected by the new handling of + `-fugly-assumed'. + + * Fix `g77' command driver so that `g77 -o foo.f' no longer deletes + `foo.f' before issuing other diagnostics, and so the `-x' option + is properly handled. + + * Enable inlining of subroutines and functions by the `gcc' back end. + This works as it does for `gcc' itself--program units may be + inlined for invocations that follow them in the same program unit, + as long as the appropriate compile-time options are specified. + + * Dummy arguments are no longer assumed to potentially alias + (overlap) other dummy arguments or `COMMON' areas when any of + these are defined (assigned to) by Fortran code. + + This can result in faster and/or smaller programs when compiling + with optimization enabled, though on some systems this effect is + observed only when `-fforce-addr' also is specified. + + New options `-falias-check', `-fargument-alias', + `-fargument-noalias', and `-fno-argument-noalias-global' control + the way `g77' handles potential aliasing. + + * The `CONJG()' and `DCONJG()' intrinsics now are compiled in-line. + + * The bug-fix for 0.5.19.1 has been re-done. The `g77' compiler has + been changed back to assume `libf2c' has no aliasing problems in + its implementations of the `COMPLEX' (and `DOUBLE COMPLEX') + intrinsics. The `libf2c' has been changed to have no such + problems. + + As a result, 0.5.20 is expected to offer improved performance over + 0.5.19.1, perhaps as good as 0.5.19 in most or all cases, due to + this change alone. + + *Note:* This change requires version 0.5.20 of `libf2c', at least, + when linking code produced by any versions of `g77' other than + 0.5.19.1. Use `g77 -v' to determine the version numbers of the + `libF77', `libI77', and `libU77' components of the `libf2c' + library. (If these version numbers are not printed--in + particular, if the linker complains about unresolved references to + names like `g77__fvers__'--that strongly suggests your + installation has an obsolete version of `libf2c'.) + + * New option `-fugly-assign' specifies that the same memory + locations are to be used to hold the values assigned by both + statements `I = 3' and `ASSIGN 10 TO I', for example. (Normally, + `g77' uses a separate memory location to hold assigned statement + labels.) + + * `FORMAT' and `ENTRY' statements now are allowed to precede + `IMPLICIT NONE' statements. + + * Produce diagnostic for unsupported `SELECT CASE' on `CHARACTER' + type, instead of crashing, at compile time. + + * Fix crashes involving diagnosed or invalid code. + + * Change approach to building `libf2c' archive (`libf2c.a') so that + members are added to it only when truly necessary, so the user + that installs an already-built `g77' doesn't need to have write + access to the build tree (whereas the user doing the build might + not have access to install new software on the system). + + * Support `gcc' version 2.7.2.2 (modified by `g77' into version + 2.7.2.2.f.2), and remove support for prior versions of `gcc'. + + * Upgrade to `libf2c' as of 1997-02-08, and fix up some of the build + procedures. + + * Improve general build procedures for `g77', fixing minor bugs + (such as deletion of any file named `f771' in the parent directory + of `gcc/'). + + * Enable full support of `INTEGER*8' available in `libf2c' and + `f2c.h' so that `f2c' users may make full use of its features via + the `g77' version of `f2c.h' and the `INTEGER*8' support routines + in the `g77' version of `libf2c'. + + * Improve `g77' driver and `libf2c' so that `g77 -v' yields version + information on the library. + + * The `SNGL' and `FLOAT' intrinsics now are specific intrinsics, + instead of synonyms for the generic intrinsic `REAL'. + + * New intrinsics have been added. These are `REALPART', `IMAGPART', + `COMPLEX', `LONG', and `SHORT'. + + * A new group of intrinsics, `gnu', has been added to contain the + new `REALPART', `IMAGPART', and `COMPLEX' intrinsics. An old + group, `dcp', has been removed. + + * Complain about industry-wide ambiguous references `REAL(EXPR)' and + `AIMAG(EXPR)', where EXPR is `DOUBLE COMPLEX' (or any complex type + other than `COMPLEX'), unless `-ff90' option specifies Fortran 90 + interpretation or new `-fugly-complex' option, in conjunction with + `-fnot-f90', specifies `f2c' interpretation. + + * Make improvements to diagnostics. + + * Speed up compiler a bit. + + * Improvements to documentation and indexing, including a new + chapter containing information on one, later more, diagnostics + that users are directed to pull up automatically via a message in + the diagnostic itself. + + (Hence the menu item `M' for the node `Diagnostics' in the + top-level menu of the Info documentation.) + +In 0.5.19.1: +============ + + * Code-generation bugs afflicting operations on complex data have + been fixed. + + These bugs occurred when assigning the result of an operation to a + complex variable (or array element) that also served as an input + to that operation. + + The operations affected by this bug were: `CONJG()', `DCONJG()', + `CCOS()', `CDCOS()', `CLOG()', `CDLOG()', `CSIN()', `CDSIN()', + `CSQRT()', `CDSQRT()', complex division, and raising a `DOUBLE + COMPLEX' operand to an `INTEGER' power. (The related generic and + `Z'-prefixed intrinsics, such as `ZSIN()', also were affected.) + + For example, `C = CSQRT(C)', `Z = Z/C', and `Z = Z**I' (where `C' + is `COMPLEX' and `Z' is `DOUBLE COMPLEX') have been fixed. + In 0.5.19: ========== @@ -100,7 +305,7 @@ In 0.5.18: `INTEGER*8', and their `LOGICAL' equivalents. (This support works on most, maybe all, `gcc' targets.) - Thanks to Scott Snyder (`snyder@d0sgif.fnal.gov') for providing + Thanks to Scott Snyder (<snyder@d0sgif.fnal.gov>) for providing the patch for this! Among the missing elements from the support for these features are @@ -110,7 +315,7 @@ In 0.5.18: type-declaration statements. `BYTE' corresponds to `INTEGER*1', while `WORD' corresponds to `INTEGER*2'. - Thanks to Scott Snyder (`snyder@d0sgif.fnal.gov') for providing + Thanks to Scott Snyder (<snyder@d0sgif.fnal.gov>) for providing the patch for this! * The compiler code handling intrinsics has been largely rewritten @@ -182,7 +387,7 @@ In 0.5.18: enhanced for Fortran, and N is `1' for the first Fortran patch for that version of `gcc', `2' for the second, and so on. - So, this introduces version `2.7.2.f.1' of `gcc'. + So, this introduces version 2.7.2.f.1 of `gcc'. * Make several improvements and fixes to diagnostics, including the removal of two that were inappropriate or inadequate. @@ -206,7 +411,7 @@ In 0.5.18: This effort was inspired by a first pass at translating `g77-0.5.16/f/DOC' that was contributed to Craig by David Ronis - (`ronis@onsager.chem.mcgill.ca'). + (<ronis@onsager.chem.mcgill.ca>). * New `-fno-second-underscore' option to specify that, when `-funderscoring' is in effect, a second underscore is not to be @@ -231,7 +436,7 @@ In 0.5.18: Note that the email addresses related to `f2c' have changed--the distribution site now is named `netlib.bell-labs.com', and the - maintainer's new address is `dmg@bell-labs.com'. + maintainer's new address is <dmg@bell-labs.com>. In 0.5.17: ========== @@ -443,7 +648,7 @@ In 0.5.16: `gcc/f/expr.c'. * Add warning to be printed for each invocation of the compiler if - the target machine `INTEGER', REAL, or `LOGICAL' size is not 32 + the target machine `INTEGER', `REAL', or `LOGICAL' size is not 32 bits, since `g77' is known to not work well for such cases (to be fixed in Version 0.6--*note Actual Bugs We Haven't Fixed Yet: Actual Bugs.). @@ -604,7 +809,7 @@ In 0.5.14: - Hollerith "format specifications" in the form of arrays of non-character allowed. - - Warnings issued when non-blank truncation occurs when + - Warnings issued when non-space truncation occurs when converting to another type. - When specified as actual argument, now passed by reference to @@ -615,7 +820,7 @@ In 0.5.14: *Warning:* `f2c' differs on the interpretation of `CALL FOO(1HX)', which it treats exactly the same as `CALL FOO('X')', but which the standard and `g77' treat as `CALL FOO(%REF('X '))' (padded with - as many blanks as necessary to widen to `INTEGER'), essentially. + as many spaces as necessary to widen to `INTEGER'), essentially. * Changes and fixes to typeless-constant support: @@ -660,5 +865,5 @@ In 0.5.14: * Generate better code for some kinds of array references. * Speed up lexing somewhat (this makes the compilation phase - noticably faster). + noticeably faster). diff --git a/gnu/usr.bin/gcc/f/PROJECTS b/gnu/usr.bin/gcc/f/PROJECTS deleted file mode 100644 index 4e863c58f6f..00000000000 --- a/gnu/usr.bin/gcc/f/PROJECTS +++ /dev/null @@ -1,5 +0,0 @@ -THIS FILE HAS BEEN OBSOLETED in the GNU Fortran distribution as -of version 0.5.18. It will be removed in a future distribution. - -Its contents have been assimilated into the Info documentation, -the source to which is in gcc/f/g77.texi. diff --git a/gnu/usr.bin/gcc/f/README.NEXTSTEP b/gnu/usr.bin/gcc/f/README.NEXTSTEP deleted file mode 100644 index 6ea24ac89f2..00000000000 --- a/gnu/usr.bin/gcc/f/README.NEXTSTEP +++ /dev/null @@ -1,6 +0,0 @@ -THIS FILE HAS BEEN OBSOLETED in the GNU Fortran distribution as -of version 0.5.18. It will be removed in a future distribution. - -Its contents have been assimilated into the Info documentation, -the source to which is in gcc/f/g77.texi. In particular, see -the node ``(g77)But-bugs''. diff --git a/gnu/usr.bin/gcc/f/bad.def b/gnu/usr.bin/gcc/f/bad.def index 4fc20eccec2..ce2866dcdc8 100644 --- a/gnu/usr.bin/gcc/f/bad.def +++ b/gnu/usr.bin/gcc/f/bad.def @@ -1,5 +1,5 @@ /* bad.def -- Public #include File (module.h template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995-1997 Free Software Foundation, Inc. Contributed by James Craig Burley (burley@gnu.ai.mit.edu). This file is part of GNU Fortran. @@ -172,9 +172,6 @@ FFEBAD_MSGS1 (FFEBAD_SEMICOLON, FATAL, FFEBAD_MSGS2 (FFEBAD_UNREC_STMT, FATAL, "Unrecognized statement name at %0 and invalid form for assignment or statement-function definition at %1", "Invalid statement at %0") -FFEBAD_MSGS2 (FFEBAD_UNIMPL_STMT, FATAL, -"Unimplemented or invalid form of statement at %0 (this is a catchall diagnostic that currently applies to a wide variety of errors, including things like invalid ordering of statements and invalid reference to intrinsic procedure)", -"Invalid statement at %0") FFEBAD_MSGS2 (FFEBAD_INVALID_STMT_FORM, FATAL, "Invalid form for %A statement at %0", "Invalid %A statement at %0") @@ -488,29 +485,34 @@ FFEBAD_MSGS2 (FFEBAD_RELOP_ARG_KIND, FATAL, "Relational operator at %0 must operate on two scalar (not array) subexpressions, two function invocations returning integer, real, or character scalars, or a combination of both -- but the subexpression at %1 is %A", "Invalid operand (is %A) at %1 for relational operator at %0") FFEBAD_MSGS2 (FFEBAD_INTRINSIC_REF, FATAL, -"Reference to intrinsic function or subroutine `%A' at %0 invalid -- number or nature of arguments incorrect", -"Invalid reference to intrinsic `%A' at %0") +"Reference to intrinsic %A at %0 invalid -- one or more arguments have incorrect type", +"Invalid reference to intrinsic %A at %0") FFEBAD_MSGS2 (FFEBAD_INTRINSIC_TOOFEW, FATAL, -"Too few arguments passed to intrinsic function or subroutine `%A' at %0", -"Too few arguments for intrinsic `%A' at %0") +"Too few arguments passed to intrinsic %A at %0", +"Too few arguments for intrinsic %A at %0") FFEBAD_MSGS2 (FFEBAD_INTRINSIC_TOOMANY, FATAL, -"Too many arguments passed to intrinsic function or subroutine `%A' at %0", -"Too many arguments for intrinsic `%A' at %0") +"Too many arguments passed to intrinsic %A at %0", +"Too many arguments for intrinsic %A at %0") FFEBAD_MSGS2 (FFEBAD_INTRINSIC_DISABLED, FATAL, -"Reference to disabled intrinsic function or subroutine `%A' at %0", -"Disabled intrinsic `%A' at %0") +"Reference to disabled intrinsic %A at %0", +"Disabled intrinsic %A at %0") FFEBAD_MSGS2 (FFEBAD_INTRINSIC_IS_SUBR, FATAL, -"Reference to intrinsic subroutine `%A' as if it were a function at %0", -"Function reference to intrinsic subroutine `%A' at %0") +"Reference to intrinsic subroutine %A as if it were a function at %0", +"Function reference to intrinsic subroutine %A at %0") FFEBAD_MSGS2 (FFEBAD_INTRINSIC_IS_FUNC, FATAL, -"Reference to intrinsic function `%A' as if it were a subroutine at %0", -"Subroutine reference to intrinsic function `%A' at %0") +"Reference to intrinsic function %A as if it were a subroutine at %0", +"Subroutine reference to intrinsic function %A at %0") FFEBAD_MSGS2 (FFEBAD_INTRINSIC_UNIMPL, FATAL, -"Reference to unimplemented intrinsic procedure `%A' at %0 -- use EXTERNAL to reference non-intrinsic procedure with this name", -"Unimplemented intrinsic `%A' at %0") +"Reference to unimplemented intrinsic %A at %0 -- use EXTERNAL to reference user-written procedure with this name", +"Unimplemented intrinsic %A at %0") +FFEBAD_MSGS2 (FFEBAD_INTRINSIC_UNIMPLW, WARN, +"Reference to unimplemented intrinsic %A at %0 (assumed EXTERNAL)", +"Unimplemented intrinsic %A at %0 (assumed EXTERNAL)") FFEBAD_MSGS2 (FFEBAD_INTRINSIC_AMBIG, FATAL, -"Reference to generic intrinsic procedure `%A' at %0 could be for specific intrinsic procedure `%B' or `%C'", -"Ambiguous reference to generic intrinsic `%A' at %0") +"Reference to generic intrinsic %A at %0 could be for specific intrinsic %B or %C", +"Ambiguous reference to generic intrinsic %A (could be %B or %C) at %0") +FFEBAD_MSGS1 (FFEBAD_INTRINSIC_CMPAMBIG, FATAL, +"Ambiguous use of intrinsic %A at %0 [info -f g77 M CMPAMBIG]") FFEBAD_MSGS1 (FFEBAD_OPEN_INCLUDE, FATAL, "Unable to open INCLUDE file `%A' at %0") FFEBAD_MSGS2 (FFEBAD_DOITER, FATAL, @@ -618,7 +620,7 @@ FFEBAD_MSGS2 (FFEBAD_COMMON_ENLARGED, FATAL, FFEBAD_MSGS1 (FFEBAD_COMMON_BLANK_INIT, WARN, "Blank common initialized at %0") FFEBAD_MSGS1 (FFEBAD_NEED_INTRINSIC, WARN, -"Intrinsic procedure `%A' is passed as actual argument at %0 but not explicitly declared INTRINSIC") +"Intrinsic %A is passed as actual argument at %0 but not explicitly declared INTRINSIC") FFEBAD_MSGS1 (FFEBAD_NEED_EXTERNAL, WARN, "External procedure `%A' is passed as actual argument at %0 but not explicitly declared EXTERNAL") FFEBAD_MSGS1 (FFEBAD_SYMBOL_UPPER_CASE, WARN, @@ -647,8 +649,6 @@ FFEBAD_MSGS2 (FFEBAD_TOO_BIG_INIT, WARN, "This could take a while (initializing `%A' at %0)...") FFEBAD_MSGS1 (FFEBAD_BLOCKDATA_STMT, WARN, "Statement at %0 invalid in BLOCK DATA program unit at %1") -FFEBAD_MSGS1 (FFEBAD_TYPELESS_TOO_LARGE, WARN, -"Typeless constant at %0 too large") FFEBAD_MSGS1 (FFEBAD_TRUNCATING_CHARACTER, WARN, "Truncating characters on right side of character constant at %0") FFEBAD_MSGS1 (FFEBAD_TRUNCATING_HOLLERITH, WARN, diff --git a/gnu/usr.bin/gcc/f/bld.c b/gnu/usr.bin/gcc/f/bld.c index 63fe91d678a..3a95727adc1 100644 --- a/gnu/usr.bin/gcc/f/bld.c +++ b/gnu/usr.bin/gcc/f/bld.c @@ -1,5 +1,5 @@ /* bld.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995, 1996 Free Software Foundation, Inc. Contributed by James Craig Burley (burley@gnu.ai.mit.edu). This file is part of GNU Fortran. @@ -1067,7 +1067,7 @@ ffebld_constant_is_zero (ffebldConstant c) #endif #if FFETARGET_okCHARACTER2 || FFETARGET_okCHARACTER3 /* ... */ -#error no support for these!! +#error "no support for these!!" #endif case FFEBLD_constHOLLERITH: @@ -2007,6 +2007,7 @@ ffebld_constantarray_dump (ffebldConstantArray array, ffeinfoBasictype bt, ffeinfoKindtype kt, ffetargetOffset size, ffebit bits) { ffetargetOffset i; + ffebitCount j; ffebld_dump_prefix (dmpout, bt, kt); @@ -2038,12 +2039,12 @@ ffebld_constantarray_dump (ffebldConstantArray array, ffeinfoBasictype bt, else fprintf (dmpout, "[%" ffetargetOffset_f "u..%" ffetargetOffset_f "d]:", - offset, offset + length - 1); - for (i = 0; i < length; ++i, ++offset) + offset, offset + (ffetargetOffset) length - 1); + for (j = 0; j < length; ++j, ++offset) { ffebld_constantunion_dump (ffebld_constantarray_get (array, bt, kt, offset), bt, kt); - if (i != length - 1) + if (j != length - 1) fputc (',', dmpout); } fprintf (dmpout, ";"); diff --git a/gnu/usr.bin/gcc/f/bld.h b/gnu/usr.bin/gcc/f/bld.h index 7e77c1e26cb..a9dbe9f2e03 100644 --- a/gnu/usr.bin/gcc/f/bld.h +++ b/gnu/usr.bin/gcc/f/bld.h @@ -1,5 +1,5 @@ /* bld.h -- Public #include File (module.h template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995, 1996 Free Software Foundation, Inc. Contributed by James Craig Burley (burley@gnu.ai.mit.edu). This file is part of GNU Fortran. diff --git a/gnu/usr.bin/gcc/f/bugs.texi b/gnu/usr.bin/gcc/f/bugs.texi index 4feeab0d0ca..35df036727a 100644 --- a/gnu/usr.bin/gcc/f/bugs.texi +++ b/gnu/usr.bin/gcc/f/bugs.texi @@ -1,11 +1,11 @@ -@c Copyright (C) 1995, 1996 Free Software Foundation, Inc. +@c Copyright (C) 1995-1997 Free Software Foundation, Inc. @c This is part of the G77 manual. @c For copying conditions, see the file g77.texi. @c The text of this file appears in the file BUGS @c in the G77 distribution, as well as in the G77 manual. -@c 1996-11-27 +@c 1996-02-24 @ifclear BUGSONLY @node Actual Bugs @@ -25,12 +25,19 @@ configure, port, build, and install @code{g77}, @ref{Problems Installing}. @itemize @bullet -@cindex -fugly option -@cindex options, -fugly +@cindex SIGNAL() intrinsic +@cindex intrinsics, SIGNAL() @item -When using @samp{-fugly}, @code{g77} assumes an extra +Work is needed on the @code{SIGNAL()} intrinsic to ensure +that pointers and integers are properly handled on all +targets, including 64-bit machines. + +@cindex -fugly-comma option +@cindex options, -fugly-comma +@item +When using @samp{-fugly-comma}, @code{g77} assumes an extra @samp{%VAL(0)} argument is to be passed to intrinsics -taking no arguments, such as @samp{IARGC()}, which in +taking no arguments, such as @code{IARGC()}, which in turn reject such a call. Although this has been worked around for 0.5.18 due to changes in the handling of intrinsics, @@ -40,29 +47,11 @@ probably be more consistent with compilers that default to using that trick. @item -Although @code{g77} generally supports @samp{SELECT CASE}, -it doesn't do so for @samp{CHARACTER} types. -Worse, it just crashes with a barely servicable -diagnostic. -If the time can't be taken soon to finish implementing -this feature, at least a better way of diagnosing -the problem should be provided. - -@item -To accept a lot of fine code, @code{g77} needs to -accept @samp{FORMAT} and @samp{ENTRY} before an -@samp{IMPLICIT NONE}. - -@item -Some crashes occur when compiling under Solaris on x86 -machines. - -@item Something about @code{g77}'s straightforward handling of label references and definitions sometimes prevents the GBE from unrolling loops. -Until this is solved, try inserting or removing @samp{CONTINUE} -statements as the terminal statement, using the @samp{END DO} +Until this is solved, try inserting or removing @code{CONTINUE} +statements as the terminal statement, using the @code{END DO} form instead, and so on. @item @@ -72,20 +61,16 @@ For example, @code{gcc} accepts abbreviated forms of long options, @code{g77} generally doesn't. @item -Some confusion in diagnostics concerning failing @samp{INCLUDE} -statements from within @samp{INCLUDE}'d or @samp{#include}'d files. - -@item -Some problems on RS/6000 regarding statement functions and/or -@samp{COMPLEX} arithmetic? +Some confusion in diagnostics concerning failing @code{INCLUDE} +statements from within @code{INCLUDE}'d or @code{#include}'d files. @cindex integer constants @cindex constants, integer @item -@code{g77} assumes that @samp{INTEGER} constants range +@code{g77} assumes that @code{INTEGER(KIND=1)} constants range from @samp{-2**31} to @samp{2**31-1} (the range for two's-complement 32-bit values), -instead of determining their range from the actual range of the @samp{INTEGER} +instead of determining their range from the actual range of the type for the configuration (and, someday, for the constant). Further, it generally doesn't implement the handling @@ -167,14 +152,33 @@ main program unit is activated and about to execute its first executable statement, but that's the state in which the debugger should start up, as is the case for languages like C. +@cindex debugger +@item +Debugging @code{g77}-compiled code using debuggers other than +@code{gdb} is likely not to work. + +Getting @code{g77} and @code{gdb} to work together is a known +problem---getting @code{g77} to work properly with other +debuggers, for which source code often is unavailable to @code{g77} +developers, seems like a much larger, unknown problem, +and is a lower priority than making @code{g77} and @code{gdb} +work together properly. + +On the other hand, information about problems other debuggers +have with @code{g77} output might make it easier to properly +fix @code{g77}, and perhaps even improve @code{gdb}, so it +is definitely welcome. +Such information might even lead to all relevant products +working together properly sooner. + @cindex padding @cindex structures @cindex common blocks @cindex equivalence areas @item @code{g77} currently inserts needless padding for things like -@samp{COMMON A,IPAD} where @samp{A} is @samp{CHARACTER*1} and @samp{IPAD} -is @samp{INTEGER*4} on machines like x86, because +@samp{COMMON A,IPAD} where @samp{A} is @code{CHARACTER*1} and @samp{IPAD} +is @code{INTEGER(KIND=1)} on machines like x86, because the back end insists that @samp{IPAD} be aligned to a 4-byte boundary, but the processor has no such requirement (though it's good for performance). @@ -187,6 +191,15 @@ is the potential, with the current setup, for interface differences in the way such areas are laid out between @code{g77} and other compilers. +@item +Some crashes occur when compiling under Solaris on x86 +machines. + +Nothing has been heard about any such problems for some time, +so this is considering a closed item as of 0.5.20. +Please submit any bug reports pertinent to @code{g77}'s support +for Solaris/x86 systems. + @cindex RS/6000 support @cindex support, RS/6000 @item @@ -197,6 +210,11 @@ likely to be a code-generation bug in @file{gcc-2.7.0} plus @file{g77-0.5.16}. This problem shows up only when compiling the Fortran program with @samp{-O}. +Nothing has been heard about any RS/6000 problems for some time, +so this is considering a closed item as of 0.5.20. +Please submit any bug reports pertinent to @code{g77}'s support +for RS/6000 systems. + @cindex SGI support @cindex support, SGI @item @@ -204,29 +222,50 @@ SGI support is known to be a bit buggy. The known problem shows up only when compiling the Fortran program with @samp{-O}. -@cindex Alpha support +It is possible these problems have all been fixed in 0.5.20 by +emulating complex arithmetic in the front end. +Please submit any bug reports pertinent to @code{g77}'s support +for SGI systems. + +@cindex Alpha, support @cindex support, Alpha @item -@code{g77} doesn't work on 64-bit configurations such as the Alpha. +@code{g77} doesn't work perfectly on 64-bit configurations such as the Alpha. This problem is expected to be largely resolved as of version 0.5.20, and version 0.6 should solve most or all related problems (such as 64-bit machines other than DEC Alphas). +One known bug that causes a compile-time crash occurs when compiling +code such as the following with optimization: + +@example +SUBROUTINE CRASH (TEMP) +INTEGER*2 HALF(2) +REAL TEMP +HALF(1) = NINT (TEMP) +END +@end example + +It is expected that a future version of @code{g77} will have a fix for this +problem, almost certainly by the time @code{g77} supports the forthcoming +version 2.8.0 of @code{gcc}. + @cindex COMPLEX support @cindex support, COMPLEX @item Maintainers of gcc report that the back end definitely has ``broken'' -support for @samp{COMPLEX} types. +support for @code{COMPLEX} types. Based on their input, it seems many of the problems affect only the more-general facilities for gcc's -@samp{__complex__} type, such as @samp{__complex__ int} +@code{__complex__} type, such as @code{__complex__ int} (where the real and imaginary parts are integers) that GNU Fortran does not use. -Version 0.5.20 of @code{g77} is expected to work around this -problem by not using the back end's support for @samp{COMPLEX}. -This work has already been done, and is being tested by -developers. +Version 0.5.20 of @code{g77} works around this +problem by not using the back end's support for @code{COMPLEX}. +The new option @samp{-fno-emulate-complex} avoids the work-around, +reverting to using the same ``broken'' mechanism as that used +by versions of @code{g77} prior to 0.5.20. @cindex ELF support @cindex support, ELF @@ -242,7 +281,5 @@ More investigation is needed, but the problem is almost certainly in the gcc back end, and it apparently occurs only when compiling sufficiently complicated functions @emph{without} the @samp{-O} option. - -This might be fixed in version 2.7.2 of @code{gcc}. @end itemize diff --git a/gnu/usr.bin/gcc/f/com-rt.def b/gnu/usr.bin/gcc/f/com-rt.def index dae8b2a864f..e32cce03c53 100644 --- a/gnu/usr.bin/gcc/f/com-rt.def +++ b/gnu/usr.bin/gcc/f/com-rt.def @@ -1,5 +1,5 @@ /* com-rt.def -- Public #include File (module.h template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995-1997 Free Software Foundation, Inc. Contributed by James Craig Burley (burley@gnu.ai.mit.edu). This file is part of GNU Fortran. @@ -108,6 +108,7 @@ DEFGFRT (FFECOM_gfrtFREW, "f_rew", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) DEFGFRT (FFECOM_gfrtABORT, "abort_", FFECOM_rttypeVOID_, 0, TRUE, FALSE) DEFGFRT (FFECOM_gfrtABS, "r_abs", FFECOM_rttypeDOUBLE_, "&f", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtACCESS, "access_", FFECOM_rttypeINTEGER_, "&a&a", FALSE, FALSE) DEFGFRT (FFECOM_gfrtACOS, "r_acos", FFECOM_rttypeDOUBLE_, "&f", FALSE, FALSE) DEFGFRT (FFECOM_gfrtAIMAG, "r_imag", FFECOM_rttypeDOUBLE_, "&f", FALSE, FALSE) DEFGFRT (FFECOM_gfrtAINT, "r_int", FFECOM_rttypeDOUBLE_, "&f", FALSE, FALSE) @@ -118,27 +119,43 @@ DEFGFRT (FFECOM_gfrtANINT, "r_nint", FFECOM_rttypeDOUBLE_, "&f", FALSE, FALSE) DEFGFRT (FFECOM_gfrtASIN, "r_asin", FFECOM_rttypeDOUBLE_, "&f", FALSE, FALSE) DEFGFRT (FFECOM_gfrtATAN, "r_atan", FFECOM_rttypeDOUBLE_, "&f", FALSE, FALSE) DEFGFRT (FFECOM_gfrtATAN2, "r_atn2", FFECOM_rttypeDOUBLE_, "&f", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtBESJ0, "j0", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtBESJ1, "j1", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtBESJN, "jn", FFECOM_rttypeDOUBLE_, "id", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtBESY0, "y0", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtBESY1, "y1", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtBESYN, "yn", FFECOM_rttypeDOUBLE_, "id", FALSE, FALSE) DEFGFRT (FFECOM_gfrtCABS, "c_abs", FFECOM_rttypeDOUBLE_, "&c", FALSE, FALSE) DEFGFRT (FFECOM_gfrtCCOS, "c_cos", FFECOM_rttypeCOMPLEX_, "&c", FALSE, TRUE) DEFGFRT (FFECOM_gfrtCEXP, "c_exp", FFECOM_rttypeCOMPLEX_, "&c", FALSE, TRUE) +DEFGFRT (FFECOM_gfrtCHDIR, "chdir_", FFECOM_rttypeINTEGER_, "&a", FALSE, FALSE) DEFGFRT (FFECOM_gfrtCLOG, "c_log", FFECOM_rttypeCOMPLEX_, "&c", FALSE, TRUE) +DEFGFRT (FFECOM_gfrtCHMOD, "chmod_", FFECOM_rttypeINTEGER_, "&a&a", FALSE, FALSE) DEFGFRT (FFECOM_gfrtCONJG, "r_cnjg", FFECOM_rttypeCOMPLEX_, "&c", FALSE, TRUE) DEFGFRT (FFECOM_gfrtCOS, "r_cos", FFECOM_rttypeDOUBLE_, "&f", FALSE, FALSE) DEFGFRT (FFECOM_gfrtCOSH, "r_cosh", FFECOM_rttypeDOUBLE_, "&f", FALSE, FALSE) DEFGFRT (FFECOM_gfrtCSIN, "c_sin", FFECOM_rttypeCOMPLEX_, "&c", FALSE, TRUE) DEFGFRT (FFECOM_gfrtCSQRT, "c_sqrt", FFECOM_rttypeCOMPLEX_, "&c", FALSE, TRUE) +DEFGFRT (FFECOM_gfrtCTIME, "ctime_", FFECOM_rttypeCHARACTER_, "j", FALSE, FALSE) DEFGFRT (FFECOM_gfrtDABS, "d_abs", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) DEFGFRT (FFECOM_gfrtDACOS, "d_acos", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) DEFGFRT (FFECOM_gfrtDASIN, "d_asin", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) DEFGFRT (FFECOM_gfrtDATAN, "d_atan", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) DEFGFRT (FFECOM_gfrtDATAN2, "d_atn2", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtDATE, "date_", FFECOM_rttypeVOID_, "&a", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtDBESJ0, "j0", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtDBESJ1, "j1", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtDBESJN, "jn", FFECOM_rttypeDOUBLE_, "id", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtDBESY0, "y0", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtDBESY1, "y1", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtDBESYN, "yn", FFECOM_rttypeDOUBLE_, "id", FALSE, FALSE) DEFGFRT (FFECOM_gfrtDCOS, "d_cos", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) DEFGFRT (FFECOM_gfrtDCOSH, "d_cosh", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) DEFGFRT (FFECOM_gfrtDDIM, "d_dim", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) DEFGFRT (FFECOM_gfrtDERF, "derf_", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) DEFGFRT (FFECOM_gfrtDERFC, "derfc_", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) DEFGFRT (FFECOM_gfrtDEXP, "d_exp", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtDIM, "r_dim", FFECOM_rttypeDOUBLE_, "&r", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtDIM, "r_dim", FFECOM_rttypeDOUBLE_, "&f", FALSE, FALSE) DEFGFRT (FFECOM_gfrtDINT, "d_int", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) DEFGFRT (FFECOM_gfrtDLOG, "d_log", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) DEFGFRT (FFECOM_gfrtDLOG10, "d_lg10", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) @@ -151,36 +168,81 @@ DEFGFRT (FFECOM_gfrtDSINH, "d_sinh", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) DEFGFRT (FFECOM_gfrtDSQRT, "d_sqrt", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) DEFGFRT (FFECOM_gfrtDTAN, "d_tan", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) DEFGFRT (FFECOM_gfrtDTANH, "d_tanh", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtERF, "erf_", FFECOM_rttypeDOUBLE_, "&r", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtERFC, "erfc_", FFECOM_rttypeDOUBLE_, "&r", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtDTIME, "dtime_", FFECOM_rttypeDOUBLE_, "&f", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtERF, "erf_", FFECOM_rttypeDOUBLE_, "&f", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtERFC, "erfc_", FFECOM_rttypeDOUBLE_, "&f", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtETIME, "etime_", FFECOM_rttypeDOUBLE_, "&f", FALSE, FALSE) DEFGFRT (FFECOM_gfrtEXIT, "exit_", FFECOM_rttypeVOID_, "&i", TRUE, FALSE) -DEFGFRT (FFECOM_gfrtEXP, "r_exp", FFECOM_rttypeDOUBLE_, "&r", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtEXP, "r_exp", FFECOM_rttypeDOUBLE_, "&f", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtFDATE, "fdate_", FFECOM_rttypeCHARACTER_, 0, FALSE, FALSE) +DEFGFRT (FFECOM_gfrtFGET, "fget_", FFECOM_rttypeINTEGER_, "&a", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtFGETC, "fgetc_", FFECOM_rttypeINTEGER_, "&i&a", FALSE, FALSE) DEFGFRT (FFECOM_gfrtFLUSH, "flush_", FFECOM_rttypeVOID_, 0, FALSE, FALSE) +DEFGFRT (FFECOM_gfrtFLUSH1, "flush1_", FFECOM_rttypeVOID_, "&i", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtFNUM, "fnum_", FFECOM_rttypeINTEGER_, "&i", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtFPUT, "fput_", FFECOM_rttypeINTEGER_, "&a", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtFPUTC, "fputc_", FFECOM_rttypeINTEGER_, "&i&a", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtFSTAT, "fstat_", FFECOM_rttypeINTEGER_, "&i&", FALSE, FALSE) DEFGFRT (FFECOM_gfrtFTELL, "ftell_", FFECOM_rttypeINTEGER_, "&i", FALSE, FALSE) DEFGFRT (FFECOM_gfrtFSEEK, "fseek_", FFECOM_rttypeINTEGER_, "&i&i&i", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtGERROR, "gerror_", FFECOM_rttypeVOID_, "&a", FALSE, FALSE) DEFGFRT (FFECOM_gfrtGETARG, "getarg_", FFECOM_rttypeVOID_, "&i&a", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtGETCWD, "getcwd_", FFECOM_rttypeINTEGER_, "&a", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtGETGID, "getgid_", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) +DEFGFRT (FFECOM_gfrtGETLOG, "getlog_", FFECOM_rttypeVOID_, "&a", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtGETPID, "getpid_", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) +DEFGFRT (FFECOM_gfrtGETUID, "getuid_", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) DEFGFRT (FFECOM_gfrtGETENV, "getenv_", FFECOM_rttypeVOID_, "&a&a", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtGMTIME, "gmtime_", FFECOM_rttypeVOID_, "&i&i", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtHOSTNM, "hostnm_", FFECOM_rttypeINTEGER_, "&a", FALSE, FALSE) DEFGFRT (FFECOM_gfrtIABS, "i_abs", FFECOM_rttypeINTEGER_, "&i", FALSE, FALSE) DEFGFRT (FFECOM_gfrtIARGC, "iargc_", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) +DEFGFRT (FFECOM_gfrtIDATE, "idate_", FFECOM_rttypeVOID_, "&i", FALSE, FALSE) DEFGFRT (FFECOM_gfrtIDIM, "i_dim", FFECOM_rttypeINTEGER_, "&i", FALSE, FALSE) DEFGFRT (FFECOM_gfrtIDNINT, "i_dnnt", FFECOM_rttypeINTEGER_, "&i", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtIERRNO, "ierrno_", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) DEFGFRT (FFECOM_gfrtINDEX, "i_indx", FFECOM_rttypeINTEGER_, "&a&a", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtIRAND, "irand_", FFECOM_rttypeINTEGER_, "&i", FALSE, FALSE) DEFGFRT (FFECOM_gfrtISIGN, "i_sign", FFECOM_rttypeINTEGER_, "&i", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtISATTY, "isatty_", FFECOM_rttypeINTEGER_, "&i", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtITIME, "itime_", FFECOM_rttypeVOID_, "&i", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtKILL, "kill_", FFECOM_rttypeINTEGER_, "&i&i", FALSE, FALSE) DEFGFRT (FFECOM_gfrtLEN, "i_len", FFECOM_rttypeINTEGER_, "&a", FALSE, FALSE) DEFGFRT (FFECOM_gfrtLGE, "l_ge", FFECOM_rttypeLOGICAL_, "&a", FALSE, FALSE) DEFGFRT (FFECOM_gfrtLGT, "l_gt", FFECOM_rttypeLOGICAL_, "&a", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtLINK, "link_", FFECOM_rttypeINTEGER_, "&a&a", FALSE, FALSE) DEFGFRT (FFECOM_gfrtLLE, "l_le", FFECOM_rttypeLOGICAL_, "&a", FALSE, FALSE) DEFGFRT (FFECOM_gfrtLLT, "l_lt", FFECOM_rttypeLOGICAL_, "&a", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtLNBLNK, "lnblnk_", FFECOM_rttypeINTEGER_, "&a", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtLSTAT, "lstat_", FFECOM_rttypeINTEGER_, "&a&i", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtLTIME, "ltime_", FFECOM_rttypeVOID_, "&i&i", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtMCLOCK, "mclock_", FFECOM_rttypeLONGINT_, 0, FALSE, FALSE) DEFGFRT (FFECOM_gfrtMOD, "i_mod", FFECOM_rttypeINTEGER_, "&i", FALSE, FALSE) DEFGFRT (FFECOM_gfrtNINT, "i_nint", FFECOM_rttypeINTEGER_, "&i", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtSIGN, "r_sign", FFECOM_rttypeDOUBLE_, "&r", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtPERROR, "perror_", FFECOM_rttypeVOID_, "&a", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtRAND, "rand_", FFECOM_rttypeDOUBLE_, "&i", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtRENAME, "rename_", FFECOM_rttypeINTEGER_, "&a&a", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtSECNDS, "secnds_", FFECOM_rttypeDOUBLE_, "&f", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtSECOND, "second_", FFECOM_rttypeDOUBLE_, 0, FALSE, FALSE) +DEFGFRT (FFECOM_gfrtSIGN, "r_sign", FFECOM_rttypeDOUBLE_, "&f", FALSE, FALSE) DEFGFRT (FFECOM_gfrtSIGNAL, "signal_", FFECOM_rttypeINTEGER_, "&i0", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtSIN, "r_sin", FFECOM_rttypeDOUBLE_, "&r", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtSINH, "r_sinh", FFECOM_rttypeDOUBLE_, "&r", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtSQRT, "r_sqrt", FFECOM_rttypeDOUBLE_, "&r", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtSIN, "r_sin", FFECOM_rttypeDOUBLE_, "&f", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtSINH, "r_sinh", FFECOM_rttypeDOUBLE_, "&f", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtSLEEP, "sleep_", FFECOM_rttypeVOID_, "&i", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtSQRT, "r_sqrt", FFECOM_rttypeDOUBLE_, "&f", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtSRAND, "srand_", FFECOM_rttypeVOID_, "&i", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtSTAT, "stat_", FFECOM_rttypeINTEGER_, "&a&i", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtSYMLNK, "symlnk_", FFECOM_rttypeINTEGER_, "&a&a", FALSE, FALSE) DEFGFRT (FFECOM_gfrtSYSTEM, "system_", FFECOM_rttypeINTEGER_, "&a", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtTAN, "r_tan", FFECOM_rttypeDOUBLE_, "&r", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtTANH, "r_tanh", FFECOM_rttypeDOUBLE_, "&r", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtSYSTEM_CLOCK, "system_clock_", FFECOM_rttypeVOID_, "&i&i&i", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtTAN, "r_tan", FFECOM_rttypeDOUBLE_, "&f", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtTANH, "r_tanh", FFECOM_rttypeDOUBLE_, "&f", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtTIME, "time_", FFECOM_rttypeLONGINT_, 0, FALSE, FALSE) +DEFGFRT (FFECOM_gfrtTTYNAM, "ttynam_", FFECOM_rttypeCHARACTER_, "i", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtUNLINK, "unlink_", FFECOM_rttypeINTEGER_, "&a", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtUMASK, "umask_", FFECOM_rttypeINTEGER_, "&i", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtVXTIDATE, "vxtidate_", FFECOM_rttypeVOID_, "&i&i&i", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtVXTTIME, "vxttime_", FFECOM_rttypeVOID_, "&a", FALSE, FALSE) DEFGFRT (FFECOM_gfrtCDABS, "z_abs", FFECOM_rttypeDOUBLE_, "&e", FALSE, FALSE) DEFGFRT (FFECOM_gfrtCDCOS, "z_cos", FFECOM_rttypeDBLCMPLX_, "&e", FALSE, TRUE) DEFGFRT (FFECOM_gfrtCDEXP, "z_exp", FFECOM_rttypeDBLCMPLX_, "&e", FALSE, TRUE) @@ -212,7 +274,7 @@ DEFGFRT (FFECOM_gfrtPOW_DD, "pow_dd", FFECOM_rttypeDOUBLE_, "&d&d", FALSE, FALSE DEFGFRT (FFECOM_gfrtPOW_DI, "pow_di", FFECOM_rttypeDOUBLE_, "&d&i", FALSE, FALSE) DEFGFRT (FFECOM_gfrtPOW_II, "pow_ii", FFECOM_rttypeINTEGER_, "&i", FALSE, FALSE) DEFGFRT (FFECOM_gfrtPOW_QQ, "pow_qq", FFECOM_rttypeLONGINT_, "&j&j", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtPOW_RI, "pow_ri", FFECOM_rttypeDOUBLE_, "&r&i", FALSE, FALSE) +DEFGFRT (FFECOM_gfrtPOW_RI, "pow_ri", FFECOM_rttypeDOUBLE_, "&f&i", FALSE, FALSE) DEFGFRT (FFECOM_gfrtPOW_ZI, "pow_zi", FFECOM_rttypeDBLCMPLX_, "&e&i", FALSE, TRUE) DEFGFRT (FFECOM_gfrtPOW_ZZ, "pow_zz", FFECOM_rttypeDBLCMPLX_, "&e&e", FALSE, TRUE) DEFGFRT (FFECOM_gfrtDIV_CC, "c_div", FFECOM_rttypeCOMPLEX_, "&c", FALSE, TRUE) diff --git a/gnu/usr.bin/gcc/f/com.c b/gnu/usr.bin/gcc/f/com.c index e6661c6b53a..f1f3a50c799 100644 --- a/gnu/usr.bin/gcc/f/com.c +++ b/gnu/usr.bin/gcc/f/com.c @@ -1,5 +1,5 @@ /* com.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995-1997 Free Software Foundation, Inc. Contributed by James Craig Burley (burley@gnu.ai.mit.edu). This file is part of GNU Fortran. @@ -302,11 +302,15 @@ ffecomSymbol ffecom_symbol_null_ NULL_TREE, NULL_TREE, }; +ffeinfoKindtype ffecom_pointer_kind_ = FFEINFO_basictypeNONE; +ffeinfoKindtype ffecom_label_kind_ = FFEINFO_basictypeNONE; int ffecom_f2c_typecode_[FFEINFO_basictype][FFEINFO_kindtype]; tree ffecom_f2c_integer_type_node; +tree ffecom_f2c_ptr_to_integer_type_node; tree ffecom_f2c_address_type_node; tree ffecom_f2c_real_type_node; +tree ffecom_f2c_ptr_to_real_type_node; tree ffecom_f2c_doublereal_type_node; tree ffecom_f2c_complex_type_node; tree ffecom_f2c_doublecomplex_type_node; @@ -350,6 +354,7 @@ typedef enum FFECOM_rttypeDOUBLE_, /* C's `double' type. */ FFECOM_rttypeDOUBLEREAL_, FFECOM_rttypeDBLCMPLX_, + FFECOM_rttypeCHARACTER_, /* f2c `char *'/`ftnlen' pair. */ FFECOM_rttype_ } ffecomRttype_; @@ -749,6 +754,210 @@ static tree shadowed_labels; #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */ +/* This is like gcc's stabilize_reference -- in fact, most of the code + comes from that -- but it handles the situation where the reference + is going to have its subparts picked at, and it shouldn't change + (or trigger extra invocations of functions in the subtrees) due to + this. save_expr is a bit overzealous, because we don't need the + entire thing calculated and saved like a temp. So, for DECLs, no + change is needed, because these are stable aggregates, and ARRAY_REF + and such might well be stable too, but for things like calculations, + we do need to calculate a snapshot of a value before picking at it. */ + +#if FFECOM_targetCURRENT == FFECOM_targetGCC +tree +ffecom_stabilize_aggregate_ (tree ref) +{ + tree result; + enum tree_code code = TREE_CODE (ref); + + switch (code) + { + case VAR_DECL: + case PARM_DECL: + case RESULT_DECL: + /* No action is needed in this case. */ + return ref; + + case NOP_EXPR: + case CONVERT_EXPR: + case FLOAT_EXPR: + case FIX_TRUNC_EXPR: + case FIX_FLOOR_EXPR: + case FIX_ROUND_EXPR: + case FIX_CEIL_EXPR: + result = build_nt (code, stabilize_reference (TREE_OPERAND (ref, 0))); + break; + + case INDIRECT_REF: + result = build_nt (INDIRECT_REF, + stabilize_reference_1 (TREE_OPERAND (ref, 0))); + break; + + case COMPONENT_REF: + result = build_nt (COMPONENT_REF, + stabilize_reference (TREE_OPERAND (ref, 0)), + TREE_OPERAND (ref, 1)); + break; + + case BIT_FIELD_REF: + result = build_nt (BIT_FIELD_REF, + stabilize_reference (TREE_OPERAND (ref, 0)), + stabilize_reference_1 (TREE_OPERAND (ref, 1)), + stabilize_reference_1 (TREE_OPERAND (ref, 2))); + break; + + case ARRAY_REF: + result = build_nt (ARRAY_REF, + stabilize_reference (TREE_OPERAND (ref, 0)), + stabilize_reference_1 (TREE_OPERAND (ref, 1))); + break; + + case COMPOUND_EXPR: + result = build_nt (COMPOUND_EXPR, + stabilize_reference_1 (TREE_OPERAND (ref, 0)), + stabilize_reference (TREE_OPERAND (ref, 1))); + break; + + case RTL_EXPR: + result = build1 (INDIRECT_REF, TREE_TYPE (ref), + save_expr (build1 (ADDR_EXPR, + build_pointer_type (TREE_TYPE (ref)), + ref))); + break; + + + default: + return save_expr (ref); + + case ERROR_MARK: + return error_mark_node; + } + + TREE_TYPE (result) = TREE_TYPE (ref); + TREE_READONLY (result) = TREE_READONLY (ref); + TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (ref); + TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (ref); + TREE_RAISES (result) = TREE_RAISES (ref); + + return result; +} +#endif + +/* A rip-off of gcc's convert.c convert_to_complex function, + reworked to handle complex implemented as C structures + (RECORD_TYPE with two fields, real and imaginary `r' and `i'). */ + +#if FFECOM_targetCURRENT == FFECOM_targetGCC +tree +ffecom_convert_to_complex_ (tree type, tree expr) +{ + register enum tree_code form = TREE_CODE (TREE_TYPE (expr)); + tree subtype; + + assert (TREE_CODE (type) == RECORD_TYPE); + + subtype = TREE_TYPE (TYPE_FIELDS (type)); + + if (form == REAL_TYPE || form == INTEGER_TYPE || form == ENUMERAL_TYPE) + { + expr = convert (subtype, expr); + return ffecom_2 (COMPLEX_EXPR, type, expr, + convert (subtype, integer_zero_node)); + } + + if (form == RECORD_TYPE) + { + tree elt_type = TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))); + if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype)) + return expr; + else + { + expr = save_expr (expr); + return ffecom_2 (COMPLEX_EXPR, + type, + convert (subtype, + ffecom_1 (REALPART_EXPR, + TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))), + expr)), + convert (subtype, + ffecom_1 (IMAGPART_EXPR, + TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))), + expr))); + } + } + + if (form == POINTER_TYPE || form == REFERENCE_TYPE) + error ("pointer value used where a complex was expected"); + else + error ("aggregate value used where a complex was expected"); + + return ffecom_2 (COMPLEX_EXPR, type, + convert (subtype, integer_zero_node), + convert (subtype, integer_zero_node)); +} +#endif + +/* Handles making a COMPLEX type, either the standard + (but buggy?) gbe way, or the safer (but less elegant?) + f2c way. */ + +#if FFECOM_targetCURRENT == FFECOM_targetGCC +static tree +ffecom_make_complex_type_ (tree subtype) +{ + tree type; + tree realfield; + tree imagfield; + + if (ffe_is_emulate_complex ()) + { + type = make_node (RECORD_TYPE); + realfield = ffecom_decl_field (type, NULL_TREE, "r", subtype); + imagfield = ffecom_decl_field (type, realfield, "i", subtype); + TYPE_FIELDS (type) = realfield; + layout_type (type); + } + else + { + type = make_node (COMPLEX_TYPE); + TREE_TYPE (type) = subtype; + layout_type (type); + } + + return type; +} +#endif + +/* Chooses either the gbe or the f2c way to build a + complex constant. */ + +#if FFECOM_targetCURRENT == FFECOM_targetGCC +static tree +ffecom_build_complex_constant_ (tree type, tree realpart, tree imagpart) +{ + tree bothparts; + + if (ffe_is_emulate_complex ()) + { + bothparts = build_tree_list (TYPE_FIELDS (type), realpart); + TREE_CHAIN (bothparts) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), imagpart); + bothparts = build (CONSTRUCTOR, type, NULL_TREE, bothparts); + } + else + { +#if BUILT_FOR_280 + bothparts = build_complex (NULL_TREE, realpart, imagpart); +#else + bothparts = build_complex (realpart, imagpart); +#endif + TREE_TYPE (bothparts) = type; + } + + return bothparts; +} +#endif + #if FFECOM_targetCURRENT == FFECOM_targetGCC static tree ffecom_arglist_expr_ (char *c, ffebld expr) @@ -1169,7 +1378,7 @@ ffecom_build_f2c_string_ (int i, char *s) #endif /* Returns CALL_EXPR or equivalent with given type (pass NULL_TREE for type to just get whatever the function returns), handling the - f2c complex-returning convention, if required, by prepending + f2c value-returning convention, if required, by prepending to the arglist a pointer to a temporary to receive the return value. */ #if FFECOM_targetCURRENT == FFECOM_targetGCC @@ -1491,45 +1700,55 @@ ffecom_char_args_ (tree *xitem, tree *length, ffebld expr) { ffesymbol s = ffebld_symter (ffebld_left (expr)); tree tempvar; - tree dt; tree args; + ffetargetCharacterSize size = ffeinfo_size (ffebld_info (expr)); + + if (size == FFETARGET_charactersizeNONE) + size = 24; /* ~~~~ Kludge alert! This should someday be fixed. */ - *length = build_int_2 (ffeinfo_size (ffebld_info (expr)), 0); + *length = build_int_2 (size, 0); TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node; if (ffeinfo_where (ffebld_info (ffebld_left (expr))) == FFEINFO_whereINTRINSIC) - { /* Invocation of an intrinsic. */ - item = ffecom_expr_intrinsic_ (expr, NULL_TREE, - NULL, NULL); - break; + { + ffecomGfrt ix; + + if (size == 1) + { /* Invocation of an intrinsic returning CHARACTER*1. */ + item = ffecom_expr_intrinsic_ (expr, NULL_TREE, + NULL, NULL); + break; + } + ix = ffeintrin_gfrt (ffebld_symter_implementation (ffebld_left (expr))); + assert (ix != FFECOM_gfrt); + item = ffecom_gfrt_tree_ (ix); + } + else + { + item = ffesymbol_hook (s).decl_tree; + if (item == NULL_TREE) + { + s = ffecom_sym_transform_ (s); + item = ffesymbol_hook (s).decl_tree; + } + if (item == error_mark_node) + { + item = *length = error_mark_node; + break; + } + + if (!ffesymbol_hook (s).addr) + item = ffecom_1_fn (item); } assert (ffecom_pending_calls_ != 0); - tempvar = ffecom_push_tempvar (char_type_node, - ffeinfo_size (ffebld_info (expr)), - -1, TRUE); + tempvar = ffecom_push_tempvar (char_type_node, size, -1, TRUE); tempvar = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (tempvar)), tempvar); ffecom_push_calltemps (); - dt = ffesymbol_hook (s).decl_tree; - if (dt == NULL_TREE) - { - s = ffecom_sym_transform_ (s); - dt = ffesymbol_hook (s).decl_tree; - } - if (dt == error_mark_node) - { - item = *length = error_mark_node; - break; - } - - if (ffesymbol_hook (s).addr) - item = dt; - else - item = ffecom_1_fn (dt); args = build_tree_list (NULL_TREE, tempvar); @@ -1918,6 +2137,8 @@ ffecom_do_entry_ (ffesymbol fn, int entrynum) tree result; /* Var holding result. */ ffeinfoBasictype bt; ffeinfoKindtype kt; + ffeglobal g; + ffeglobalType gt; bool charfunc; /* All entry points return same type CHARACTER. */ bool cmplxfunc; /* Use f2c way of returning COMPLEX. */ @@ -1943,6 +2164,7 @@ ffecom_do_entry_ (ffesymbol fn, int entrynum) /* Determine actual return type for function. */ + gt = FFEGLOBAL_typeFUNC; bt = ffesymbol_basictype (fn); kt = ffesymbol_kindtype (fn); if (bt == FFEINFO_basictypeNONE) @@ -1977,6 +2199,7 @@ ffecom_do_entry_ (ffesymbol fn, int entrynum) break; case FFEINFO_kindSUBROUTINE: + gt = FFEGLOBAL_typeSUBR; bt = FFEINFO_basictypeNONE; kt = FFEINFO_kindtypeNONE; if (ffecom_is_altreturning_) @@ -2007,6 +2230,7 @@ ffecom_do_entry_ (ffesymbol fn, int entrynum) assert ("say what??" == NULL); /* Fall through. */ case FFEINFO_kindANY: + gt = FFEGLOBAL_typeANY; bt = FFEINFO_basictypeNONE; kt = FFEINFO_kindtypeNONE; type = error_mark_node; @@ -2026,6 +2250,12 @@ ffecom_do_entry_ (ffesymbol fn, int entrynum) 0, /* nested/inline */ 1); /* TREE_PUBLIC */ + if (((g = ffesymbol_global (fn)) != NULL) + && (ffeglobal_type (g) == gt)) + { + ffeglobal_set_hook (g, current_function_decl); + } + /* Reset args in master arg list so they get retransitioned. */ for (item = ffecom_master_arglist_; @@ -2301,7 +2531,7 @@ ffecom_expr_ (ffebld expr, tree dest_tree, case FFEBLD_opACCTER: tree_type = ffecom_tree_type[bt][kt]; { - ffetargetOffset i; + ffebitCount i; ffebit bits = ffebld_accter_bits (expr); ffetargetOffset source_offset = 0; size_t size; @@ -2410,9 +2640,54 @@ ffecom_expr_ (ffebld expr, tree dest_tree, || (ffebld_symter_specific (expr) != FFEINTRIN_specNONE)) return ffecom_ptr_to_expr (expr); /* Same as %REF(intrinsic). */ s = ffebld_symter (expr); + t = ffesymbol_hook (s).decl_tree; + if (assignp) { /* ASSIGN'ed-label expr. */ - t = ffesymbol_hook (s).decl_tree; + if (ffe_is_ugly_assign ()) + { + /* User explicitly wants ASSIGN'ed variables to be at the same + memory address as the variables when used in non-ASSIGN + contexts. That can make old, arcane, non-standard code + work, but don't try to do it when a pointer wouldn't fit + in the normal variable (take other approach, and warn, + instead). */ + + if (t == NULL_TREE) + { + s = ffecom_sym_transform_ (s); + t = ffesymbol_hook (s).decl_tree; + assert (t != NULL_TREE); + } + + if (t == error_mark_node) + return t; + + if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (t))) + >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node)))) + { + if (ffesymbol_hook (s).addr) + t = ffecom_1 (INDIRECT_REF, + TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))), t); + return t; + } + + if (ffesymbol_hook (s).assign_tree == NULL_TREE) + { + ffebad_start_msg ("ASSIGN'ed label cannot fit into `%A' at %0 -- using wider sibling", + FFEBAD_severityWARNING); + ffebad_string (ffesymbol_text (s)); + ffebad_here (0, ffesymbol_where_line (s), + ffesymbol_where_column (s)); + ffebad_finish (); + } + } + + /* Don't use the normal variable's tree for ASSIGN, though mark + it as in the system header (housekeeping). Use an explicit, + specially created sibling that is known to be wide enough + to hold pointers to labels. */ + if (t != NULL_TREE) DECL_IN_SYSTEM_HEADER (t) = 1; /* Don't let -Wunused complain. */ @@ -2426,7 +2701,6 @@ ffecom_expr_ (ffebld expr, tree dest_tree, } else { - t = ffesymbol_hook (s).decl_tree; if (t == NULL_TREE) { s = ffecom_sym_transform_ (s); @@ -2581,10 +2855,7 @@ ffecom_expr_ (ffebld expr, tree dest_tree, == FFEINFO_kindtypeREAL1) code = FFECOM_gfrtPOW_CI; /* Overlapping result okay. */ else - { - code = FFECOM_gfrtPOW_ZI; - dest_used = NULL; /* This one doesn't work with overlapping result. */ - } + code = FFECOM_gfrtPOW_ZI; /* Overlapping result okay. */ break; default: @@ -2841,7 +3112,8 @@ ffecom_expr_ (ffebld expr, tree dest_tree, item = ffecom_expr (ffebld_left (expr)); if (item == error_mark_node) return error_mark_node; - item = convert (TREE_TYPE (tree_type), item); + /* convert() takes care of converting to the subtype first, + at least in gcc-2.7.2. */ item = convert (tree_type, item); return item; @@ -2913,8 +3185,16 @@ ffecom_expr_ (ffebld expr, tree dest_tree, arg1 = ffecom_save_tree (arg1); arg2 = ffecom_save_tree (arg2); - real_type = TREE_TYPE (TREE_TYPE (arg1)); - assert (real_type == TREE_TYPE (TREE_TYPE (arg2))); + if (TREE_CODE (TREE_TYPE (arg1)) == COMPLEX_TYPE) + { + real_type = TREE_TYPE (TREE_TYPE (arg1)); + assert (real_type == TREE_TYPE (TREE_TYPE (arg2))); + } + else + { + real_type = TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg1))); + assert (real_type == TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg2)))); + } item = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node, @@ -3092,6 +3372,7 @@ ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree, ffebld arg2; ffebld arg3; ffecomGfrt ix; + ffeintrinImp codegen_imp; assert (ffebld_op (ffebld_left (expr)) == FFEBLD_opSYMTER); @@ -3145,7 +3426,7 @@ ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree, A standard call is made to the specific intrinsic just as if it had been passed in as a dummy procedure and called as any old procedure. This - method can produce slower code but in some cases its the easiest way for + method can produce slower code but in some cases it's the easiest way for now. goto library; @@ -3162,8 +3443,9 @@ ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree, /* For info on how the switch statement cases were written, see the files enclosed in comments below the switch statement. */ - switch (ffeintrin_codegen_imp - (ffebld_symter_implementation (ffebld_left (expr)))) + codegen_imp = ffeintrin_codegen_imp (ffebld_symter_implementation + (ffebld_left (expr))); + switch (codegen_imp) { case FFEINTRIN_impABS: /* Plus impCABS, impCDABS, impDABS, impIABS. */ if (ffeinfo_basictype (ffebld_info (arg1)) @@ -3196,9 +3478,14 @@ ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree, goto library; /* :::::::::::::::::::: */ case FFEINTRIN_impAIMAG: /* Plus impDIMAG. */ + if (TREE_CODE (arg1_type) == COMPLEX_TYPE) + arg1_type = TREE_TYPE (arg1_type); + else + arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type)); + return convert (tree_type, - ffecom_1 (IMAGPART_EXPR, TREE_TYPE (arg1_type), + ffecom_1 (IMAGPART_EXPR, arg1_type, ffecom_expr (arg1))); case FFEINTRIN_impAINT: /* Plus impDINT. */ @@ -3342,43 +3629,48 @@ ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree, return expr_tree; case FFEINTRIN_impCMPLX: - real_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt]; if (arg2 == NULL) return convert (tree_type, ffecom_expr (arg1)); + real_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt]; return ffecom_2 (COMPLEX_EXPR, tree_type, convert (real_type, ffecom_expr (arg1)), convert (real_type, ffecom_expr (arg2))); + case FFEINTRIN_impCOMPLEX: + return + ffecom_2 (COMPLEX_EXPR, tree_type, + ffecom_expr (arg1), + ffecom_expr (arg2)); + case FFEINTRIN_impCONJG: /* Plus impDCONJG. */ - if (kt == FFEINFO_kindtypeREAL1) - ix = FFECOM_gfrtCONJG; - else if (kt == FFEINFO_kindtypeREAL2) - ix = FFECOM_gfrtDCONJG; - else - { - assert ("bad CONJG kind type" == NULL); - ix = FFECOM_gfrt; - } - dest_used = NULL; /* These don't work with overlapping result. */ - goto library; /* :::::::::::::::::::: */ + { + tree arg1_tree; + + real_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt]; + arg1_tree = ffecom_save_tree (ffecom_expr (arg1)); + return + ffecom_2 (COMPLEX_EXPR, tree_type, + ffecom_1 (REALPART_EXPR, real_type, arg1_tree), + ffecom_1 (NEGATE_EXPR, real_type, + ffecom_1 (IMAGPART_EXPR, real_type, arg1_tree))); + } case FFEINTRIN_impCOS: /* Plus impCCOS, impCDCOS, impDCOS. */ if (bt == FFEINFO_basictypeCOMPLEX) { if (kt == FFEINFO_kindtypeREAL1) - ix = FFECOM_gfrtCCOS; + ix = FFECOM_gfrtCCOS; /* Overlapping result okay. */ else if (kt == FFEINFO_kindtypeREAL2) - ix = FFECOM_gfrtCDCOS; + ix = FFECOM_gfrtCDCOS; /* Overlapping result okay. */ else { assert ("bad COS COMPLEX kind type" == NULL); ix = FFECOM_gfrt; } - dest_used = NULL; /* These don't work with overlapping result. */ } else { @@ -3407,6 +3699,10 @@ ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree, goto library; /* :::::::::::::::::::: */ case FFEINTRIN_impDBLE: + case FFEINTRIN_impINT: + case FFEINTRIN_impREAL: + case FFEINTRIN_impLONG: + case FFEINTRIN_impSHORT: return convert (tree_type, ffecom_expr (arg1)); case FFEINTRIN_impDIM: /* Plus impDDIM, impIDIM. */ @@ -3435,15 +3731,14 @@ ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree, if (bt == FFEINFO_basictypeCOMPLEX) { if (kt == FFEINFO_kindtypeREAL1) - ix = FFECOM_gfrtCEXP; + ix = FFECOM_gfrtCEXP; /* Overlapping result okay. */ else if (kt == FFEINFO_kindtypeREAL2) - ix = FFECOM_gfrtCDEXP; + ix = FFECOM_gfrtCDEXP; /* Overlapping result okay. */ else { assert ("bad EXP COMPLEX kind type" == NULL); ix = FFECOM_gfrt; } - dest_used = NULL; /* These don't work with overlapping result. */ } else { @@ -3485,9 +3780,6 @@ ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree, case FFEINTRIN_impINDEX: break; - case FFEINTRIN_impINT: - return convert (tree_type, ffecom_expr (arg1)); - case FFEINTRIN_impLEN: #if 0 /* The simple approach. */ break; @@ -3511,15 +3803,14 @@ ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree, if (bt == FFEINFO_basictypeCOMPLEX) { if (kt == FFEINFO_kindtypeREAL1) - ix = FFECOM_gfrtCLOG; + ix = FFECOM_gfrtCLOG; /* Overlapping result okay. */ else if (kt == FFEINFO_kindtypeREAL2) - ix = FFECOM_gfrtCDLOG; + ix = FFECOM_gfrtCDLOG; /* Overlapping result okay. */ else { assert ("bad LOG COMPLEX kind type" == NULL); ix = FFECOM_gfrt; } - dest_used = NULL; /* These don't work with overlapping result. */ } else { @@ -3632,9 +3923,6 @@ ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree, ffecom_float_half_)))); #endif - case FFEINTRIN_impREAL: - return convert (tree_type, ffecom_expr (arg1)); - case FFEINTRIN_impSIGN: /* Plus impDSIGN, impISIGN. */ { tree arg2_tree = ffecom_expr (arg2); @@ -3665,15 +3953,14 @@ ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree, if (bt == FFEINFO_basictypeCOMPLEX) { if (kt == FFEINFO_kindtypeREAL1) - ix = FFECOM_gfrtCSIN; + ix = FFECOM_gfrtCSIN; /* Overlapping result okay. */ else if (kt == FFEINFO_kindtypeREAL2) - ix = FFECOM_gfrtCDSIN; + ix = FFECOM_gfrtCDSIN; /* Overlapping result okay. */ else { assert ("bad SIN COMPLEX kind type" == NULL); ix = FFECOM_gfrt; } - dest_used = NULL; /* These don't work with overlapping result. */ } else { @@ -3705,15 +3992,14 @@ ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree, if (bt == FFEINFO_basictypeCOMPLEX) { if (kt == FFEINFO_kindtypeREAL1) - ix = FFECOM_gfrtCSQRT; + ix = FFECOM_gfrtCSQRT; /* Overlapping result okay. */ else if (kt == FFEINFO_kindtypeREAL2) - ix = FFECOM_gfrtCDSQRT; + ix = FFECOM_gfrtCDSQRT; /* Overlapping result okay. */ else { assert ("bad SQRT COMPLEX kind type" == NULL); ix = FFECOM_gfrt; } - dest_used = NULL; /* These don't work with overlapping result. */ } else { @@ -3753,6 +4039,17 @@ ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree, } goto library; /* :::::::::::::::::::: */ + case FFEINTRIN_impREALPART: + if (TREE_CODE (arg1_type) == COMPLEX_TYPE) + arg1_type = TREE_TYPE (arg1_type); + else + arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type)); + + return + convert (tree_type, + ffecom_1 (REALPART_EXPR, arg1_type, + ffecom_expr (arg1))); + case FFEINTRIN_impIAND: return ffecom_2 (BIT_AND_EXPR, tree_type, convert (tree_type, @@ -4054,26 +4351,34 @@ ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree, case FFEINTRIN_impMVBITS: { tree arg1_tree; - tree arg2_tree = convert (integer_type_node, - ffecom_expr (arg2)); - tree arg3_tree = ffecom_save_tree (convert (integer_type_node, - ffecom_expr (arg3))); + tree arg2_tree; + tree arg3_tree; ffebld arg4 = ffebld_head (ffebld_trail (list)); tree arg4_tree; tree arg4_type; ffebld arg5 = ffebld_head (ffebld_trail (ffebld_trail (list))); - tree arg5_tree = ffecom_save_tree (convert (integer_type_node, - ffecom_expr (arg5))); + tree arg5_tree; tree prep_arg1; tree prep_arg4; tree arg5_plus_arg3; + ffecom_push_calltemps (); + + arg2_tree = convert (integer_type_node, + ffecom_expr (arg2)); + arg3_tree = ffecom_save_tree (convert (integer_type_node, + ffecom_expr (arg3))); arg4_tree = ffecom_expr_rw (arg4); arg4_type = TREE_TYPE (arg4_tree); arg1_tree = ffecom_save_tree (convert (arg4_type, ffecom_expr (arg1))); + arg5_tree = ffecom_save_tree (convert (integer_type_node, + ffecom_expr (arg5))); + + ffecom_pop_calltemps (); + prep_arg1 = ffecom_2 (LSHIFT_EXPR, arg4_type, ffecom_2 (BIT_AND_EXPR, arg4_type, @@ -4252,10 +4557,15 @@ ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree, return expr_tree; case FFEINTRIN_impSYSTEM: + case FFEINTRIN_impUNLINK: + case FFEINTRIN_impCHDIR: + case FFEINTRIN_impFPUT: + case FFEINTRIN_impFGET: { tree arg1_len = integer_zero_node; tree arg1_tree; tree arg2_tree; + ffecomGfrt gfrt = ffeintrin_gfrt (codegen_imp); ffecom_push_calltemps (); @@ -4273,10 +4583,10 @@ ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree, TREE_CHAIN (arg1_tree) = arg1_len; expr_tree - = ffecom_call_ (ffecom_gfrt_tree_ (FFECOM_gfrtSYSTEM), - ffecom_gfrt_kind_type_ (FFECOM_gfrtSYSTEM), + = ffecom_call_ (ffecom_gfrt_tree_ (gfrt), + ffecom_gfrt_kind_type_ (gfrt), FALSE, - integer_type_node, + ffecom_f2c_integer_type_node, arg1_tree, NULL_TREE, NULL, NULL, NULL_TREE, TRUE); @@ -4292,17 +4602,11 @@ ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree, if (arg1 != NULL) break; -#ifdef VMS_TARGET - expr_tree = ffecom_integer_zero_node; /* C lib translates this!! */ -#else - expr_tree = ffecom_integer_zero_node; -#endif - expr_tree = build_tree_list (NULL_TREE, ffecom_1 (ADDR_EXPR, build_pointer_type (ffecom_integer_type_node), - expr_tree)); + integer_zero_node)); return ffecom_call_ (ffecom_gfrt_tree_ (FFECOM_gfrtEXIT), @@ -4313,20 +4617,264 @@ ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree, NULL_TREE, NULL, NULL, NULL_TREE, TRUE); case FFEINTRIN_impFLUSH: - /* Ignore the arg, since the library has no use for it yet. */ - return - ffecom_call_ (ffecom_gfrt_tree_ (FFECOM_gfrtFLUSH), - ffecom_gfrt_kind_type_ (FFECOM_gfrtFLUSH), - FALSE, - void_type_node, - NULL_TREE, - NULL_TREE, NULL, NULL, NULL_TREE, TRUE); + if (arg1 == NULL) + ix = FFECOM_gfrtFLUSH; + else + ix = FFECOM_gfrtFLUSH1; + goto library; /* :::::::::::::::::::: */ + + case FFEINTRIN_impCHMOD: + case FFEINTRIN_impLINK: + case FFEINTRIN_impRENAME: + case FFEINTRIN_impSYMLNK: + { + tree arg1_len = integer_zero_node; + tree arg1_tree; + tree arg2_len = integer_zero_node; + tree arg2_tree; + tree arg3_tree; + ffecomGfrt gfrt = ffeintrin_gfrt (codegen_imp); + + ffecom_push_calltemps (); + + arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len); + arg2_tree = ffecom_arg_ptr_to_expr (arg2, &arg2_len); + if (arg3 != NULL) + arg3_tree = ffecom_expr_rw (arg3); + else + arg3_tree = NULL_TREE; + + ffecom_pop_calltemps (); + + arg1_tree = build_tree_list (NULL_TREE, arg1_tree); + arg1_len = build_tree_list (NULL_TREE, arg1_len); + arg2_tree = build_tree_list (NULL_TREE, arg2_tree); + arg2_len = build_tree_list (NULL_TREE, arg2_len); + TREE_CHAIN (arg1_tree) = arg2_tree; + TREE_CHAIN (arg2_tree) = arg1_len; + TREE_CHAIN (arg1_len) = arg2_len; + expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt), + ffecom_gfrt_kind_type_ (gfrt), + FALSE, + ffecom_f2c_integer_type_node, + arg1_tree, + NULL_TREE, NULL, NULL, NULL_TREE, TRUE); + if (arg3_tree != NULL_TREE) + expr_tree = ffecom_modify (NULL_TREE, arg3_tree, + convert (TREE_TYPE (arg3_tree), + expr_tree)); + } + return expr_tree; + + case FFEINTRIN_impFGETC: + case FFEINTRIN_impFPUTC: + { + tree arg1_tree; + tree arg2_tree; + tree arg2_len = integer_zero_node; + tree arg3_tree; + ffecomGfrt gfrt = ffeintrin_gfrt (codegen_imp); + + ffecom_push_calltemps (); + + arg1_tree = convert (ffecom_f2c_ptr_to_integer_type_node, + ffecom_ptr_to_expr (arg1)); + arg2_tree = ffecom_arg_ptr_to_expr (arg2, &arg2_len); + arg3_tree = ffecom_expr_rw (arg3); + + ffecom_pop_calltemps (); + + arg1_tree = build_tree_list (NULL_TREE, arg1_tree); + arg2_tree = build_tree_list (NULL_TREE, arg2_tree); + arg2_len = build_tree_list (NULL_TREE, arg2_len); + TREE_CHAIN (arg1_tree) = arg2_tree; + TREE_CHAIN (arg2_tree) = arg2_len; + + expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt), + ffecom_gfrt_kind_type_ (gfrt), + FALSE, + ffecom_f2c_integer_type_node, + arg1_tree, + NULL_TREE, NULL, NULL, NULL_TREE, TRUE); + expr_tree = ffecom_modify (NULL_TREE, arg3_tree, + convert (TREE_TYPE (arg3_tree), + expr_tree)); + } + return expr_tree; + + case FFEINTRIN_impKILL: + { + tree arg1_tree; + tree arg2_tree; + tree arg3_tree; + ffecomGfrt gfrt = ffeintrin_gfrt (codegen_imp); + + ffecom_push_calltemps (); + + arg1_tree = convert (ffecom_f2c_ptr_to_integer_type_node, + ffecom_ptr_to_expr (arg1)); + arg2_tree = convert (ffecom_f2c_ptr_to_integer_type_node, + ffecom_ptr_to_expr (arg2)); + if (arg3 == NULL) + arg3_tree = NULL_TREE; + else + arg3_tree = ffecom_expr_rw (arg3); + + ffecom_pop_calltemps (); + + arg1_tree = build_tree_list (NULL_TREE, arg1_tree); + arg2_tree = build_tree_list (NULL_TREE, arg2_tree); + TREE_CHAIN (arg1_tree) = arg2_tree; + expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt), + ffecom_gfrt_kind_type_ (gfrt), + FALSE, + ffecom_f2c_integer_type_node, + arg1_tree, + NULL_TREE, NULL, NULL, NULL_TREE, TRUE); + if (arg3_tree != NULL_TREE) { + expr_tree = ffecom_modify (NULL_TREE, arg3_tree, + convert (TREE_TYPE (arg3_tree), + expr_tree)); + } + } + return expr_tree; + + case FFEINTRIN_impIRAND: + case FFEINTRIN_impRAND: + /* Arg defaults to 0 (normal random case) */ + { + tree arg1_tree; + ffecomGfrt gfrt = ffeintrin_gfrt (codegen_imp); + + if (arg1 == NULL) + arg1_tree = ffecom_1 (ADDR_EXPR, + build_pointer_type + (ffecom_integer_type_node), + ffecom_integer_zero_node); + else + arg1_tree = ffecom_ptr_to_expr (arg1); + arg1_tree = convert (ffecom_f2c_ptr_to_integer_type_node, + arg1_tree); + arg1_tree = build_tree_list (NULL_TREE, arg1_tree); + return ffecom_call_ (ffecom_gfrt_tree_ (gfrt), + ffecom_gfrt_kind_type_ (gfrt), + FALSE, + ((codegen_imp == FFEINTRIN_impIRAND) ? + ffecom_f2c_integer_type_node : + ffecom_f2c_doublereal_type_node), + arg1_tree, + dest_tree, dest, dest_used, + NULL_TREE, TRUE); + } + + case FFEINTRIN_impUMASK: + { + tree arg1_tree; + tree arg2_tree; + ffecomGfrt gfrt = ffeintrin_gfrt (codegen_imp); + ffecom_push_calltemps (); + + arg1_tree = convert (ffecom_f2c_ptr_to_integer_type_node, + ffecom_ptr_to_expr (arg1)); + if (arg2 == NULL) + arg2_tree = NULL_TREE; + else + arg2_tree = ffecom_expr_rw (arg2); + + ffecom_pop_calltemps (); + + expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt), + ffecom_gfrt_kind_type_ (gfrt), + FALSE, + ffecom_f2c_integer_type_node, + build_tree_list (NULL_TREE, arg1_tree), + NULL_TREE, NULL, NULL, NULL_TREE, + TRUE); + if (arg2_tree != NULL_TREE) { + expr_tree = ffecom_modify (NULL_TREE, arg2_tree, + convert (TREE_TYPE (arg2_tree), + expr_tree)); + } + } + return expr_tree; + + case FFEINTRIN_impSECONDSUBR: + { + tree arg1_tree; + ffecomGfrt gfrt = ffeintrin_gfrt (codegen_imp); + + ffecom_push_calltemps (); + + arg1_tree = ffecom_expr_rw (arg1); + + ffecom_pop_calltemps (); + + expr_tree + = ffecom_call_ (ffecom_gfrt_tree_ (gfrt), + ffecom_gfrt_kind_type_ (gfrt), + FALSE, + NULL_TREE, + NULL_TREE, + NULL_TREE, NULL, NULL, NULL_TREE, TRUE); + + expr_tree + = ffecom_modify (NULL_TREE, arg1_tree, + convert (TREE_TYPE (arg1_tree), + expr_tree)); + } + return expr_tree; + + /* Straightforward calls of libf2c routines: */ case FFEINTRIN_impABORT: - case FFEINTRIN_impGETARG: - case FFEINTRIN_impGETENV: + case FFEINTRIN_impACCESS: + case FFEINTRIN_impBESJ0: + case FFEINTRIN_impBESJ1: + case FFEINTRIN_impBESJN: + case FFEINTRIN_impBESY0: + case FFEINTRIN_impBESY1: + case FFEINTRIN_impBESYN: + case FFEINTRIN_impDATE: + case FFEINTRIN_impDBESJ0: + case FFEINTRIN_impDBESJ1: + case FFEINTRIN_impDBESJN: + case FFEINTRIN_impDBESY0: + case FFEINTRIN_impDBESY1: + case FFEINTRIN_impDBESYN: + case FFEINTRIN_impDTIME: + case FFEINTRIN_impETIME: + case FFEINTRIN_impFNUM: + case FFEINTRIN_impFSTAT: case FFEINTRIN_impFTELL: case FFEINTRIN_impFSEEK: + case FFEINTRIN_impGETARG: + case FFEINTRIN_impGERROR: + case FFEINTRIN_impGETCWD: + case FFEINTRIN_impGETENV: + case FFEINTRIN_impGETGID: + case FFEINTRIN_impGETLOG: + case FFEINTRIN_impGETPID: + case FFEINTRIN_impGETUID: + case FFEINTRIN_impGMTIME: + case FFEINTRIN_impHOSTNM: + case FFEINTRIN_impIDATE: + case FFEINTRIN_impIDATEVXT: + case FFEINTRIN_impIERRNO: + case FFEINTRIN_impISATTY: + case FFEINTRIN_impITIME: + case FFEINTRIN_impLNBLNK: + case FFEINTRIN_impLSTAT: + case FFEINTRIN_impLTIME: + case FFEINTRIN_impMCLOCK: + case FFEINTRIN_impPERROR: + case FFEINTRIN_impSECNDS: + case FFEINTRIN_impSECONDFUNC: + case FFEINTRIN_impSLEEP: + case FFEINTRIN_impSRAND: + case FFEINTRIN_impSTAT: + case FFEINTRIN_impSYSTEM_CLOCK: + case FFEINTRIN_impTIME: + case FFEINTRIN_impTIMEVXT: break; default: @@ -5580,7 +6128,10 @@ tail_recurse: /* :::::::::::::::::::: */ case FFEBLD_opSYMTER: s = ffebld_symter (expr); t = ffesymbol_hook (s).decl_tree; - if (t == NULL_TREE) + if ((t == NULL_TREE) + && ((ffesymbol_kind (s) != FFEINFO_kindNONE) + || ((ffesymbol_where (s) != FFEINFO_whereNONE) + && (ffesymbol_where (s) != FFEINFO_whereINTRINSIC)))) { s = ffecom_sym_transform_ (s); t = ffesymbol_hook (s).decl_tree; /* Sfunc expr non-dummy, @@ -5669,15 +6220,11 @@ ffecom_f2c_make_type_ (tree *type, int tcode, char *name) break; case FFECOM_f2ccodeTWOREALS: - *type = make_node (COMPLEX_TYPE); - TREE_TYPE (*type) = ffecom_f2c_real_type_node; - layout_type (*type); + *type = ffecom_make_complex_type_ (ffecom_f2c_real_type_node); break; case FFECOM_f2ccodeTWODOUBLEREALS: - *type = make_node (COMPLEX_TYPE); - TREE_TYPE (*type) = ffecom_f2c_doublereal_type_node; - layout_type (*type); + *type = ffecom_make_complex_type_ (ffecom_f2c_doublereal_type_node); break; default: @@ -5706,7 +6253,7 @@ ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt, int size, for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j) if (((t = ffecom_tree_type[bt][j]) != NULL_TREE) - && (TYPE_PRECISION (t) == size)) + && (TREE_INT_CST_LOW (TYPE_SIZE (t)) == size)) { assert (code != -1); ffecom_f2c_typecode_[bt][j] = code; @@ -5783,7 +6330,8 @@ ffecom_finish_symbol_transform_ (ffesymbol s) if ((ffesymbol_hook (s).decl_tree == NULL_TREE) && ((ffesymbol_kind (s) != FFEINFO_kindNONE) - || (ffesymbol_where (s) != FFEINFO_whereNONE))) + || ((ffesymbol_where (s) != FFEINFO_whereNONE) + && (ffesymbol_where (s) != FFEINFO_whereINTRINSIC)))) /* Not transformed, and not CHARACTER*(*). */ s = ffecom_sym_transform_ (s); @@ -6660,6 +7208,11 @@ ffecom_make_gfrt_ (ffecomGfrt ix) kt = FFEINFO_kindtypeREAL2; break; + case FFECOM_rttypeCHARACTER_: + ttype = void_type_node; + kt = FFEINFO_kindtypeCHARACTER1; + break; + default: ttype = NULL; kt = FFEINFO_kindtypeANY; @@ -6849,6 +7402,8 @@ ffecom_start_progunit_ () tree result; /* Result of function. */ ffeinfoBasictype bt; ffeinfoKindtype kt; + ffeglobal g; + ffeglobalType gt; bool charfunc; bool cmplxfunc; bool altentries = (ffecom_num_entrypoints_ != 0); @@ -6881,8 +7436,16 @@ ffecom_start_progunit_ () { case FFEINFO_kindPROGRAM: main_program = TRUE; - /* Fall through. */ + gt = FFEGLOBAL_typeMAIN; + bt = FFEINFO_basictypeNONE; + kt = FFEINFO_kindtypeNONE; + type = ffecom_tree_fun_type_void; + charfunc = FALSE; + cmplxfunc = FALSE; + break; + case FFEINFO_kindBLOCKDATA: + gt = FFEGLOBAL_typeBDATA; bt = FFEINFO_basictypeNONE; kt = FFEINFO_kindtypeNONE; type = ffecom_tree_fun_type_void; @@ -6891,6 +7454,7 @@ ffecom_start_progunit_ () break; case FFEINFO_kindFUNCTION: + gt = FFEGLOBAL_typeFUNC; bt = ffesymbol_basictype (fn); kt = ffesymbol_kindtype (fn); if (bt == FFEINFO_basictypeNONE) @@ -6926,6 +7490,7 @@ ffecom_start_progunit_ () break; case FFEINFO_kindSUBROUTINE: + gt = FFEGLOBAL_typeSUBR; bt = FFEINFO_basictypeNONE; kt = FFEINFO_kindtypeNONE; if (ffecom_is_altreturning_) @@ -6940,6 +7505,7 @@ ffecom_start_progunit_ () assert ("say what??" == NULL); /* Fall through. */ case FFEINFO_kindANY: + gt = FFEGLOBAL_typeANY; bt = FFEINFO_basictypeNONE; kt = FFEINFO_kindtypeNONE; type = error_mark_node; @@ -6964,6 +7530,13 @@ ffecom_start_progunit_ () 0, /* nested/inline */ !altentries); /* TREE_PUBLIC */ + if (!altentries + && ((g = ffesymbol_global (fn)) != NULL) + && (ffeglobal_type (g) == gt)) + { + ffeglobal_set_hook (g, current_function_decl); + } + yes = suspend_momentary (); /* Arg handling needs exec-transitioned ffesymbols to work with. But @@ -7066,6 +7639,7 @@ ffecom_sym_transform_ (ffesymbol s) bool addr; /* Is t the address of the thingy? */ ffeinfoBasictype bt; ffeinfoKindtype kt; + ffeglobal g; int yes; int old_lineno = lineno; char *old_input_filename = input_filename; @@ -7116,6 +7690,15 @@ ffecom_sym_transform_ (ffesymbol s) case FFEINFO_whereGLOBAL: /* Subroutine or function. */ assert (!ffecom_transform_only_dummies_); + if (((g = ffesymbol_global (s)) != NULL) + && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR) + || (ffeglobal_type (g) == FFEGLOBAL_typeFUNC)) + && (ffeglobal_hook (g) != NULL_TREE)) + { + t = ffeglobal_hook (g); + break; + } + yes = suspend_momentary (); t = build_decl (FUNCTION_DECL, @@ -7127,6 +7710,11 @@ ffecom_sym_transform_ (ffesymbol s) t = start_decl (t, FALSE); finish_decl (t, NULL_TREE, FALSE); + if ((g != NULL) + && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR) + || (ffeglobal_type (g) == FFEGLOBAL_typeFUNC))) + ffeglobal_set_hook (g, t); + if (current_function_decl != NULL_TREE) resume_momentary (yes); @@ -7259,7 +7847,7 @@ ffecom_sym_transform_ (ffesymbol s) if (st != NULL) assert (ffestorag_size (st) * BITS_PER_UNIT - == (unsigned long int) + == (ffetargetOffset) TREE_INT_CST_LOW (DECL_SIZE (t))); resume_momentary (yes); @@ -7731,6 +8319,14 @@ ffecom_sym_transform_ (ffesymbol s) case FFEINFO_whereGLOBAL: assert (!ffecom_transform_only_dummies_); + if (((g = ffesymbol_global (s)) != NULL) + && (ffeglobal_type (g) == FFEGLOBAL_typeFUNC) + && (ffeglobal_hook (g) != NULL_TREE)) + { + t = ffeglobal_hook (g); + break; + } + yes = suspend_momentary (); if (ffesymbol_is_f2c (s) @@ -7748,6 +8344,10 @@ ffecom_sym_transform_ (ffesymbol s) t = start_decl (t, FALSE); finish_decl (t, NULL_TREE, FALSE); + if ((g != NULL) + && (ffeglobal_type (g) == FFEGLOBAL_typeFUNC)) + ffeglobal_set_hook (g, t); + if (current_function_decl != NULL_TREE) resume_momentary (yes); @@ -7802,6 +8402,14 @@ ffecom_sym_transform_ (ffesymbol s) case FFEINFO_whereGLOBAL: assert (!ffecom_transform_only_dummies_); + if (((g = ffesymbol_global (s)) != NULL) + && (ffeglobal_type (g) == FFEGLOBAL_typeSUBR) + && (ffeglobal_hook (g) != NULL_TREE)) + { + t = ffeglobal_hook (g); + break; + } + yes = suspend_momentary (); t = build_decl (FUNCTION_DECL, @@ -7813,6 +8421,10 @@ ffecom_sym_transform_ (ffesymbol s) t = start_decl (t, FALSE); finish_decl (t, NULL_TREE, FALSE); + if ((g != NULL) + && (ffeglobal_type (g) == FFEGLOBAL_typeSUBR)) + ffeglobal_set_hook (g, t); + if (current_function_decl != NULL_TREE) resume_momentary (yes); @@ -8169,7 +8781,7 @@ ffecom_transform_common_ (ffesymbol s) if ((cbt != NULL_TREE) && (!is_init - || !DECL_EXTERNAL (ffeglobal_hook (g)))) + || !DECL_EXTERNAL (cbt))) return; /* Process inits. */ @@ -8366,7 +8978,7 @@ ffecom_transform_equiv_ (ffestorag eqst) ffestorag_set_init (eqst, ffebld_new_any ()); assert (ffestorag_size (eqst) * BITS_PER_UNIT - == (unsigned long int) TREE_INT_CST_LOW (DECL_SIZE (eqt))); + == (ffetargetOffset) TREE_INT_CST_LOW (DECL_SIZE (eqt))); ffestorag_set_hook (eqst, eqt); @@ -8742,10 +9354,9 @@ ffecom_tree_divide_ (tree tree_type, tree left, tree right, if (TREE_TYPE (tree_type) == ffecom_tree_type [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]) - ix = FFECOM_gfrtDIV_CC; + ix = FFECOM_gfrtDIV_CC; /* Overlapping result okay. */ else - ix = FFECOM_gfrtDIV_ZZ; - dest_used = NULL; /* These don't work with overlapping result. */ + ix = FFECOM_gfrtDIV_ZZ; /* Overlapping result okay. */ left = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (left)), @@ -8765,6 +9376,37 @@ ffecom_tree_divide_ (tree tree_type, tree left, tree right, dest_tree, dest, dest_used, NULL_TREE, TRUE); } + break; + + case RECORD_TYPE: + { + ffecomGfrt ix; + + if (TREE_TYPE (TYPE_FIELDS (tree_type)) + == ffecom_tree_type [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]) + ix = FFECOM_gfrtDIV_CC; /* Overlapping result okay. */ + else + ix = FFECOM_gfrtDIV_ZZ; /* Overlapping result okay. */ + + left = ffecom_1 (ADDR_EXPR, + build_pointer_type (TREE_TYPE (left)), + left); + left = build_tree_list (NULL_TREE, left); + right = ffecom_1 (ADDR_EXPR, + build_pointer_type (TREE_TYPE (right)), + right); + right = build_tree_list (NULL_TREE, right); + TREE_CHAIN (left) = right; + + return ffecom_call_ (ffecom_gfrt_tree_ (ix), + ffecom_gfrt_kind_type_ (ix), + ffe_is_f2c_library (), + tree_type, + left, + dest_tree, dest, dest_used, + NULL_TREE, TRUE); + } + break; default: return ffecom_2 (RDIV_EXPR, tree_type, @@ -9236,7 +9878,43 @@ ffecom_1 (enum tree_code code, tree type, tree node) if (!mark_addressable (node)) assert ("can't mark_addressable this node!" == NULL); } - item = build1 (code, type, node); + + switch (ffe_is_emulate_complex () ? code : NOP_EXPR) + { + tree realtype; + + case REALPART_EXPR: + item = build (COMPONENT_REF, type, node, TYPE_FIELDS (TREE_TYPE (node))); + break; + + case IMAGPART_EXPR: + item = build (COMPONENT_REF, type, node, TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (node)))); + break; + + + case NEGATE_EXPR: + if (TREE_CODE (type) != RECORD_TYPE) + { + item = build1 (code, type, node); + break; + } + node = ffecom_stabilize_aggregate_ (node); + realtype = TREE_TYPE (TYPE_FIELDS (type)); + item = + ffecom_2 (COMPLEX_EXPR, type, + ffecom_1 (NEGATE_EXPR, realtype, + ffecom_1 (REALPART_EXPR, realtype, + node)), + ffecom_1 (NEGATE_EXPR, realtype, + ffecom_1 (IMAGPART_EXPR, realtype, + node))); + break; + + default: + item = build1 (code, type, node); + break; + } + if (TREE_SIDE_EFFECTS (node)) TREE_SIDE_EFFECTS (item) = 1; if ((code == ADDR_EXPR) && staticp (node)) @@ -9289,7 +9967,158 @@ ffecom_2 (enum tree_code code, tree type, tree node1, || (type == error_mark_node)) return error_mark_node; - item = build (code, type, node1, node2); + switch (ffe_is_emulate_complex () ? code : NOP_EXPR) + { + tree a, b, c, d, realtype; + + case CONJ_EXPR: + assert ("no CONJ_EXPR support yet" == NULL); + return error_mark_node; + + case COMPLEX_EXPR: + item = build_tree_list (TYPE_FIELDS (type), node1); + TREE_CHAIN (item) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), node2); + item = build (CONSTRUCTOR, type, NULL_TREE, item); + break; + + case PLUS_EXPR: + if (TREE_CODE (type) != RECORD_TYPE) + { + item = build (code, type, node1, node2); + break; + } + node1 = ffecom_stabilize_aggregate_ (node1); + node2 = ffecom_stabilize_aggregate_ (node2); + realtype = TREE_TYPE (TYPE_FIELDS (type)); + item = + ffecom_2 (COMPLEX_EXPR, type, + ffecom_2 (PLUS_EXPR, realtype, + ffecom_1 (REALPART_EXPR, realtype, + node1), + ffecom_1 (REALPART_EXPR, realtype, + node2)), + ffecom_2 (PLUS_EXPR, realtype, + ffecom_1 (IMAGPART_EXPR, realtype, + node1), + ffecom_1 (IMAGPART_EXPR, realtype, + node2))); + break; + + case MINUS_EXPR: + if (TREE_CODE (type) != RECORD_TYPE) + { + item = build (code, type, node1, node2); + break; + } + node1 = ffecom_stabilize_aggregate_ (node1); + node2 = ffecom_stabilize_aggregate_ (node2); + realtype = TREE_TYPE (TYPE_FIELDS (type)); + item = + ffecom_2 (COMPLEX_EXPR, type, + ffecom_2 (MINUS_EXPR, realtype, + ffecom_1 (REALPART_EXPR, realtype, + node1), + ffecom_1 (REALPART_EXPR, realtype, + node2)), + ffecom_2 (MINUS_EXPR, realtype, + ffecom_1 (IMAGPART_EXPR, realtype, + node1), + ffecom_1 (IMAGPART_EXPR, realtype, + node2))); + break; + + case MULT_EXPR: + if (TREE_CODE (type) != RECORD_TYPE) + { + item = build (code, type, node1, node2); + break; + } + node1 = ffecom_stabilize_aggregate_ (node1); + node2 = ffecom_stabilize_aggregate_ (node2); + realtype = TREE_TYPE (TYPE_FIELDS (type)); + a = save_expr (ffecom_1 (REALPART_EXPR, realtype, + node1)); + b = save_expr (ffecom_1 (IMAGPART_EXPR, realtype, + node1)); + c = save_expr (ffecom_1 (REALPART_EXPR, realtype, + node2)); + d = save_expr (ffecom_1 (IMAGPART_EXPR, realtype, + node2)); + item = + ffecom_2 (COMPLEX_EXPR, type, + ffecom_2 (MINUS_EXPR, realtype, + ffecom_2 (MULT_EXPR, realtype, + a, + c), + ffecom_2 (MULT_EXPR, realtype, + b, + d)), + ffecom_2 (PLUS_EXPR, realtype, + ffecom_2 (MULT_EXPR, realtype, + a, + d), + ffecom_2 (MULT_EXPR, realtype, + c, + b))); + break; + + case EQ_EXPR: + if ((TREE_CODE (node1) != RECORD_TYPE) + && (TREE_CODE (node2) != RECORD_TYPE)) + { + item = build (code, type, node1, node2); + break; + } + assert (TREE_CODE (node1) == RECORD_TYPE); + assert (TREE_CODE (node2) == RECORD_TYPE); + node1 = ffecom_stabilize_aggregate_ (node1); + node2 = ffecom_stabilize_aggregate_ (node2); + realtype = TREE_TYPE (TYPE_FIELDS (type)); + item = + ffecom_2 (TRUTH_ANDIF_EXPR, type, + ffecom_2 (code, type, + ffecom_1 (REALPART_EXPR, realtype, + node1), + ffecom_1 (REALPART_EXPR, realtype, + node2)), + ffecom_2 (code, type, + ffecom_1 (IMAGPART_EXPR, realtype, + node1), + ffecom_1 (IMAGPART_EXPR, realtype, + node2))); + break; + + case NE_EXPR: + if ((TREE_CODE (node1) != RECORD_TYPE) + && (TREE_CODE (node2) != RECORD_TYPE)) + { + item = build (code, type, node1, node2); + break; + } + assert (TREE_CODE (node1) == RECORD_TYPE); + assert (TREE_CODE (node2) == RECORD_TYPE); + node1 = ffecom_stabilize_aggregate_ (node1); + node2 = ffecom_stabilize_aggregate_ (node2); + realtype = TREE_TYPE (TYPE_FIELDS (type)); + item = + ffecom_2 (TRUTH_ORIF_EXPR, type, + ffecom_2 (code, type, + ffecom_1 (REALPART_EXPR, realtype, + node1), + ffecom_1 (REALPART_EXPR, realtype, + node2)), + ffecom_2 (code, type, + ffecom_1 (IMAGPART_EXPR, realtype, + node1), + ffecom_1 (IMAGPART_EXPR, realtype, + node2))); + break; + + default: + item = build (code, type, node1, node2); + break; + } + if (TREE_SIDE_EFFECTS (node1) || TREE_SIDE_EFFECTS (node2)) TREE_SIDE_EFFECTS (item) = 1; return fold (item); @@ -10006,9 +10835,9 @@ ffecom_constantunion (ffebldConstantUnion *cu, ffeinfoBasictype bt, case FFEINFO_kindtypeANY: return error_mark_node; } - item = build_complex (build_real (el_type, real), - build_real (el_type, imag)); - TREE_TYPE (item) = tree_type; + item = ffecom_build_complex_constant_ (tree_type, + build_real (el_type, real), + build_real (el_type, imag)); } break; @@ -10465,39 +11294,40 @@ ffecom_init_0 () whether the compiler environment is buggy in known ways, some of which would, if not explicitly checked here, result in subtle bugs in g77. */ - { - static char names[][12] - = - {"bar", "bletch", "foo", "foobar"}; - char *name; - unsigned long ul; - double fl; - - name = bsearch ("foo", &names[0], ARRAY_SIZE (names), sizeof (names[0]), - (int (*)()) strcmp); - if (name != (char *) &names[2]) - { - assert ("bsearch doesn't work, #define FFEPROJ_BSEARCH 0 in proj.h" - == NULL); - abort (); - } + if (ffe_is_do_internal_checks ()) + { + static char names[][12] + = + {"bar", "bletch", "foo", "foobar"}; + char *name; + unsigned long ul; + double fl; - ul = strtoul ("123456789", NULL, 10); - if (ul != 123456789L) - { - assert ("strtoul doesn't have enough range, #define FFEPROJ_STRTOUL 0\ + name = bsearch ("foo", &names[0], ARRAY_SIZE (names), sizeof (names[0]), + (int (*)()) strcmp); + if (name != (char *) &names[2]) + { + assert ("bsearch doesn't work, #define FFEPROJ_BSEARCH 0 in proj.h" + == NULL); + abort (); + } + + ul = strtoul ("123456789", NULL, 10); + if (ul != 123456789L) + { + assert ("strtoul doesn't have enough range, #define FFEPROJ_STRTOUL 0\ in proj.h" == NULL); - abort (); - } + abort (); + } - fl = atof ("56.789"); - if ((fl < 56.788) || (fl > 56.79)) - { - assert ("atof not type double, fix your #include <stdio.h>" - == NULL); - abort (); - } - } + fl = atof ("56.789"); + if ((fl < 56.788) || (fl > 56.79)) + { + assert ("atof not type double, fix your #include <stdio.h>" + == NULL); + abort (); + } + } #if FFECOM_GCC_INCLUDE ffecom_initialize_char_syntax_ (); @@ -10575,45 +11405,37 @@ ffecom_init_0 () float_type_node = make_node (REAL_TYPE); TYPE_PRECISION (float_type_node) = FLOAT_TYPE_SIZE; + layout_type (float_type_node); pushdecl (build_decl (TYPE_DECL, get_identifier ("float"), float_type_node)); - layout_type (float_type_node); double_type_node = make_node (REAL_TYPE); TYPE_PRECISION (double_type_node) = DOUBLE_TYPE_SIZE; + layout_type (double_type_node); pushdecl (build_decl (TYPE_DECL, get_identifier ("double"), double_type_node)); - layout_type (double_type_node); long_double_type_node = make_node (REAL_TYPE); TYPE_PRECISION (long_double_type_node) = LONG_DOUBLE_TYPE_SIZE; + layout_type (long_double_type_node); pushdecl (build_decl (TYPE_DECL, get_identifier ("long double"), long_double_type_node)); - layout_type (long_double_type_node); - complex_integer_type_node = make_node (COMPLEX_TYPE); + complex_integer_type_node = ffecom_make_complex_type_ (integer_type_node); pushdecl (build_decl (TYPE_DECL, get_identifier ("complex int"), complex_integer_type_node)); - TREE_TYPE (complex_integer_type_node) = integer_type_node; - layout_type (complex_integer_type_node); - complex_float_type_node = make_node (COMPLEX_TYPE); + complex_float_type_node = ffecom_make_complex_type_ (float_type_node); pushdecl (build_decl (TYPE_DECL, get_identifier ("complex float"), complex_float_type_node)); - TREE_TYPE (complex_float_type_node) = float_type_node; - layout_type (complex_float_type_node); - complex_double_type_node = make_node (COMPLEX_TYPE); + complex_double_type_node = ffecom_make_complex_type_ (double_type_node); pushdecl (build_decl (TYPE_DECL, get_identifier ("complex double"), complex_double_type_node)); - TREE_TYPE (complex_double_type_node) = double_type_node; - layout_type (complex_double_type_node); - complex_long_double_type_node = make_node (COMPLEX_TYPE); + complex_long_double_type_node = ffecom_make_complex_type_ (long_double_type_node); pushdecl (build_decl (TYPE_DECL, get_identifier ("complex long double"), complex_long_double_type_node)); - TREE_TYPE (complex_long_double_type_node) = long_double_type_node; - layout_type (complex_long_double_type_node); integer_zero_node = build_int_2 (0, 0); TREE_TYPE (integer_zero_node) = integer_type_node; @@ -10710,7 +11532,7 @@ ffecom_init_0 () ffetype_set_star (base_type, TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE, type); - ffetype_set_kind (base_type, 2, type); + ffetype_set_kind (base_type, 3, type); assert (ffetype_size (type) == sizeof (ffetargetInteger2)); ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER2] @@ -10719,7 +11541,7 @@ ffecom_init_0 () t)); ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER3] - = t = make_signed_type (SHORT_TYPE_SIZE); + = t = make_signed_type (CHAR_TYPE_SIZE * 2); pushdecl (build_decl (TYPE_DECL, get_identifier ("word"), t)); type = ffetype_new (); @@ -10731,16 +11553,16 @@ ffecom_init_0 () ffetype_set_star (base_type, TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE, type); - ffetype_set_kind (base_type, 3, type); + ffetype_set_kind (base_type, 6, type); assert (ffetype_size (type) == sizeof (ffetargetInteger3)); ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER3] - = t = make_unsigned_type (SHORT_TYPE_SIZE); + = t = make_unsigned_type (CHAR_TYPE_SIZE * 2); pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned word"), t)); ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER4] - = t = make_signed_type (LONG_LONG_TYPE_SIZE); + = t = make_signed_type (FLOAT_TYPE_SIZE * 2); pushdecl (build_decl (TYPE_DECL, get_identifier ("integer4"), t)); type = ffetype_new (); @@ -10752,15 +11574,17 @@ ffecom_init_0 () ffetype_set_star (base_type, TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE, type); - ffetype_set_kind (base_type, 4, type); + ffetype_set_kind (base_type, 2, type); assert (ffetype_size (type) == sizeof (ffetargetInteger4)); ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER4] - = t = make_unsigned_type (LONG_LONG_TYPE_SIZE); + = t = make_unsigned_type (FLOAT_TYPE_SIZE * 2); pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned4"), t)); - if (LONG_TYPE_SIZE != FLOAT_TYPE_SIZE +#if 0 + if (ffe_is_do_internal_checks () + && LONG_TYPE_SIZE != FLOAT_TYPE_SIZE && LONG_TYPE_SIZE != CHAR_TYPE_SIZE && LONG_TYPE_SIZE != SHORT_TYPE_SIZE && LONG_TYPE_SIZE != LONG_LONG_TYPE_SIZE) @@ -10768,6 +11592,7 @@ ffecom_init_0 () fprintf (stderr, "Sorry, no g77 support for LONG_TYPE_SIZE (%d bits) yet.\n", LONG_TYPE_SIZE); } +#endif ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL1] = t = make_signed_type (FLOAT_TYPE_SIZE); @@ -10799,11 +11624,11 @@ ffecom_init_0 () ffetype_set_star (base_type, TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE, type); - ffetype_set_kind (base_type, 2, type); + ffetype_set_kind (base_type, 3, type); assert (ffetype_size (type) == sizeof (ffetargetLogical2)); ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL3] - = t = make_signed_type (SHORT_TYPE_SIZE); + = t = make_signed_type (CHAR_TYPE_SIZE * 2); pushdecl (build_decl (TYPE_DECL, get_identifier ("logical3"), t)); type = ffetype_new (); @@ -10815,11 +11640,11 @@ ffecom_init_0 () ffetype_set_star (base_type, TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE, type); - ffetype_set_kind (base_type, 3, type); + ffetype_set_kind (base_type, 6, type); assert (ffetype_size (type) == sizeof (ffetargetLogical3)); ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL4] - = t = make_signed_type (LONG_LONG_TYPE_SIZE); + = t = make_signed_type (FLOAT_TYPE_SIZE * 2); pushdecl (build_decl (TYPE_DECL, get_identifier ("logical4"), t)); type = ffetype_new (); @@ -10831,7 +11656,7 @@ ffecom_init_0 () ffetype_set_star (base_type, TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE, type); - ffetype_set_kind (base_type, 4, type); + ffetype_set_kind (base_type, 2, type); assert (ffetype_size (type) == sizeof (ffetargetLogical4)); ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1] @@ -10846,9 +11671,9 @@ ffecom_init_0 () type); ffetype_set_ams (type, TYPE_ALIGN (t) / BITS_PER_UNIT, 0, - TYPE_PRECISION (t) / BITS_PER_UNIT); + TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT); ffetype_set_star (base_type, - TYPE_PRECISION (t) / CHAR_TYPE_SIZE, + TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE, type); ffetype_set_kind (base_type, 1, type); ffecom_f2c_typecode_[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1] @@ -10866,9 +11691,9 @@ ffecom_init_0 () type); ffetype_set_ams (type, TYPE_ALIGN (t) / BITS_PER_UNIT, 0, - TYPE_PRECISION (t) / BITS_PER_UNIT); + TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT); ffetype_set_star (base_type, - TYPE_PRECISION (t) / CHAR_TYPE_SIZE, + TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE, type); ffetype_set_kind (base_type, 2, type); ffecom_f2c_typecode_[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2] @@ -10876,21 +11701,18 @@ ffecom_init_0 () assert (ffetype_size (type) == sizeof (ffetargetReal2)); ffecom_tree_type[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL1] - = t = make_node (COMPLEX_TYPE); + = t = ffecom_make_complex_type_ (ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]); pushdecl (build_decl (TYPE_DECL, get_identifier ("complex"), t)); - TREE_TYPE (t) - = ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]; - layout_type (t); type = ffetype_new (); base_type = type; ffeinfo_set_type (FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREAL1, type); ffetype_set_ams (type, - TYPE_ALIGN (TREE_TYPE (t)) / BITS_PER_UNIT, 0, - TYPE_PRECISION (TREE_TYPE (t)) * 2 / BITS_PER_UNIT); + TYPE_ALIGN (t) / BITS_PER_UNIT, 0, + TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT); ffetype_set_star (base_type, - TYPE_PRECISION (TREE_TYPE (t)) * 2 / CHAR_TYPE_SIZE, + TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE, type); ffetype_set_kind (base_type, 1, type); ffecom_f2c_typecode_[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL1] @@ -10898,20 +11720,17 @@ ffecom_init_0 () assert (ffetype_size (type) == sizeof (ffetargetComplex1)); ffecom_tree_type[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREALDOUBLE] - = t = make_node (COMPLEX_TYPE); + = t = ffecom_make_complex_type_ (ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2]); pushdecl (build_decl (TYPE_DECL, get_identifier ("double complex"), t)); - TREE_TYPE (t) - = ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2]; - layout_type (t); type = ffetype_new (); ffeinfo_set_type (FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREALDOUBLE, type); ffetype_set_ams (type, - TYPE_ALIGN (TREE_TYPE (t)) / BITS_PER_UNIT, 0, - TYPE_PRECISION (TREE_TYPE (t)) * 2 / BITS_PER_UNIT); + TYPE_ALIGN (t) / BITS_PER_UNIT, 0, + TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT); ffetype_set_star (base_type, - TYPE_PRECISION (TREE_TYPE (t)) * 2 / CHAR_TYPE_SIZE, + TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE, type); ffetype_set_kind (base_type, 2, type); @@ -10926,7 +11745,20 @@ ffecom_init_0 () { if ((t = ffecom_tree_type[i][j]) != NULL_TREE) { - if (i == FFEINFO_basictypeCOMPLEX) + if (i == FFEINFO_basictypeINTEGER) + { + /* Figure out the smallest INTEGER type that can hold + a pointer on this machine. */ + if (GET_MODE_SIZE (TYPE_MODE (t)) + >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node)))) + { + if ((ffecom_pointer_kind_ == FFEINFO_kindtypeNONE) + || (GET_MODE_SIZE (TYPE_MODE (ffecom_tree_type[i][ffecom_pointer_kind_])) + > GET_MODE_SIZE (TYPE_MODE (t)))) + ffecom_pointer_kind_ = j; + } + } + else if (i == FFEINFO_basictypeCOMPLEX) t = void_type_node; /* For f2c compatibility, REAL functions are really implemented as DOUBLE PRECISION. */ @@ -10941,6 +11773,26 @@ ffecom_init_0 () } } + /* Set up pointer types. */ + + if (ffecom_pointer_kind_ == FFEINFO_basictypeNONE) + fatal ("no INTEGER type can hold a pointer on this configuration"); + else if (0 && ffe_is_do_internal_checks ()) + fprintf (stderr, "Pointer type kt=%d\n", ffecom_pointer_kind_); +#if 0 + type = ffetype_new (); + ffetype_set_kind (ffeinfo_type (FFEINFO_basictypeINTEGER, + FFEINFO_kindtypeINTEGERDEFAULT), + 0, type); +#endif + + if (ffe_is_ugly_assign ()) + ffecom_label_kind_ = ffecom_pointer_kind_; /* Require ASSIGN etc to this. */ + else + ffecom_label_kind_ = FFEINFO_kindtypeINTEGERDEFAULT; + if (0 && ffe_is_do_internal_checks ()) + fprintf (stderr, "Label type kt=%d\n", ffecom_label_kind_); + ffecom_integer_type_node = ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER1]; ffecom_integer_zero_node = convert (ffecom_integer_type_node, @@ -11115,6 +11967,12 @@ ffecom_init_0 () ffecom_f2c_ptr_to_ftnint_type_node = build_pointer_type (ffecom_f2c_ftnint_type_node); + ffecom_f2c_ptr_to_integer_type_node + = build_pointer_type (ffecom_f2c_integer_type_node); + + ffecom_f2c_ptr_to_real_type_node + = build_pointer_type (ffecom_f2c_real_type_node); + ffecom_float_zero_ = build_real (float_type_node, dconst0); ffecom_double_zero_ = build_real (double_type_node, dconst0); { @@ -11140,6 +11998,7 @@ ffecom_init_0 () ffecom_tree_xargc_ = start_decl (ffecom_tree_xargc_, FALSE); finish_decl (ffecom_tree_xargc_, NULL_TREE, FALSE); +#if 0 /* This is being fixed, and seems to be working now. */ if ((FLOAT_TYPE_SIZE != 32) || (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node))) != 32)) { @@ -11151,6 +12010,7 @@ ffecom_init_0 () warning ("Please keep this in mind before you report bugs. g77 should"); warning ("support non-32-bit machines better as of version 0.6."); } +#endif #if 0 /* Code in ste.c that would crash has been commented out. */ if (TYPE_PRECISION (ffecom_f2c_ftnlen_type_node) @@ -11791,7 +12651,9 @@ ffecom_ptr_to_expr (ffebld expr) || (TREE_CODE (item) == INDIRECT_REF) || (TREE_CODE (item) == ARRAY_REF) || (TREE_CODE (item) == COMPONENT_REF) +#ifdef OFFSET_REF || (TREE_CODE (item) == OFFSET_REF) +#endif || (TREE_CODE (item) == BUFFER_REF) || (TREE_CODE (item) == REALPART_EXPR) || (TREE_CODE (item) == IMAGPART_EXPR)) @@ -13300,21 +14162,25 @@ convert (type, expr) register tree e = expr; register enum tree_code code = TREE_CODE (type); - if (type == TREE_TYPE (expr) - || TREE_CODE (expr) == ERROR_MARK) - return expr; - if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr))) - return fold (build1 (NOP_EXPR, type, expr)); - if (TREE_CODE (TREE_TYPE (expr)) == ERROR_MARK + if (type == TREE_TYPE (e) + || TREE_CODE (e) == ERROR_MARK) + return e; + if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e))) + return fold (build1 (NOP_EXPR, type, e)); + if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK || code == ERROR_MARK) return error_mark_node; - if (TREE_CODE (TREE_TYPE (expr)) == VOID_TYPE) + if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE) { assert ("void value not ignored as it ought to be" == NULL); return error_mark_node; } if (code == VOID_TYPE) return build1 (CONVERT_EXPR, type, e); + if ((code != RECORD_TYPE) + && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE)) + e = ffecom_1 (REALPART_EXPR, TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e))), + e); if (code == INTEGER_TYPE || code == ENUMERAL_TYPE) return fold (convert_to_integer (type, e)); if (code == POINTER_TYPE) @@ -13323,6 +14189,8 @@ convert (type, expr) return fold (convert_to_real (type, e)); if (code == COMPLEX_TYPE) return fold (convert_to_complex (type, e)); + if (code == RECORD_TYPE) + return fold (ffecom_convert_to_complex_ (type, e)); assert ("conversion to non-scalar type requested" == NULL); return error_mark_node; diff --git a/gnu/usr.bin/gcc/f/com.h b/gnu/usr.bin/gcc/f/com.h index 542b9ba8d6e..c01c74c2e72 100644 --- a/gnu/usr.bin/gcc/f/com.h +++ b/gnu/usr.bin/gcc/f/com.h @@ -1,5 +1,5 @@ /* com.h -- Public #include File (module.h template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995-1997 Free Software Foundation, Inc. Contributed by James Craig Burley (burley@gnu.ai.mit.edu). This file is part of GNU Fortran. @@ -138,6 +138,14 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA # error Cannot find a suitable type for FFECOM_f2cINTEGER #endif +#if LONG_TYPE_SIZE == (FLOAT_TYPE_SIZE * 2) +# define FFECOM_f2cLONGINT FFECOM_f2ccodeLONG +#elif LONG_LONG_TYPE_SIZE == (FLOAT_TYPE_SIZE * 2) +# define FFECOM_f2cLONGINT FFECOM_f2ccodeLONGLONG +#else +# error Cannot find a suitable type for FFECOM_f2cLONGINT +#endif + #define FFECOM_f2cADDRESS FFECOM_f2ccodeCHARPTR #define FFECOM_f2cSHORTINT FFECOM_f2ccodeSHORT #define FFECOM_f2cREAL FFECOM_f2ccodeFLOAT @@ -147,7 +155,6 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA #define FFECOM_f2cSHORTLOGICAL FFECOM_f2ccodeSHORT #define FFECOM_f2cLOGICAL1 FFECOM_f2ccodeCHAR #define FFECOM_f2cINTEGER1 FFECOM_f2ccodeCHAR -#define FFECOM_f2cLONGINT FFECOM_f2ccodeLONGLONG /* These must be f2c's INTEGER type, to match runtime/f2c.h.in. */ @@ -187,6 +194,14 @@ typedef enum #endif #endif /* !defined (BUILT_FOR_270) */ +#ifndef BUILT_FOR_280 +#ifdef DECL_ONE_ONLY /* In gcc/tree.h. */ +#define BUILT_FOR_280 1 +#else +#define BUILT_FOR_280 0 +#endif +#endif /* !defined (BUILT_FOR_280) */ + typedef tree ffecomConstant; #define FFECOM_constantHOOK typedef tree ffecomLabel; @@ -230,6 +245,8 @@ extern tree ffecom_integer_zero_node; extern tree ffecom_integer_one_node; extern tree ffecom_tree_type[FFEINFO_basictype][FFEINFO_kindtype]; extern ffecomSymbol ffecom_symbol_null_; +extern ffeinfoKindtype ffecom_pointer_kind_; +extern ffeinfoKindtype ffecom_label_kind_; extern int ffecom_f2c_typecode_[FFEINFO_basictype][FFEINFO_kindtype]; extern tree ffecom_f2c_integer_type_node; @@ -373,6 +390,8 @@ void warning (char *s, ...); #define ffecom_expr(e) (e) #define ffecom_init_0() #define ffecom_init_2() +#define ffecom_label_kind() FFEINFO_kindtypeINTEGERDEFAULT +#define ffecom_pointer_kind() FFEINFO_kindtypeINTEGERDEFAULT #define ffecom_ptr_to_expr(e) (e) #define ffecom_sym_commit(s) #define ffecom_sym_retract(s) @@ -380,6 +399,8 @@ void warning (char *s, ...); #if FFECOM_targetCURRENT == FFECOM_targetGCC #define ffecom_f2c_typecode(bt,kt) ffecom_f2c_typecode_[(bt)][(kt)] +#define ffecom_label_kind() ffecom_label_kind_ +#define ffecom_pointer_kind() ffecom_pointer_kind_ #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */ #define ffecom_init_1() diff --git a/gnu/usr.bin/gcc/f/config-lang.in b/gnu/usr.bin/gcc/f/config-lang.in index fc0240aef59..74626241d8c 100644 --- a/gnu/usr.bin/gcc/f/config-lang.in +++ b/gnu/usr.bin/gcc/f/config-lang.in @@ -1,5 +1,5 @@ # Top level configure fragment for GNU FORTRAN. -# Copyright (C) 1995 Free Software Foundation, Inc. +# Copyright (C) 1995-1997 Free Software Foundation, Inc. #This file is part of GNU Fortran. @@ -62,8 +62,9 @@ diff_excludes="-x \"f/g77.info*\"" # Create the runtime library directory tree if necessary. test -d f || mkdir f test -d f/runtime || mkdir f/runtime -test -d f/runtime/libI77 || mkdir f/runtime/libI77 test -d f/runtime/libF77 || mkdir f/runtime/libF77 +test -d f/runtime/libI77 || mkdir f/runtime/libI77 +test -d f/runtime/libU77 || mkdir f/runtime/libU77 # Need to make top-level stageN directory trees, else if needed # later by gcc/Makefile, it'll make only the first levels and @@ -75,17 +76,19 @@ do test -d $stageN/f/runtime || mkdir $stageN/f/runtime test -d $stageN/f/runtime/libF77 || mkdir $stageN/f/runtime/libF77 test -d $stageN/f/runtime/libI77 || mkdir $stageN/f/runtime/libI77 + test -d $stageN/f/runtime/libU77 || mkdir $stageN/f/runtime/libU77 done # Make links into top-level stageN from target trees. for stageN in stage1 stage2 stage3 stage4 include do $remove -f f/$stageN f/runtime/$stageN f/runtime/libF77/$stageN \ - f/runtime/libI77/$stageN + f/runtime/libI77/$stageN f/runtime/libU77/$stageN (cd f; $symbolic_link ../$stageN . 2>/dev/null) (cd f/runtime; $symbolic_link ../$stageN . 2>/dev/null) (cd f/runtime/libF77; $symbolic_link ../$stageN . 2>/dev/null) (cd f/runtime/libI77; $symbolic_link ../$stageN . 2>/dev/null) + (cd f/runtime/libU77; $symbolic_link ../$stageN . 2>/dev/null) done case "$srcdir" in diff --git a/gnu/usr.bin/gcc/f/data.c b/gnu/usr.bin/gcc/f/data.c index 16864e00c6f..15bf3b00cbb 100644 --- a/gnu/usr.bin/gcc/f/data.c +++ b/gnu/usr.bin/gcc/f/data.c @@ -1,5 +1,5 @@ /* data.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995, 1996 Free Software Foundation, Inc. Contributed by James Craig Burley (burley@gnu.ai.mit.edu). This file is part of GNU Fortran. @@ -287,7 +287,7 @@ ffedata_value (ffetargetIntegerDefault rpt, ffebld value, ffelexToken token) { ffesymbol_signal_change (ffedata_symbol_); ffesymbol_update_init (ffedata_symbol_); - if (ffe_is_90 ()) + if (1 || ffe_is_90 ()) ffesymbol_update_save (ffedata_symbol_); #if FFEGLOBAL_ENABLED if (ffesymbol_common (ffedata_symbol_) != NULL) @@ -1231,7 +1231,7 @@ ffedata_gather_ (ffestorag mst, ffestorag st) else { accter = ffestorag_accretion (mst); - assert (ffedata_storage_size_ == ffebld_accter_size (accter)); + assert (ffedata_storage_size_ == (ffetargetOffset) ffebld_accter_size (accter)); array = ffebld_accter (accter); } @@ -1251,7 +1251,7 @@ ffedata_gather_ (ffestorag mst, ffestorag st) operation. */ ffebit_count (ffebld_accter_bits (accter), offset, FALSE, units_expected, &actual); /* How many FALSE? */ - if (actual != units_expected) + if (units_expected != (ffetargetOffset) actual) { ffebad_start (FFEBAD_DATA_MULTIPLE); ffebad_here (0, ffewhere_line_unknown (), ffewhere_column_unknown ()); @@ -1291,7 +1291,7 @@ ffedata_gather_ (ffestorag mst, ffestorag st) operation. */ ffebit_count (ffebld_accter_bits (accter), offset, FALSE, units_expected, &actual); /* How many FALSE? */ - if (actual != units_expected) + if (units_expected != (ffetargetOffset) actual) { ffebad_start (FFEBAD_DATA_MULTIPLE); ffebad_here (0, ffewhere_line_unknown (), ffewhere_column_unknown ()); @@ -1345,7 +1345,7 @@ ffedata_gather_ (ffestorag mst, ffestorag st) (*fn) (ptr1, ptr2, siz); /* Does memcpy-like operation. */ ffebit_count (ffebld_accter_bits (accter), /* How many FALSE? */ offset, FALSE, unexp, &actual); - if (!whine && (actual != unexp)) + if (!whine && (unexp != (ffetargetOffset) actual)) { whine = TRUE; /* Don't whine more than once for one gather. */ ffebad_start (FFEBAD_DATA_MULTIPLE); @@ -1608,7 +1608,7 @@ ffedata_value_ (ffebld value, ffelexToken token) else { accter = ffestorag_accretion (ffedata_storage_); - assert (ffedata_storage_size_ == ffebld_accter_size (accter)); + assert (ffedata_storage_size_ == (ffetargetOffset) ffebld_accter_size (accter)); array = ffebld_accter (accter); } @@ -1627,7 +1627,7 @@ ffedata_value_ (ffebld value, ffelexToken token) ffebit_count (ffebld_accter_bits (accter), offset, FALSE, units_expected, &actual); /* How many FALSE? */ - if (actual != units_expected) + if (units_expected != (ffetargetOffset) actual) { ffebad_start (FFEBAD_DATA_MULTIPLE); ffebad_here (0, ffelex_token_where_line (token), @@ -1744,7 +1744,7 @@ ffedata_value_ (ffebld value, ffelexToken token) { accter = ffesymbol_accretion (ffedata_symbol_); assert (ffedata_symbolsize_ - == ffebld_accter_size (accter)); + == (ffetargetOffset) ffebld_accter_size (accter)); array = ffebld_accter (accter); } diff --git a/gnu/usr.bin/gcc/f/equiv.c b/gnu/usr.bin/gcc/f/equiv.c index 0dc60d85e01..d6ef0bab563 100644 --- a/gnu/usr.bin/gcc/f/equiv.c +++ b/gnu/usr.bin/gcc/f/equiv.c @@ -1,5 +1,5 @@ /* equiv.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995-1997 Free Software Foundation, Inc. Contributed by James Craig Burley (burley@gnu.ai.mit.edu). This file is part of GNU Fortran. @@ -69,6 +69,7 @@ static struct _ffeequiv_list_ ffeequiv_list_; /* Static functions (internal). */ +static void ffeequiv_destroy_ (ffeequiv eq); static void ffeequiv_layout_local_ (ffeequiv eq); static bool ffeequiv_offset_ (ffetargetOffset *offset, ffesymbol s, ffebld expr, bool subtract, @@ -77,6 +78,30 @@ static bool ffeequiv_offset_ (ffetargetOffset *offset, ffesymbol s, /* Internal macros. */ +static void +ffeequiv_destroy_ (ffeequiv victim) +{ + ffebld list; + ffebld item; + ffebld expr; + + for (list = victim->list; list != NULL; list = ffebld_trail (list)) + { + for (item = ffebld_head (list); item != NULL; item = ffebld_trail (item)) + { + ffesymbol sym; + + expr = ffebld_head (item); + sym = ffeequiv_symbol (expr); + if (sym == NULL) + continue; + if (ffesymbol_equiv (sym) != NULL) + ffesymbol_set_equiv (sym, NULL); + } + } + ffeequiv_kill (victim); +} + /* ffeequiv_layout_local_ -- Lay out storage for local equivalenced vars ffeequiv eq; @@ -116,7 +141,7 @@ ffeequiv_layout_local_ (ffeequiv eq) if (ffeequiv_common (eq) != NULL) { /* Put in common due to programmer error. */ - ffeequiv_kill (eq); + ffeequiv_destroy_ (eq); return; } @@ -151,10 +176,13 @@ ffeequiv_layout_local_ (ffeequiv eq) if (!ffeequiv_offset_ (&ign, root_sym, root_exp, FALSE, 0, FALSE)) { - ffesymbol_set_equiv (root_sym, NULL); /* Equiv area slated for - death. */ - root_sym = NULL; - continue; /* Something's wrong with eqv expr, try another. */ + /* We can't just eliminate this one symbol from the list + of candidates, because it might be the only one that + ties all these equivs together. So just destroy the + whole list. */ + + ffeequiv_destroy_ (eq); + return; } break; /* Use first valid eqv expr for root exp/sym. */ @@ -165,7 +193,7 @@ ffeequiv_layout_local_ (ffeequiv eq) if (root_sym == NULL) { - ffeequiv_kill (eq); + ffeequiv_destroy_ (eq); return; } @@ -269,7 +297,7 @@ ffeequiv_layout_local_ (ffeequiv eq) rooted_exp = ffebld_head (item); rooted_sym = ffeequiv_symbol (rooted_exp); if ((rooted_sym == NULL) - || (ffesymbol_equiv (rooted_sym) == NULL)) + || ((rooted_st = ffesymbol_storage (rooted_sym)) == NULL)) { rooted_sym = NULL; continue; /* Ignore me. */ @@ -277,11 +305,6 @@ ffeequiv_layout_local_ (ffeequiv eq) need_storage = TRUE; /* Somebody is likely to need storage. */ - if ((rooted_st = ffesymbol_storage (rooted_sym)) == NULL) - { - rooted_sym = NULL; - continue; /* No storage for this guy, try another. */ - } #if FFEEQUIV_DEBUG fprintf (stderr, " Rooted: `%s' at %" ffetargetOffset_f "d\n", @@ -384,6 +407,7 @@ ffeequiv_layout_local_ (ffeequiv eq) ffebad_start (FFEBAD_EQUIV_ALIGN); ffebad_string (ffesymbol_text (item_sym)); ffebad_finish (); + ffesymbol_set_equiv (item_sym, NULL); /* Don't bother with me anymore. */ continue; } @@ -495,12 +519,15 @@ ffeequiv_layout_local_ (ffeequiv eq) ffebad_finish (); } } + ffesymbol_set_equiv (item_sym, NULL); /* Don't bother with me anymore. */ } /* (For every equivalence item in the list) */ ffebld_set_head (list, NULL); /* Don't do this list again. */ } /* (For every equivalence list in the list of equivs) */ } while (new_storage && need_storage); + ffesymbol_set_equiv (root_sym, NULL); /* This one has storage now. */ + ffeequiv_kill (eq); /* Fully processed, no longer needed. */ if (init) @@ -873,6 +900,31 @@ ffeequiv_kill (ffeequiv victim) { victim->next->previous = victim->previous; victim->previous->next = victim->next; + if (ffe_is_do_internal_checks ()) + { + ffebld list; + ffebld item; + ffebld expr; + + /* Assert that nobody our victim points to still points to it. */ + + assert ((victim->common == NULL) + || (ffesymbol_equiv (victim->common) == NULL)); + + for (list = victim->list; list != NULL; list = ffebld_trail (list)) + { + for (item = ffebld_head (list); item != NULL; item = ffebld_trail (item)) + { + ffesymbol sym; + + expr = ffebld_head (item); + sym = ffeequiv_symbol (expr); + if (sym == NULL) + continue; + assert (ffesymbol_equiv (sym) != victim); + } + } + } malloc_kill_ks (ffe_pool_program_unit (), victim, sizeof (*victim)); } diff --git a/gnu/usr.bin/gcc/f/equiv.h b/gnu/usr.bin/gcc/f/equiv.h index e0993a34560..225cafded1b 100644 --- a/gnu/usr.bin/gcc/f/equiv.h +++ b/gnu/usr.bin/gcc/f/equiv.h @@ -1,5 +1,5 @@ /* equiv.h -- Public #include File (module.h template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995, 1996 Free Software Foundation, Inc. Contributed by James Craig Burley (burley@gnu.ai.mit.edu). This file is part of GNU Fortran. diff --git a/gnu/usr.bin/gcc/f/expr.c b/gnu/usr.bin/gcc/f/expr.c index b1ec1d46be2..47ab53fa008 100644 --- a/gnu/usr.bin/gcc/f/expr.c +++ b/gnu/usr.bin/gcc/f/expr.c @@ -1,5 +1,5 @@ /* expr.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995-1997 Free Software Foundation, Inc. Contributed by James Craig Burley (burley@gnu.ai.mit.edu). This file is part of GNU Fortran. @@ -37,6 +37,7 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "bld.h" #include "com.h" #include "implic.h" +#include "intrin.h" #include "info.h" #include "lex.h" #include "malloc.h" @@ -402,6 +403,7 @@ static ffelexHandler ffeexpr_token_substring_ (ffelexToken ft, ffebld expr, static ffelexHandler ffeexpr_token_substring_1_ (ffelexToken ft, ffebld expr, ffelexToken t); static ffelexHandler ffeexpr_token_substrp_ (ffelexToken t); +static ffelexHandler ffeexpr_token_intrincheck_ (ffelexToken t); static ffelexHandler ffeexpr_token_funsubstr_ (ffelexToken ft, ffebld expr, ffelexToken t); static ffelexHandler ffeexpr_token_anything_ (ffelexToken ft, ffebld expr, @@ -8095,7 +8097,7 @@ ffeexpr_cb_end_loc_ (ffelexToken ft UNUSED, ffebld expr, ffelexToken t) e->u.operand = ffebld_new_percent_loc (expr); ffebld_set_info (e->u.operand, ffeinfo_new (FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, + ffecom_pointer_kind (), 0, FFEINFO_kindENTITY, FFEINFO_whereFLEETING, @@ -11440,7 +11442,7 @@ ffeexpr_nil_rhs_ (ffelexToken t) switch (ffelex_token_type (t)) { case FFELEX_typeQUOTE: - if (ffe_is_vxt_not_90 ()) + if (ffe_is_vxt ()) return (ffelexHandler) ffeexpr_nil_quote_; ffelex_set_expecting_hollerith (-1, '\"', ffelex_token_where_line (t), @@ -12272,12 +12274,12 @@ again: /* :::::::::::::::::::: */ : ffeinfo_basictype (info)) { case FFEINFO_basictypeINTEGER: - error = (ffeinfo_kindtype (info) != FFEINFO_kindtypeINTEGERDEFAULT); + error = (ffeinfo_kindtype (info) != ffecom_label_kind ()); break; case FFEINFO_basictypeLOGICAL: error = !ffe_is_ugly_logint () - || (ffeinfo_kindtype (info) != FFEINFO_kindtypeLOGICALDEFAULT); + || (ffeinfo_kindtype (info) != ffecom_label_kind ()); break; default: @@ -13007,8 +13009,9 @@ again: /* :::::::::::::::::::: */ { case FFEINFO_basictypeINTEGER: error = (expr == NULL) - || ((ffeinfo_rank (info) != 0) - && ffe_is_pedantic ()) /* F77 C5. */ + || ((ffeinfo_rank (info) != 0) ? + ffe_is_pedantic () /* F77 C5. */ + : (ffeinfo_kindtype (info) != ffecom_label_kind ())) || (ffebld_op (expr) != FFEBLD_opSYMTER); break; @@ -13260,7 +13263,7 @@ ffeexpr_token_rhs_ (ffelexToken t) switch (ffelex_token_type (t)) { case FFELEX_typeQUOTE: - if (ffe_is_vxt_not_90 ()) + if (ffe_is_vxt ()) { ffeexpr_tokens_[0] = ffelex_token_use (t); return (ffelexHandler) ffeexpr_token_quote_; @@ -15036,7 +15039,7 @@ just_name: /* :::::::::::::::::::: */ if (ffesymbol_generic (s) != FFEINTRIN_genNONE) ffeintrin_fulfill_generic (&expr, &info, e->token); else if (ffesymbol_specific (s) != FFEINTRIN_specNONE) - ffeintrin_fulfill_specific (&expr, &info, e->token); + ffeintrin_fulfill_specific (&expr, &info, NULL, e->token); ffebld_set_info (expr, ffeinfo_new (ffeinfo_basictype (info), ffeinfo_kindtype (info), @@ -15835,7 +15838,9 @@ ffeexpr_declare_unadorned_ (ffelexToken t, bool maybe_intrin) switch (ffeexpr_context_outer_ (ffeexpr_stack_)) { case FFEEXPR_contextSUBROUTINEREF: - bad = (k != FFEINFO_kindSUBROUTINE); + bad = ((k != FFEINFO_kindSUBROUTINE) + && ((ffesymbol_where (s) != FFEINFO_whereINTRINSIC) + || (k != FFEINFO_kindNONE))); break; case FFEEXPR_contextFILEEXTFUNC: @@ -15861,6 +15866,11 @@ ffeexpr_declare_unadorned_ (ffelexToken t, bool maybe_intrin) break; case FFEINFO_kindNONE: + if (ffesymbol_where (s) == FFEINFO_whereINTRINSIC) + { + bad = !(ffeintrin_is_actualarg (ffesymbol_specific (s))); + break; + } /* If state is UNDERSTOOD here, it's CHAR*(*) or attrsANY, and in the former case, attrsTYPE is set, so we @@ -16432,7 +16442,7 @@ ffeexpr_sym_lhs_call_ (ffesymbol s, ffelexToken t) assert (ffesymbol_state (s) == FFESYMBOL_stateNONE); if (ffeintrin_is_intrinsic (ffesymbol_text (s), t, FALSE, - &gen, &spec, &imp, &kind)) + &gen, &spec, &imp)) { ffesymbol_signal_change (s); /* May need to back up to previous version. */ @@ -16443,7 +16453,7 @@ ffeexpr_sym_lhs_call_ (ffesymbol s, ffelexToken t) ffeinfo_new (FFEINFO_basictypeNONE, FFEINFO_kindtypeNONE, 0, - kind, + FFEINFO_kindNONE, FFEINFO_whereINTRINSIC, FFETARGET_charactersizeNONE)); ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); @@ -16480,6 +16490,8 @@ ffeexpr_sym_lhs_call_ (ffesymbol s, ffelexToken t) ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); ffesymbol_resolve_intrin (s); s = ffecom_sym_learned (s); + if (where == FFEINFO_whereGLOBAL) + ffesymbol_globalize (s); ffesymbol_signal_unreported (s); /* For debugging purposes. */ } @@ -16838,6 +16850,8 @@ ffeexpr_sym_lhs_extfunc_ (ffesymbol s, ffelexToken t) ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); ffesymbol_resolve_intrin (s); s = ffecom_sym_learned (s); + if (where == FFEINFO_whereGLOBAL) + ffesymbol_globalize (s); ffesymbol_signal_unreported (s); /* For debugging purposes. */ } @@ -17118,6 +17132,8 @@ ffeexpr_sym_rhs_actualarg_ (ffesymbol s, ffelexToken t) ffesymbol_set_attrs (s, na); ffesymbol_set_state (s, ns); s = ffecom_sym_learned (s); + if (where == FFEINFO_whereGLOBAL) + ffesymbol_globalize (s); ffesymbol_signal_unreported (s); /* For debugging purposes. */ } @@ -17562,7 +17578,9 @@ ffeexpr_declare_parenthesized_ (ffelexToken t, bool maybe_intrin, switch (ffeexpr_context_outer_ (ffeexpr_stack_)) { case FFEEXPR_contextSUBROUTINEREF: - bad = (k != FFEINFO_kindSUBROUTINE); + bad = ((k != FFEINFO_kindSUBROUTINE) + && ((ffesymbol_where (s) != FFEINFO_whereINTRINSIC) + || (k != FFEINFO_kindNONE))); break; case FFEEXPR_contextDATA: @@ -17654,6 +17672,15 @@ ffeexpr_declare_parenthesized_ (ffelexToken t, bool maybe_intrin, switch (bad ? FFEINFO_kindANY : k) { case FFEINFO_kindNONE: /* Case "CHARACTER X,Y; Y=X(?". */ + if (ffesymbol_where (s) == FFEINFO_whereINTRINSIC) + { + if (ffeexpr_context_outer_ (ffeexpr_stack_) + == FFEEXPR_contextSUBROUTINEREF) + *paren_type = FFEEXPR_parentypeSUBROUTINE_; + else + *paren_type = FFEEXPR_parentypeFUNCTION_; + break; + } if (st == FFESYMBOL_stateUNDERSTOOD) { bad = TRUE; @@ -17960,7 +17987,7 @@ ffeexpr_paren_rhs_let_ (ffesymbol s, ffelexToken t) | FFESYMBOL_attrsSFARG))); if (ffeintrin_is_intrinsic (ffesymbol_text (s), t, FALSE, - &gen, &spec, &imp, &kind)) + &gen, &spec, &imp)) { if (!(sa & FFESYMBOL_attrsANYLEN) && (ffeimplic_peek_symbol_type (s, NULL) @@ -17976,7 +18003,7 @@ ffeexpr_paren_rhs_let_ (ffesymbol s, ffelexToken t) ffeinfo_new (FFEINFO_basictypeNONE, FFEINFO_kindtypeNONE, 0, - kind, + FFEINFO_kindNONE, FFEINFO_whereINTRINSIC, FFETARGET_charactersizeNONE)); ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); @@ -18010,7 +18037,7 @@ ffeexpr_paren_rhs_let_ (ffesymbol s, ffelexToken t) assert (ffesymbol_state (s) == FFESYMBOL_stateNONE); if (ffeintrin_is_intrinsic (ffesymbol_text (s), t, FALSE, - &gen, &spec, &imp, &kind)) + &gen, &spec, &imp)) { if (ffeimplic_peek_symbol_type (s, NULL) == FFEINFO_basictypeCHARACTER) @@ -18025,7 +18052,7 @@ ffeexpr_paren_rhs_let_ (ffesymbol s, ffelexToken t) ffeinfo_new (FFEINFO_basictypeNONE, FFEINFO_kindtypeNONE, 0, - kind, + FFEINFO_kindNONE, FFEINFO_whereINTRINSIC, FFETARGET_charactersizeNONE)); ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); @@ -18073,6 +18100,8 @@ ffeexpr_paren_rhs_let_ (ffesymbol s, ffelexToken t) ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); ffesymbol_resolve_intrin (s); s = ffecom_sym_learned (s); + if (where == FFEINFO_whereGLOBAL) + ffesymbol_globalize (s); ffesymbol_signal_unreported (s); /* For debugging purposes. */ } @@ -18092,8 +18121,8 @@ ffeexpr_token_arguments_ (ffelexToken ft, ffebld expr, ffelexToken t) ffeexprExpr_ procedure; ffebld reduced; ffeinfo info; - bool is_function; ffeexprContext ctx; + bool check_intrin = FALSE; /* Set TRUE if intrinsic is REAL(Z) or AIMAG(Z). */ procedure = ffeexpr_stack_->exprstack; info = ffebld_info (procedure->u.operand); @@ -18202,7 +18231,6 @@ ffeexpr_token_arguments_ (ffelexToken ft, ffebld expr, ffelexToken t) break; } - is_function = (ffeinfo_kind (info) != FFEINFO_kindSUBROUTINE); if ((ffeinfo_where (info) == FFEINFO_whereCONSTANT) && (ffeexpr_stack_->next_dummy != NULL)) { /* Too few arguments. */ @@ -18259,7 +18287,7 @@ ffeexpr_token_arguments_ (ffelexToken ft, ffebld expr, ffelexToken t) } else { - if (is_function) + if (ffeexpr_stack_->context != FFEEXPR_contextSUBROUTINEREF) reduced = ffebld_new_funcref (procedure->u.operand, ffeexpr_stack_->expr); else @@ -18269,7 +18297,7 @@ ffeexpr_token_arguments_ (ffelexToken ft, ffebld expr, ffelexToken t) ffeintrin_fulfill_generic (&reduced, &info, ffeexpr_stack_->tokens[0]); else if (ffebld_symter_specific (procedure->u.operand) != FFEINTRIN_specNONE) - ffeintrin_fulfill_specific (&reduced, &info, + ffeintrin_fulfill_specific (&reduced, &info, &check_intrin, ffeexpr_stack_->tokens[0]); ffebld_set_info (reduced, ffeinfo_new (ffeinfo_basictype (info), @@ -18291,6 +18319,37 @@ ffeexpr_token_arguments_ (ffelexToken ft, ffebld expr, ffelexToken t) { ffelex_token_kill (ffeexpr_stack_->tokens[0]); ffeexpr_is_substr_ok_ = FALSE; /* Nobody likes "FUNC(3)(1:1)".... */ + + /* If the intrinsic needs checking (is REAL(Z) or AIMAG(Z), where + Z is DOUBLE COMPLEX), and a command-line option doesn't already + establish interpretation, probably complain. */ + + if (check_intrin + && !ffe_is_90 () + && !ffe_is_ugly_complex ()) + { + /* If the outer expression is REAL(me...), issue diagnostic + only if next token isn't the close-paren for REAL(me). */ + + if ((ffeexpr_stack_->previous != NULL) + && ((reduced = ffeexpr_stack_->previous->exprstack->u.operand) != NULL) + && (ffebld_op (reduced) == FFEBLD_opSYMTER) + && (ffebld_symter_implementation (reduced) == FFEINTRIN_impREAL)) + return (ffelexHandler) ffeexpr_token_intrincheck_; + + /* Diagnose the ambiguity now. */ + + if (ffebad_start (FFEBAD_INTRINSIC_CMPAMBIG)) + { + ffebad_string (ffeintrin_name_implementation + (ffebld_symter_implementation + (ffebld_left + (ffeexpr_stack_->exprstack->u.operand)))); + ffebad_here (0, ffelex_token_where_line (ffeexpr_stack_->exprstack->token), + ffelex_token_where_column (ffeexpr_stack_->exprstack->token)); + ffebad_finish (); + } + } return (ffelexHandler) ffeexpr_token_substrp_; } @@ -18981,6 +19040,24 @@ ffeexpr_token_substrp_ (ffelexToken t) ffeexpr_token_substring_); } +static ffelexHandler +ffeexpr_token_intrincheck_ (ffelexToken t) +{ + if ((ffelex_token_type (t) != FFELEX_typeCLOSE_PAREN) + && ffebad_start (FFEBAD_INTRINSIC_CMPAMBIG)) + { + ffebad_string (ffeintrin_name_implementation + (ffebld_symter_implementation + (ffebld_left + (ffeexpr_stack_->exprstack->u.operand)))); + ffebad_here (0, ffelex_token_where_line (ffeexpr_stack_->exprstack->token), + ffelex_token_where_column (ffeexpr_stack_->exprstack->token)); + ffebad_finish (); + } + + return (ffelexHandler) ffeexpr_token_substrp_ (t); +} + /* ffeexpr_token_funsubstr_ -- NAME OPEN_PAREN expr Return a pointer to this function to the lexer (ffelex), which will @@ -18993,7 +19070,6 @@ ffeexpr_token_substrp_ (ffelexToken t) static ffelexHandler ffeexpr_token_funsubstr_ (ffelexToken ft, ffebld expr, ffelexToken t) { - ffeinfoKind kind; ffeinfoWhere where; ffesymbol s; ffesymbolAttrs sa; @@ -19056,7 +19132,7 @@ ffeexpr_token_funsubstr_ (ffelexToken ft, ffebld expr, ffelexToken t) reference is to a function. */ if (ffeintrin_is_intrinsic (ffesymbol_text (s), ffeexpr_stack_->tokens[0], - FALSE, &gen, &spec, &imp, &kind)) + FALSE, &gen, &spec, &imp)) { ffebld_symter_set_generic (symter, gen); ffebld_symter_set_specific (symter, spec); @@ -19068,7 +19144,7 @@ ffeexpr_token_funsubstr_ (ffelexToken ft, ffebld expr, ffelexToken t) ffeinfo_new (FFEINFO_basictypeNONE, FFEINFO_kindtypeNONE, 0, - kind, + FFEINFO_kindNONE, FFEINFO_whereINTRINSIC, FFETARGET_charactersizeNONE)); } @@ -19095,6 +19171,8 @@ ffeexpr_token_funsubstr_ (ffelexToken ft, ffebld expr, ffelexToken t) ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); ffesymbol_resolve_intrin (s); s = ffecom_sym_learned (s); + if (ffesymbol_where (s) == FFEINFO_whereGLOBAL) + ffesymbol_globalize (s); ffesymbol_signal_unreported (s); /* For debugging purposes. */ ffebld_init_list (&ffeexpr_stack_->expr, &ffeexpr_stack_->bottom); diff --git a/gnu/usr.bin/gcc/f/expr.h b/gnu/usr.bin/gcc/f/expr.h index 7ddca4ca774..db7d9fa78e7 100644 --- a/gnu/usr.bin/gcc/f/expr.h +++ b/gnu/usr.bin/gcc/f/expr.h @@ -1,5 +1,5 @@ /* expr.h -- Public #include File (module.h template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995, 1996 Free Software Foundation, Inc. Contributed by James Craig Burley (burley@gnu.ai.mit.edu). This file is part of GNU Fortran. diff --git a/gnu/usr.bin/gcc/f/g77.1 b/gnu/usr.bin/gcc/f/g77.1 index b9709f3cd71..8164564f4b7 100644 --- a/gnu/usr.bin/gcc/f/g77.1 +++ b/gnu/usr.bin/gcc/f/g77.1 @@ -1,7 +1,7 @@ .\" Copyright (c) 1995, 1996 Free Software Foundation -*-Text-*- .\" See section COPYING for conditions for redistribution .\" FIXME: no info here on predefines. Should there be? extra for F77... -.TH G77 1 "1996-03-01" "GNU Tools" "GNU Tools" +.TH G77 1 "1997-02-24" "GNU Tools" "GNU Tools" .de BP .sp .ti \-.2i @@ -14,14 +14,18 @@ g77 \- GNU project F77 Compiler (v0.5.18) .IR option " | " "filename " ].\|.\|. .SH WARNING The information in this man page is an extract from the full -documentation of the GNU Fortran compiler, and is limited to the meaning of -the options. +documentation of the GNU Fortran compiler (version 0.5.18), +and is limited to the meaning of the options. .PP -This man page is not kept up to date except when volunteers want to +This man page is not up to date, since no volunteers want to maintain it. If you find a discrepancy between the man page and the software, please check the Info file, which is the authoritative documentation. .PP +The version of GNU Fortran documented by the Info file is 0.5.20, +which includes substantial improvements and changes since 0.5.18, +the version documented in this man page. +.PP If we find that the things in this man page that are out of date cause significant confusion or complaints, we will stop distributing the man page. The alternative, updating the man page when we update the Info diff --git a/gnu/usr.bin/gcc/f/g77.c b/gnu/usr.bin/gcc/f/g77.c index bc924176ead..f7b982199d7 100644 --- a/gnu/usr.bin/gcc/f/g77.c +++ b/gnu/usr.bin/gcc/f/g77.c @@ -1,5 +1,5 @@ /* G77 preliminary semantic processing for the compiler driver. - Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. + Copyright (C) 1993-1997 Free Software Foundation, Inc. Contributed by Brendan Kehoe (brendan@cygnus.com), with significant modifications for GNU Fortran by James Craig Burley (burley@gnu.ai.mit.edu). @@ -88,12 +88,28 @@ g77: `f77' language not included in list of languages\n\ #endif #include <stdio.h> +/* Include multi-lib information. */ +#include "multilib.h" + #ifndef R_OK #define R_OK 4 #define W_OK 2 #define X_OK 1 #endif +#ifndef WIFSIGNALED +#define WIFSIGNALED(S) (((S) & 0xff) != 0 && ((S) & 0xff) != 0x7f) +#endif +#ifndef WTERMSIG +#define WTERMSIG(S) ((S) & 0x7f) +#endif +#ifndef WIFEXITED +#define WIFEXITED(S) (((S) & 0xff) == 0) +#endif +#ifndef WEXITSTATUS +#define WEXITSTATUS(S) (((S) & 0xff00) >> 8) +#endif + /* Defined to the name of the compiler; if using a cross compiler, the Makefile should compile this file with the proper name (e.g., "i386-aout-gcc"). */ @@ -224,12 +240,16 @@ typedef enum OPTION_c, /* Aka --compile. */ OPTION_driver, /* Wrapper-specific option. */ OPTION_E, /* Aka --preprocess. */ + OPTION_for_linker, /* Aka `-Xlinker' and `-Wl,'. */ OPTION_help, /* --help. */ OPTION_i, /* -imacros, -include, -include-*. */ + OPTION_l, + OPTION_L, /* Aka --library-directory. */ OPTION_M, /* Aka --dependencies. */ OPTION_MM, /* Aka --user-dependencies. */ OPTION_nostdlib, /* Aka --no-standard-libraries, or -nodefaultlibs. */ + OPTION_o, /* Aka --output. */ OPTION_P, /* Aka --print-*-name. */ OPTION_S, /* Aka --assemble. */ OPTION_v, /* Aka --verbose. */ @@ -278,11 +298,20 @@ typedef enum otherwise, in /usr/tmp or /tmp. */ static char *temp_filename; +static char *temp_filename_f; /* Same with ".f" appended. */ /* Length of the prefix. */ static int temp_filename_length; +/* The number of errors that have occurred; the link phase will not be + run if this is non-zero. */ +static int error_count = 0; + +/* Number of commands that exited with a signal. */ + +static int signal_count = 0; + /* END OF STUFF FROM gcc-2.7.0/gcc.c. */ char * @@ -443,12 +472,26 @@ pfatal_with_name (name) char *s; if (errno < sys_nerr) - s = concat3 ("%s: ", sys_errlist[errno], ""); + s = concat ("%s: ", my_strerror (errno)); else - s = "cannot open %s"; + s = "cannot open `%s'"; fatal (s, name); } +static void +perror_exec (name) + char *name; +{ + char *s; + + if (errno < sys_nerr) + s = concat ("installation problem, cannot exec `%s': ", + my_strerror (errno)); + else + s = "installation problem, cannot exec `%s'"; + error (s, name); +} + /* Compute a string to use as the base of all temporary file names. It is substituted for %g. */ @@ -505,65 +548,14 @@ choose_temp_base () temp_filename_length = strlen (temp_filename); if (temp_filename_length == 0) abort (); -} -#ifdef __MSDOS__ -static void -perror_exec (name) - char *name; -{ - char *s; - - if (errno < sys_nerr) - s = concat3 ("installation problem, cannot exec %s: ", - my_strerror( errno ), ""); - else - s = "installation problem, cannot exec %s"; - error (s, name); + temp_filename_f = xmalloc (temp_filename_length + 2); + strcpy (temp_filename_f, temp_filename); + temp_filename_f[temp_filename_length] = '.'; + temp_filename_f[temp_filename_length + 1] = 'f'; + temp_filename_f[temp_filename_length + 2] = '\0'; } -/* This is almost exactly what's in gcc.c:pexecute for MSDOS. */ -void -run_dos (program, argv) - char *program; - char *argv[]; -{ - char *scmd, *rf; - FILE *argfile; - int i; - - choose_temp_base (); /* not in gcc.c */ - - scmd = (char *) malloc (strlen (program) + strlen (temp_filename) + 10); - rf = scmd + strlen (program) + 6; - sprintf (scmd, "%s.exe @%s.gp", program, temp_filename); - - argfile = fopen (rf, "w"); - if (argfile == 0) - pfatal_with_name (rf); - - for (i=1; argv[i]; i++) - { - char *cp; - for (cp = argv[i]; *cp; cp++) - { - if (*cp == '"' || *cp == '\'' || *cp == '\\' || isspace (*cp)) - fputc ('\\', argfile); - fputc (*cp, argfile); - } - fputc ('\n', argfile); - } - fclose (argfile); - - i = system (scmd); - - remove (rf); - - if (i == -1) - perror_exec (program); -} -#endif /* __MSDOS__ */ - /* This structure describes one mapping. */ struct option_map { @@ -747,12 +739,13 @@ lookup_option (xopt, xskip, xarg, text) char *text; { Option opt = OPTION_; - int skip = -1; + int skip; char *arg = NULL; if ((skip = SWITCH_TAKES_ARG (text[1])) > (text[2] != '\0')) skip -= (text[2] != '\0'); /* Usually one of "DUoeTuImLA". */ - else if (text[1] == 'B') + + if (text[1] == 'B') opt = OPTION_B, skip = (text[2] == '\0'), arg = text + 2; else if (text[1] == 'b') opt = OPTION_b, skip = (text[2] == '\0'), arg = text + 2; @@ -762,12 +755,20 @@ lookup_option (xopt, xskip, xarg, text) opt = OPTION_E, skip = 0; else if (text[1] == 'i') opt = OPTION_i, skip = 0; + else if (text[1] == 'l') + opt = OPTION_l; + else if (text[1] == 'L') + opt = OPTION_L, skip = (text[2] == '\0'), arg = text + 2; + else if (text[1] == 'o') + opt = OPTION_o; else if ((text[1] == 'S') && (text[2] == '\0')) opt = OPTION_S, skip = 0; else if (text[1] == 'V') opt = OPTION_V, skip = (text[2] == '\0'); else if ((text[1] == 'v') && (text[2] == '\0')) opt = OPTION_v, skip = 0; + else if ((text[1] == 'W') && (text[2] == 'l') && (text[3] == ',')) + opt = OPTION_for_linker, skip = 0; else if (text[1] == 'x') opt = OPTION_x, skip = (text[2] == '\0'), arg = text + 2; else @@ -777,7 +778,8 @@ lookup_option (xopt, xskip, xarg, text) "imacros", "aux-info", "idirafter", "iprefix", "iwithprefix", "iwithprefixbefore", "isystem". */ ; - else if (text[1] != '-') + + if (text[1] != '-') skip = 0; else if (strcmp (text, "--assemble") == 0) opt = OPTION_S; @@ -797,12 +799,16 @@ lookup_option (xopt, xskip, xarg, text) opt = OPTION_i; else if (opteq (&skip, &arg, text, "--language") == 0) opt = OPTION_x; + else if (opteq (&skip, &arg, text, "--library-directory") == 0) + opt = OPTION_L; else if ((strcmp (text, "-M") == 0) || (strcmp (text, "--dependencies") == 0)) opt = OPTION_M; else if ((strcmp (text, "-MM") == 0) || (strcmp (text, "--user-dependencies") == 0)) opt = OPTION_MM; + else if (strcmp (text, "--output") == 0) + opt = OPTION_o; else if (opteq (&skip, &arg, text, "--prefix") == 0) opt = OPTION_B; else if (strcmp (text, "--preprocess") == 0) @@ -832,9 +838,7 @@ lookup_option (xopt, xskip, xarg, text) || (opteq (&skip, &arg, text, "--for-assembler") == 0) || (opteq (&skip, &arg, text, "--for-linker") == 0) || (opteq (&skip, &arg, text, "--force-link") == 0) - || (opteq (&skip, &arg, text, "--library-directory") == 0) || (opteq (&skip, &arg, text, "--machine") == 0) - || (opteq (&skip, &arg, text, "--output") == 0) || (opteq (&skip, &arg, text, "--target") == 0) || (opteq (&skip, &arg, text, "--undefine-macro") == 0)) ; @@ -847,7 +851,13 @@ lookup_option (xopt, xskip, xarg, text) if (xskip != NULL) *xskip = skip; if (xarg != NULL) - *xarg = arg; + { + if ((arg != NULL) + && (arg[0] == '\0')) + *xarg = NULL; + else + *xarg = arg; + } } static void @@ -884,6 +894,245 @@ append_arg (arg) newargv[newargc++] = arg; } +extern int execv (), execvp (); + +/* If a stage of compilation returns an exit status >= 1, + compilation of that file ceases. */ + +#define MIN_FATAL_STATUS 1 + +/* stdin file number. */ +#define STDIN_FILE_NO 0 + +/* stdout file number. */ +#define STDOUT_FILE_NO 1 + +/* value of `pipe': port index for reading. */ +#define READ_PORT 0 + +/* value of `pipe': port index for writing. */ +#define WRITE_PORT 1 + +/* Pipe waiting from last process, to be used as input for the next one. + Value is STDIN_FILE_NO if no pipe is waiting + (i.e. the next command is the first of a group). */ + +static int last_pipe_input; + +/* Fork one piped subcommand. FUNC is the system call to use + (either execv or execvp). ARGV is the arg vector to use. + NOT_LAST is nonzero if this is not the last subcommand + (i.e. its output should be piped to the next one.) */ + +#ifdef __MSDOS__ + +#include <process.h> +static int +pexecute (search_flag, program, argv, not_last) + int search_flag; + char *program; + char *argv[]; + int not_last; +{ +#ifdef __GO32__ + int i = (search_flag ? spawnv : spawnvp) (1, program, argv); +#else + char *scmd, *rf; + FILE *argfile; + int i, el = search_flag ? 0 : 4; + + scmd = (char *)malloc (strlen (program) + strlen (temp_filename) + 6 + el); + rf = scmd + strlen(program) + 2 + el; + sprintf (scmd, "%s%s @%s.gp", program, + (search_flag ? "" : ".exe"), temp_filename); + argfile = fopen (rf, "w"); + if (argfile == 0) + pfatal_with_name (rf); + + for (i=1; argv[i]; i++) + { + char *cp; + for (cp = argv[i]; *cp; cp++) + { + if (*cp == '"' || *cp == '\'' || *cp == '\\' || isspace (*cp)) + fputc ('\\', argfile); + fputc (*cp, argfile); + } + fputc ('\n', argfile); + } + fclose (argfile); + + i = system (scmd); + + remove (rf); +#endif + + if (i == -1) + { + perror_exec (program); + return MIN_FATAL_STATUS << 8; + } + return i << 8; +} + +#endif + +#if !defined(__MSDOS__) && !defined(OS2) && !defined(_WIN32) + +static int +pexecute (search_flag, program, argv, not_last) + int search_flag; + char *program; + char *argv[]; + int not_last; +{ + int (*func)() = (search_flag ? execv : execvp); + int pid; + int pdes[2]; + int input_desc = last_pipe_input; + int output_desc = STDOUT_FILE_NO; + int retries, sleep_interval; + + /* If this isn't the last process, make a pipe for its output, + and record it as waiting to be the input to the next process. */ + + if (not_last) + { + if (pipe (pdes) < 0) + pfatal_with_name ("pipe"); + output_desc = pdes[WRITE_PORT]; + last_pipe_input = pdes[READ_PORT]; + } + else + last_pipe_input = STDIN_FILE_NO; + + /* Fork a subprocess; wait and retry if it fails. */ + sleep_interval = 1; + for (retries = 0; retries < 4; retries++) + { + pid = vfork (); + if (pid >= 0) + break; + sleep (sleep_interval); + sleep_interval *= 2; + } + + switch (pid) + { + case -1: +#ifdef vfork + pfatal_with_name ("fork"); +#else + pfatal_with_name ("vfork"); +#endif + /* NOTREACHED */ + return 0; + + case 0: /* child */ + /* Move the input and output pipes into place, if nec. */ + if (input_desc != STDIN_FILE_NO) + { + close (STDIN_FILE_NO); + dup (input_desc); + close (input_desc); + } + if (output_desc != STDOUT_FILE_NO) + { + close (STDOUT_FILE_NO); + dup (output_desc); + close (output_desc); + } + + /* Close the parent's descs that aren't wanted here. */ + if (last_pipe_input != STDIN_FILE_NO) + close (last_pipe_input); + + /* Exec the program. */ + (*func) (program, argv); + perror_exec (program); + exit (-1); + /* NOTREACHED */ + return 0; + + default: + /* In the parent, after forking. + Close the descriptors that we made for this child. */ + if (input_desc != STDIN_FILE_NO) + close (input_desc); + if (output_desc != STDOUT_FILE_NO) + close (output_desc); + + /* Return child's process number. */ + return pid; + } +} + +#endif /* not __MSDOS__ and not OS2 and not _WIN32 */ + +#if defined(OS2) + +static int +pexecute (search_flag, program, argv, not_last) + int search_flag; + char *program; + char *argv[]; + int not_last; +{ + return (search_flag ? spawnv : spawnvp) (1, program, argv); +} +#endif /* OS2 */ + +#if defined(_WIN32) + +static int +pexecute (search_flag, program, argv, not_last) + int search_flag; + char *program; + char *argv[]; + int not_last; +{ + return (search_flag ? __spawnv : __spawnvp) (1, program, argv); +} +#endif /* _WIN32 */ + +static int +doit (char *program, char **argv) +{ + int pid; + int status; + int ret_code = 0; + + pid = pexecute (0, program, argv, 0); + +#ifdef __MSDOS__ + status = pid; +#else +#ifdef _WIN32 + pid = cwait (&status, pid, WAIT_CHILD); +#else + pid = wait (&status); +#endif +#endif + if (pid < 0) + abort (); + + if (status != 0) + { + if (WIFSIGNALED (status)) + { + fatal ("Internal compiler error: program %s got fatal signal %d", + program, WTERMSIG (status)); + signal_count++; + ret_code = -1; + } + else if (WIFEXITED (status) + && WEXITSTATUS (status) >= MIN_FATAL_STATUS) + ret_code = -1; + } + + return ret_code; +} + int main (argc, argv) int argc; @@ -895,6 +1144,8 @@ main (argc, argv) Option opt; int skip; char *arg; + int n_infiles = 0; + int n_outfiles = 0; /* This will be NULL if we encounter a situation where we should not link in libf2c. */ @@ -902,7 +1153,7 @@ main (argc, argv) /* This will become 0 if anything other than -v and kin (like -V) is seen, meaning the user is trying to accomplish something. - If it remains nonzero, the user wants version info, so add stuff to + If it remains nonzero, and the user wants version info, add stuff to the command line to make gcc invoke all the appropriate phases to get all the version info. */ int add_version_magic = 1; @@ -968,11 +1219,17 @@ main (argc, argv) for (i = 1; i < argc; ++i) { - if (argv[i][0] != '-') + if ((argv[i][0] == '+') && (argv[i][1] == 'e')) { add_version_magic = 0; continue; } + else if ((argv[i][0] != '-') || (argv[i][1] == 0)) + { + ++n_infiles; + add_version_magic = 0; + continue; + } lookup_option (&opt, &skip, NULL, argv[i]); @@ -990,13 +1247,26 @@ main (argc, argv) add_version_magic = 0; break; + case OPTION_for_linker: + case OPTION_l: + ++n_infiles; + add_version_magic = 0; + break; + + case OPTION_o: + ++n_outfiles; + add_version_magic = 0; + break; + case OPTION_v: + if (!verbose) + printf ("g77 version %s\n", ffezzz_version_string); verbose = 1; - printf ("g77 version %s\n", ffezzz_version_string); break; case OPTION_b: case OPTION_B: + case OPTION_L: case OPTION_driver: case OPTION_i: case OPTION_V: @@ -1067,11 +1337,8 @@ Report bugs to fortran@gnu.ai.mit.edu.\n"); fatal ("argument to `%s' missing\n", argv[i]); } - /* If only -v and related options (like -V), don't link the standard - libraries. */ - - if (add_version_magic) - library = NULL; + if ((n_outfiles != 0) && (n_infiles == 0)) + fatal ("No input files; unwilling to write output files"); /* Second pass through arglist, transforming arguments as appropriate. */ @@ -1098,8 +1365,6 @@ Report bugs to fortran@gnu.ai.mit.edu.\n"); /* Track input language. */ char *lang; - append_arg (argv[i]); - if (arg == NULL) lang = argv[i+1]; else @@ -1185,7 +1450,7 @@ Report bugs to fortran@gnu.ai.mit.edu.\n"); /* Add -lf2c -lm as necessary. */ - if (library) + if (!add_version_magic && library) { /* Doing a link and no -nostdlib. */ if (saw_speclang) append_arg ("-xnone"); @@ -1199,21 +1464,29 @@ Report bugs to fortran@gnu.ai.mit.edu.\n"); break; } } - else if (verbose && add_version_magic) + else if (add_version_magic && verbose) { + FILE *fsrc; + choose_temp_base (); append_arg ("-fnull-version"); append_arg ("-o"); append_arg (temp_filename); append_arg ("-xf77-cpp-input"); - append_arg ("/dev/null"); + append_arg (temp_filename_f); append_arg ("-xnone"); if (library) { append_arg (library); append_arg ("-lm"); } + + fsrc = fopen (temp_filename_f, "w"); + if (fsrc == 0) + pfatal_with_name (fsrc); + fputs (" call g77__fvers;call g77__ivers;call g77__uvers;end\n", fsrc); + fclose (fsrc); } append_arg (NULL); @@ -1232,18 +1505,26 @@ Report bugs to fortran@gnu.ai.mit.edu.\n"); fprintf (stderr, " %s", newargv[i]); fprintf (stderr, "\n"); } -#if !defined(OS2) && !defined (_WIN32) -#ifdef __MSDOS__ - run_dos (gcc, newargv); -#else /* !__MSDOS__ */ - if (execvp (gcc, newargv) < 0) - pfatal_with_name (gcc); -#endif /* __MSDOS__ */ -#else /* OS2 or _WIN32 */ - if (spawnvp (1, gcc, newargv) < 0) - pfatal_with_name (gcc); -#endif + if (doit (gcc, newargv) < 0) + ++error_count; + else if (add_version_magic && verbose) + { + char *outargv[2]; + + outargv[0] = temp_filename; + outargv[1] = 0; + + if (doit (temp_filename, outargv) < 0) + ++error_count; + + remove (temp_filename); + remove (temp_filename_f); + } + + exit (error_count > 0 ? (signal_count ? 2 : 1) : 0); + /* NOTREACHED */ return 0; } + #endif /* LANGUAGE_F77 == 1 */ diff --git a/gnu/usr.bin/gcc/f/g77.texi b/gnu/usr.bin/gcc/f/g77.texi index 4b7970ec637..ebe7e559098 100644 --- a/gnu/usr.bin/gcc/f/g77.texi +++ b/gnu/usr.bin/gcc/f/g77.texi @@ -61,7 +61,7 @@ Published by the Free Software Foundation 59 Temple Place - Suite 330 Boston, MA 02111-1307 USA -Copyright (C) 1995, 1996 Free Software Foundation, Inc. +Copyright (C) 1995-1997 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice @@ -91,9 +91,9 @@ translations approved by the Free Software Foundation instead of in the original English. @end ifinfo -Contributed by James Craig Burley (@code{burley@@gnu.ai.mit.edu}). -Inspired by a first pass at translating @code{g77-0.5.16/f/DOC} that -was contributed to Craig by David Ronis (@code{ronis@@onsager.chem.mcgill.ca}). +Contributed by James Craig Burley (@email{burley@@gnu.ai.mit.edu}). +Inspired by a first pass at translating @file{g77-0.5.16/f/DOC} that +was contributed to Craig by David Ronis (@email{ronis@@onsager.chem.mcgill.ca}). @finalout @titlepage @@ -102,16 +102,16 @@ was contributed to Craig by David Ronis (@code{ronis@@onsager.chem.mcgill.ca}). @sp 2 @center James Craig Burley @sp 3 -@center Last updated 1996-12-03 +@center Last updated 1997-02-28 @sp 1 @c The version number appears some more times in this file. -@center for version 0.5.19 +@center for version 0.5.20 @page @vskip 0pt plus 1filll -Copyright @copyright{} 1995, 1996 Free Software Foundation, Inc. +Copyright @copyright{} 1995-1997 Free Software Foundation, Inc. @sp 2 -For GNU Fortran Version 0.5.19* +For GNU Fortran Version 0.5.20* @sp 1 Published by the Free Software Foundation @* 59 Temple Place - Suite 330@* @@ -144,6 +144,10 @@ original English. @ifinfo +@dircategory Fortran Programming +@direntry +* g77: (g77). The GNU Fortran compilation system. +@end direntry @node Top, Copying,, (DIR) @top Introduction @cindex Introduction @@ -152,19 +156,19 @@ original English. @ifset USING This manual documents how to run, install and port the GNU Fortran compiler, as well as its new features and incompatibilities, and how to -report bugs. It corresponds to GNU Fortran version 0.5.19. +report bugs. It corresponds to GNU Fortran version 0.5.20. @end ifset @end ifset @ifclear INTERNALS This manual documents how to run and install the GNU Fortran compiler, as well as its new features and incompatibilities, and how to report -bugs. It corresponds to GNU Fortran version 0.5.19. +bugs. It corresponds to GNU Fortran version 0.5.20. @end ifclear @ifclear USING This manual documents how to port the GNU Fortran compiler, as well as its new features and incompatibilities, and how to report -bugs. It corresponds to GNU Fortran version 0.5.19. +bugs. It corresponds to GNU Fortran version 0.5.20. @end ifclear @end ifinfo @@ -183,6 +187,10 @@ bugs. It corresponds to GNU Fortran version 0.5.19. * News:: News about recent releases of @code{g77}. * Changes:: User-visible changes to recent releases of @code{g77}. * Language:: The GNU Fortran language. +* Compiler:: The GNU Fortran compiler. +* Other Dialects:: Dialects of Fortran supported by @code{g77}. +* Other Compilers:: Fortran compilers other than @code{g77}. +* Other Languages:: Languages other than Fortran. * Installation:: How to configure, compile and install GNU Fortran. * Debugging and Interfacing:: How @code{g77} generates code. * Collected Fortran Wisdom:: How to avoid Trouble. @@ -196,8 +204,11 @@ bugs. It corresponds to GNU Fortran version 0.5.19. * Projects:: Projects for @code{g77} internals hackers. @end ifset -* Index:: Index of concepts and symbol names. +* M: Diagnostics. Diagnostics produced by @code{g77}. + +* Index:: Index of concepts and symbol names. @end menu +@c yes, the "M: " @emph{is} intentional -- bad.def references it (CMPAMBIG)! @node Copying @unnumbered GNU GENERAL PUBLIC LICENSE @@ -628,11 +639,11 @@ Jonathan Corbet @item Dr.@: Mark Fernyhough @item -Takafumi Hayashi (The University of AIzu)---@code{takafumi@@u-aizu.ac.jp} +Takafumi Hayashi (The University of AIzu)---@email{takafumi@@u-aizu.ac.jp} @item Kate Hedstrom @item -Michel Kern (INRIA and Rice University)---@code{Michel.Kern@@inria.fr} +Michel Kern (INRIA and Rice University)---@email{Michel.Kern@@inria.fr} @item Dr.@: A. O. V. Le Blanc @item @@ -656,23 +667,23 @@ Ian Watson @end itemize @item -Scott Snyder (@code{snyder@@d0sgif.fnal.gov}) +Scott Snyder (@email{snyder@@d0sgif.fnal.gov}) provided the patch to add rudimentary support -for @samp{INTEGER*1}, @samp{INTEGER*2}, and -@samp{LOGICAL*1}. +for @code{INTEGER*1}, @code{INTEGER*2}, and +@code{LOGICAL*1}. This inspired Craig to add further support, even though the resulting support would still be incomplete, because version 0.6 is still a ways off. @item -David Ronis (@code{ronis@@onsager.chem.mcgill.ca}) inspired +David Ronis (@email{ronis@@onsager.chem.mcgill.ca}) inspired and encouraged Craig to rewrite the documentation in texinfo format by contributing a first pass at a translation of the -old @code{g77-0.5.16/f/DOC} file. +old @file{g77-0.5.16/f/DOC} file. @item -Toon Moene (@code{toon@@moene.indiv.nluug.nl}) performed +Toon Moene (@email{toon@@moene.indiv.nluug.nl}) performed some analysis of generated code as part of an overall project to improve @code{g77} code generation to at least be as good as @code{f2c} used in conjunction with @code{gcc}. @@ -681,6 +692,13 @@ experimental, options added by @code{g77} to the @code{gcc} compiler and its back end. @item +John Carr (@email{jfc@@mit.edu}) wrote the alias analysis improvements. + +@item +Thanks to Mary Cortani and the staff at Craftwork Solutions +(@email{support@@craftwork.com}) for all of their support. + +@item Many other individuals have helped debug, test, and improve @code{g77} over the past several years, and undoubtedly more people will be doing so in the future. @@ -744,7 +762,7 @@ without royalty; alteration is not permitted. @cindex improvements, funding Work on GNU Fortran is still being done mostly by its author, -James Craig Burley (@code{burley@@gnu.ai.mit.edu}), who is a volunteer +James Craig Burley (@email{burley@@gnu.ai.mit.edu}), who is a volunteer for, not an employee of, the Free Software Foundation (FSF). As with other GNU software, funding is important because it can pay for needed equipment, personnel, and so on. @@ -754,7 +772,7 @@ needed equipment, personnel, and so on. The FSF provides information on the best way to fund ongoing development of GNU software (such as GNU Fortran) in documents such as the ``GNUS Bulletin''. -Email @code{gnu@@prep.ai.mit.edu} for information on funding the FSF. +Email @email{gnu@@prep.ai.mit.edu} for information on funding the FSF. To fund specific GNU Fortran work in particular, the FSF might provide a means for that, but the FSF does not provide direct funding @@ -781,12 +799,10 @@ contract work on a few occasions. If more people did this, he would be able to plan on not doing contract work for many months and could thus devote that time to work on projects (such as the planned -changes for @code{g77-0.6}) that require longer timeframes to complete. +changes for 0.6) that require longer timeframes to complete. For the latest information on the status of the author, do -@samp{finger -l burley@@gnu.ai.mit.edu}, i.e. access @code{burley}'s -@code{.plan} file just as you would @code{fortran}'s to get @code{g77} -status (except there's no public @code{ftp} access to @code{burley}'s -@code{.plan} file---you can email him asking for it). +@kbd{finger -l burley@@gate.gnu.ai.mit.edu} on a UNIX system +(or any system with a command like UNIX @code{finger}). Another important way to support work on GNU Fortran is to volunteer to help out. @@ -794,7 +810,7 @@ Work is needed on documentation, testing, porting to various machines, and in some cases, coding (although major changes planned for version 0.6 make it difficult to add manpower to this area). -Email @code{fortran@@gnu.ai.mit.edu} to volunteer for this work. +Email @email{fortran@@gnu.ai.mit.edu} to volunteer for this work. @xref{Funding,,Funding Free Software}, for more information. @@ -927,7 +943,7 @@ When writing Fortran or C, it is easy to make big mistakes. @cindex debugger -@cindex bugs +@cindex bugs, finding @cindex gdb command @cindex commands, gdb @item @@ -1062,7 +1078,7 @@ and linking. @cindex cpp program @cindex programs, cpp For example, the command @samp{gcc foo.c} @dfn{drives} the file -@samp{foo.c} through the preprocessor @samp{cpp}, then +@file{foo.c} through the preprocessor @code{cpp}, then the C compiler (internally named @code{cc1}), then the assembler (usually @code{as}), then the linker (@code{ld}), producing an executable program named @file{a.out} (on @@ -1108,10 +1124,10 @@ The command @samp{g77 -v} is a quick way to display lots of version information for the various programs used to compile a typical preprocessed Fortran source file---this produces much more output than @samp{gcc -v} currently does. -(It also produces an error message near the end of the output, -a diagnostic from the linker, usually @code{ld}---you can safely -ignore this error, but do include the entire output with any -bug report you submit.) +(If it produces an error message near the end of the output---diagnostics +from the linker, usually @code{ld}---you might +have an out-of-date @code{libf2c} that improperly handles +complex arithmetic.)@ In the output of this command, the line beginning @samp{GNU Fortran Front End} identifies the version number of GNU Fortran; immediately preceding that line is a line identifying the version of @code{gcc} @@ -1250,14 +1266,14 @@ the @code{gcc} command: @table @code @cindex -@w{}-driver option -@cindex g77 options, driver +@cindex g77 options, -@w{}-driver @cindex options, -@w{}-driver @item --driver=@var{command} Specifies that @var{command}, rather than @code{gcc}, is to be invoked by @code{g77} to do its job. -For example, within the @samp{gcc} build directory after +For example, within the @code{gcc} build directory after building GNU Fortran (but without having to install it), -@samp{./g77 --driver=./xgcc foo.f -B./}. +@kbd{./g77 --driver=./xgcc foo.f -B./}. @end table @cindex options, negative forms @@ -1270,7 +1286,7 @@ This manual documents only one of these two forms, whichever one is not the default. @menu -* Option Summary:: Brief list of all @code{g77} options, +* Option Summary:: Brief list of all @code{g77} options, without explanations. * Overall Options:: Controlling the kind of output: an executable, object files, assembler files, @@ -1300,26 +1316,23 @@ by type. Explanations are in the following sections. @item Overall Options @xref{Overall Options,,Options Controlling the Kind of Output}. @smallexample ---driver -fversion -fset-g77-defaults --fno-silent +--driver -fversion -fset-g77-defaults -fno-silent @end smallexample @item Shorthand Options @xref{Shorthand Options}. @smallexample --ff66 -fno-f66 --ff77 -fno-f77 --fugly -fno-ugly +-ff66 -fno-f66 -ff77 -fno-f77 -fugly -fno-ugly @end smallexample @item Fortran Language Options @xref{Fortran Dialect Options,,Options Controlling Fortran Dialect}. @smallexample --ffree-form -fno-fixed-form -ff90 -fvxt-not-f90 --ff90-not-vxt -fdollar-ok -fno-backslash --fno-ugly-args -fno-ugly-assumed -fugly-comma --fugly-init -fugly-logint --fonetrip -fno-typeless-boz +-ffree-form -fno-fixed-form -ff90 +-fvxt -fdollar-ok -fno-backslash +-fno-ugly-args -fno-ugly-assign -fno-ugly-assumed +-fugly-comma -fugly-complex -fugly-init -fugly-logint +-fonetrip -ftypeless-boz -fintrin-case-initcap -fintrin-case-upper -fintrin-case-lower -fintrin-case-any -fmatch-case-initcap -fmatch-case-upper @@ -1329,12 +1342,12 @@ by type. Explanations are in the following sections. -fsymbol-case-lower -fsymbol-case-any -fcase-strict-upper -fcase-strict-lower -fcase-initcap -fcase-upper -fcase-lower -fcase-preserve --fdcp-intrinsics-delete -fdcp-intrinsics-hide --fdcp-intrinsics-disable -fdcp-intrinsics-enable -ff2c-intrinsics-delete -ff2c-intrinsics-hide -ff2c-intrinsics-disable -ff2c-intrinsics-enable -ff90-intrinsics-delete -ff90-intrinsics-hide -ff90-intrinsics-disable -ff90-intrinsics-enable +-fgnu-intrinsics-delete -fgnu-intrinsics-hide +-fgnu-intrinsics-disable -fgnu-intrinsics-enable -fmil-intrinsics-delete -fmil-intrinsics-hide -fmil-intrinsics-disable -fmil-intrinsics-enable -funix-intrinsics-delete -funix-intrinsics-hide @@ -1361,6 +1374,7 @@ by type. Explanations are in the following sections. @item Optimization Options @xref{Optimize Options,,Options that Control Optimization}. @smallexample +-malign-double -ffloat-store -fforce-mem -fforce-addr -fno-inline -ffast-math -fstrength-reduce -frerun-cse-after-loop -fexpensive-optimizations -fdelayed-branch @@ -1384,7 +1398,9 @@ by type. Explanations are in the following sections. -fpcc-struct-return -freg-struct-return -fshort-double -fno-common -fpack-struct -fzeros -fno-second-underscore --fdebug-kludge +-fdebug-kludge -fno-emulate-complex +-falias-check -fargument-alias +-fargument-noalias -fno-argument-noalias-global @end smallexample @end table @@ -1411,8 +1427,9 @@ by type. Explanations are in the following sections. @cindex overall options @cindex options, overall -Compilation can involve as many as four stages: preprocessing, compilation -proper, assembly, and linking, always in that order. The first three +Compilation can involve as many as four stages: preprocessing, code +generation (often what is really meant by the term ``compilation''), +assembly, and linking, always in that order. The first three stages apply to an individual source file, and end by producing an object file; linking combines all the object files (those newly compiled, and those specified as input) into an executable file. @@ -1424,9 +1441,9 @@ compiled, and those specified as input) into an executable file. @cindex file type @cindex types, file For any given input file, the file name suffix determines what kind of -compilation is done. -Suffixes specific to GNU Fortran are listed -below. +program is contained in the file---that is, the language in which the +program is written is generally indicated by the suffix. +Suffixes specific to GNU Fortran are listed below. @xref{Overall Options,,gcc,Using and Porting GNU CC}, for information on suffixes recognized by GNU CC. @@ -1441,8 +1458,8 @@ Fortran source code that should not be preprocessed. @cindex Fortran preprocessor @cindex cpp program @cindex programs, cpp -@cindex .F -@cindex .fpp +@cindex .F filename suffix +@cindex .fpp filename suffix @item @var{file}.F @item @var{file}.fpp Fortran source code that must be preprocessed (by the C preprocessor @@ -1460,26 +1477,42 @@ the @file{@var{file}.for} and @file{@var{file}.fpp} nomenclature. @cindex #include @cindex #if Use of the preprocessor @code{cpp} allows use of C-like -constructs such as @samp{#define} and @samp{#include}, but can +constructs such as @code{#define} and @code{#include}, but can lead to unexpected, even mistaken, results due to Fortran's source file format. It is recommended that use of the C preprocessor -be limited to @samp{#include} and, in -conjunction with @samp{#define}, only @samp{#if} and related directives, +be limited to @code{#include} and, in +conjunction with @code{#define}, only @code{#if} and related directives, thus avoiding in-line macro expansion entirely. This recommendation applies especially when using the traditional fixed source form. With free source form, fewer unexpected transformations are likely to happen, but use of -Hollerith and things like continued character constants can nevertheless -present problems. +constructs such as Hollerith and character constants can nevertheless +present problems, especially when these are continued across multiple +source lines. +These problems result, primarily, from differences between the way +such constants are interpreted by the C preprocessor and by a Fortran +compiler. + +@emph{Note:} The @samp{-traditional} and @samp{-undef} flags are supplied +to @code{cpp} by default, to avoid unpleasant surprises. +@xref{Preprocessor Options,,Options Controlling the Preprocessor, +gcc,Using and Porting GNU CC}. +This means that ANSI C preprocessor features (such as the @samp{#} +operator) aren't available, and only variables in the C reserved +namespace (generally, names with a leading underscore) are liable to +substitution by C predefines. +Thus, if you want to do system-specific +tests, use, for example, @samp{#ifdef __linux__} rather than @samp{#ifdef linux}. +Use the @samp{-v} option to see exactly how the preprocessor is invoked. The following options that affect overall processing are recognized by the @code{g77} and @code{gcc} commands in a GNU Fortran installation: @table @code @item --driver=@var{command} -This works only when invoking the @code{g77} command, not +This works when invoking only the @code{g77} command, not when invoking the @code{gcc} command. @xref{Invoking G77,,GNU Fortran Command Options}, for information on this option. @@ -1499,16 +1532,30 @@ and when the resulting commands compile Fortran source files.) @cindex options, -fset-g77-defaults @item -fset-g77-defaults Set up whatever @code{gcc} options are to apply to Fortran -compilations. -As of version 0.5.18, this is equivalent to @samp{-fmove-all-movables --freduce-all-givs -frerun-loop-opt}. -(This is supplied automatically when compiling Fortran code. -The description of this option is here so that users seeing +compilations, and avoid running internal consistency checks +that might take some time. + +As of version 0.5.20, this is equivalent to @samp{-fmove-all-movables +-freduce-all-givs -frerun-loop-opt -fargument-noalias-global}. + +This option is supplied automatically when compiling Fortran code +via the @code{g77} or @code{gcc} command. +The description of this option is provided so that users seeing it in the output of, say, @samp{g77 -v} understand why it is there. + +@cindex modifying g77 +@cindex code, modifying Also, developers who run @code{f771} directly might want to specify it by hand to get the same defaults as they would running @code{f771} -via @code{g77} or @code{gcc}.) +via @code{g77} or @code{gcc}. +However, such developers should, after linking a new @code{f771} +executable, invoke it without this option once, +e.g. via @kbd{./f771 -quiet < /dev/null}, +to ensure that they have not introduced any +internal inconsistencies (such as in the table of +intrinsics) before proceeding---@code{g77} will crash +with a diagnostic if it detects an inconsistency. @cindex -fno-silent option @cindex options, -fno-silent @@ -1549,7 +1596,9 @@ Specify that certain ``ugly'' constructs are to be quietly accepted. Same as: @smallexample --fugly-args -fugly-assumed -fugly-comma -fugly-init -fugly-logint +-fugly-args -fugly-assign -fugly-assumed +-fugly-comma -fugly-complex -fugly-init +-fugly-logint @end smallexample These constructs are considered inappropriate to use in new @@ -1557,6 +1606,14 @@ or well-maintained portable Fortran code, but widely used in old code. @xref{Distensions}, for more information. +@emph{Note:} The @samp{-fugly} option is likely to +be removed in a future version. +Implicitly enabling all the @samp{-fugly-*} options +is unlikely to be feasible, or sensible, in the future, +so users should learn to specify only those +@samp{-fugly-*} options they really need for a +particular source file. + @cindex -fno-ugly option @cindex options, -fno-ugly @item -fno-ugly @@ -1566,10 +1623,13 @@ Specify that all ``ugly'' constructs are to be noisily rejected. Same as: @smallexample --fno-ugly-args -fno-ugly-assumed -fno-ugly-comma -fno-ugly-init +-fno-ugly-args -fno-ugly-assign -fno-ugly-assumed +-fno-ugly-comma -fno-ugly-complex -fno-ugly-init -fno-ugly-logint @end smallexample +@xref{Distensions}, for more information. + @cindex -ff66 option @cindex options, -ff66 @item -ff66 @@ -1649,32 +1709,26 @@ This option controls whether certain Fortran 90 constructs are recognized. (Other Fortran 90 constructs might or might not be recognized depending on other options such as -@samp{-fvxt-not-f90}, @samp{-ff90-intrinsics-enable}, and the +@samp{-fvxt}, @samp{-ff90-intrinsics-enable}, and the current level of support for Fortran 90.) -@xref{Extensions,,GNU Fortran Extensions}, for more information. +@xref{Fortran 90}, for more information. -@cindex -fvxt-not-f90 option -@cindex options, -fvxt-not-f90 -@item -fvxt-not-f90 -@cindex -ff90-not-vxt option -@cindex options, -ff90-not-vxt -@item -ff90-not-vxt +@cindex -fvxt option +@cindex options, -fvxt +@item -fvxt @cindex Fortran 90 features @cindex VXT features -Specify whether Fortran 90 or other popular extensions -are to be assumed for ambiguous constructs. -The default is -fvxt-not-f90. +Specify the treatment of certain constructs that have different +meanings depending on whether the code is written in +GNU Fortran (based on FORTRAN 77 and akin to Fortran 90) +or VXT Fortran (more like VAX FORTRAN). -For example, with @samp{-ff90-not-vxt}, -@samp{PRINT *,"double-quoted string"} is valid, -while with @samp{-fvxt-not-f90}, @samp{PRINT *,"2000} is valid. +The default is @samp{-fno-vxt}. +@samp{-fvxt} specifies that the VXT Fortran interpretations +for those constructs are to be chosen. -(There is no way to allow -both constructs in the general case, since statements like -@samp{PRINT *,"2000 !comment?"} would be ambiguous.) - -@xref{Dialects,,GNU Fortran Dialects}, for more information. +@xref{VXT Fortran}, for more information. @cindex -fdollar-ok option @cindex options, -fdollar-ok @@ -1718,12 +1772,22 @@ arguments (for example, @samp{CALL FOO(4HABCD)}). @xref{Ugly Implicit Argument Conversion}, for more information. +@cindex -fugly-assign option +@cindex options, -fugly-assign +@item -fugly-assign +Use the same storage for a given variable regardless of +whether it is used to hold an assigned-statement label +(as in @samp{ASSIGN 10 TO I}) or used to hold numeric data +(as in @samp{I = 3}). + +@xref{Ugly Assigned Labels}, for more information. + @cindex -fugly-assumed option @cindex options, -fugly-assumed @item -fugly-assumed -Assume any array with a final dimension specified as @samp{1} +Assume any dummy array with a final dimension specified as @samp{1} is really an assumed-size array, as if @samp{*} had been specified -instead. +for the final dimension instead of @samp{1}. For example, @samp{DIMENSION X(1)} is treated as if it had read @samp{DIMENSION X(*)}. @@ -1748,6 +1812,20 @@ a single trailing comma in an argument list. @xref{Ugly Null Arguments}, for more information. +@cindex -fugly-complex option +@cindex options, -fugly-complex +@item -fugly-complex +Do not complain about @samp{REAL(@var{expr})} or +@samp{AIMAG(@var{expr})} when @var{expr} is a @code{COMPLEX} +type other than @code{COMPLEX(KIND=1)}---usually +this is used to permit @code{COMPLEX(KIND=2)} +(@code{DOUBLE COMPLEX}) operands. + +The @samp{-ff90} option controls the interpretation +of this construct. + +@xref{Ugly Complex Part Extraction}, for more information. + @cindex -fno-ugly-init option @cindex options, -fno-ugly-init @item -fno-ugly-init @@ -1764,11 +1842,11 @@ For example, @samp{DATA I/'F'/, CHRVAR/65/, J/4HABCD/} is disallowed by @cindex -fugly-logint option @cindex options, -fugly-logint @item -fugly-logint -Treat @samp{INTEGER} and @samp{LOGICAL} variables and +Treat @code{INTEGER} and @code{LOGICAL} variables and expressions as potential stand-ins for each other. -For example, automatic conversion between @samp{INTEGER} and -@samp{LOGICAL} is enabled, for many contexts, via this option. +For example, automatic conversion between @code{INTEGER} and +@code{LOGICAL} is enabled, for many contexts, via this option. @xref{Ugly Integer Conversions}, for more information. @@ -1779,48 +1857,45 @@ For example, automatic conversion between @samp{INTEGER} and @cindex DO loops, one-trip @cindex one-trip DO loops @cindex compatibility, FORTRAN 66 -Imperative executable @samp{DO} loops are to be executed at +Imperative executable @code{DO} loops are to be executed at least once each time they are reached. ANSI FORTRAN 77 and more recent versions of the Fortran standard -specify that the body of an imperative @samp{DO} loop is not executed +specify that the body of an imperative @code{DO} loop is not executed if the number of iterations calculated from the parameters of the loop is less than 1. -(For example, @samp{DO 10 I = 1, 0}.) +(For example, @samp{DO 10 I = 1, 0}.)@ Such a loop is called a @dfn{zero-trip loop}. -Prior to ANSI FORTRAN 77, many compilers implemented @samp{DO} loops +Prior to ANSI FORTRAN 77, many compilers implemented @code{DO} loops such that the body of a loop would be executed at least once, even if the iteration count was zero. Fortran code written assuming this behavior is said to require @dfn{one-trip loops}. For example, some code written to the FORTRAN 66 standard -expects this behavior from its @samp{DO} loops, although that +expects this behavior from its @code{DO} loops, although that standard did not specify this behavior. The @samp{-fonetrip} option specifies that the source file(s) being compiled require one-trip loops. -This option affects only those loops specified by the (imperative) @samp{DO} -statement and by implied-@samp{DO} lists in I/O statements. -Loops specified by implied-@samp{DO} lists in @samp{DATA} and +This option affects only those loops specified by the (imperative) @code{DO} +statement and by implied-@code{DO} lists in I/O statements. +Loops specified by implied-@code{DO} lists in @code{DATA} and specification (non-executable) statements are not affected. -@cindex -fno-typeless-boz option -@cindex options, -fno-typeless-boz +@cindex -ftypeless-boz option +@cindex options, -ftypeless-boz @cindex prefix-radix constants @cindex constants, prefix-radix @cindex constants, types @cindex types, constants -@item -fno-typeless-boz +@item -ftypeless-boz Specifies that prefix-radix non-decimal constants, such as -@samp{Z'ABCD'}, as @samp{INTEGER} instead of typeless. - -Currently plans call for this option being the default as of -version 0.5.20. +@samp{Z'ABCD'}, are typeless instead of @code{INTEGER(KIND=1)}. You can test for yourself whether a particular compiler treats -the prefix form as @samp{INTEGER} or typeless by running the +the prefix form as @code{INTEGER(KIND=1)} or typeless by running the following program: @smallexample @@ -1833,7 +1908,7 @@ END @end smallexample Reports indicate that many compilers process this form as -@samp{INTEGER}, though a few as typeless, and at least one +@code{INTEGER(KIND=1)}, though a few as typeless, and at least one based on a command-line option specifying some kind of compatibility. @@ -1941,24 +2016,6 @@ while allowing any-case matching of intrinsics and keywords. For example, @samp{call Foo(i,I)} would pass two @emph{different} variables named @samp{i} and @samp{I} to a procedure named @samp{Foo}.) -@cindex -fdcp-intrinsics-delete option -@cindex options, -fdcp-intrinsics-delete -@item -fdcp-intrinsics-delete -@cindex -fdcp-intrinsics-hide option -@cindex options, -fdcp-intrinsics-hide -@item -fdcp-intrinsics-hide -@cindex -fdcp-intrinsics-disable option -@cindex options, -fdcp-intrinsics-disable -@item -fdcp-intrinsics-disable -@cindex -fdcp-intrinsics-enable option -@cindex options, -fdcp-intrinsics-enable -@item -fdcp-intrinsics-enable -@cindex Digital Fortran features -@cindex COMPLEX intrinsics -@cindex intrinsics, COMPLEX -Specify status of Digital's COMPLEX-related intrinsics. -@samp{-fdcp-intrinsics-enable} is the default. - @cindex -ff2c-intrinsics-delete option @cindex options, -ff2c-intrinsics-delete @item -ff2c-intrinsics-delete @@ -1991,7 +2048,25 @@ Specify status of f2c-specific intrinsics. @cindex Fortran 90 intrinsics @cindex intrinsics, Fortran 90 Specify status of F90-specific intrinsics. -@samp{-ff90-intrinsics-delete} is the default. +@samp{-ff90-intrinsics-enable} is the default. + +@cindex -fgnu-intrinsics-delete option +@cindex options, -fgnu-intrinsics-delete +@item -fgnu-intrinsics-delete +@cindex -fgnu-intrinsics-hide option +@cindex options, -fgnu-intrinsics-hide +@item -fgnu-intrinsics-hide +@cindex -fgnu-intrinsics-disable option +@cindex options, -fgnu-intrinsics-disable +@item -fgnu-intrinsics-disable +@cindex -fgnu-intrinsics-enable option +@cindex options, -fgnu-intrinsics-enable +@item -fgnu-intrinsics-enable +@cindex Digital Fortran features +@cindex COMPLEX intrinsics +@cindex intrinsics, COMPLEX +Specify status of Digital's COMPLEX-related intrinsics. +@samp{-fgnu-intrinsics-enable} is the default. @cindex -fmil-intrinsics-delete option @cindex options, -fmil-intrinsics-delete @@ -2027,57 +2102,6 @@ Specify status of MIL-STD-1753-specific intrinsics. Specify status of UNIX intrinsics. @samp{-funix-intrinsics-enable} is the default. -@cindex FLUSH() intrinsic -@cindex intrinsics, FLUSH() -For example, if your code invokes @code{FLUSH} as -a library function and thus works with other UNIX Fortran -compilers or earlier version of @code{g77}, either add the -@samp{EXTERNAL FLUSH} statement or, perhaps -more convenient for you, compile with the -@samp{-funix-intrinsics-hide} or -@samp{-funix-intrinsics-delete} option. - -@cindex ABORT() intrinsic -@cindex intrinsics, ABORT() -@cindex EXIT() intrinsic -@cindex intrinsics, EXIT() -@cindex FSEEK() intrinsic -@cindex intrinsics, FSEEK() -@cindex SIGNAL() intrinsic -@cindex intrinsics, SIGNAL() -@cindex SYSTEM() intrinsic -@cindex intrinsics, SYSTEM() -@cindex intrinsic subroutines -@cindex subroutines, intrinsic -@cindex intrinsic functions -@cindex functions, intrinsic -@cindex side effects -@cindex intrinsics, side effects of -Note that @code{ABORT}, @code{EXIT}, @code{FLUSH}, @code{FSEEK}, -@code{SIGNAL}, and -@code{SYSTEM} are intrinsic subroutines, not functions (since they have -side effects), so to get the return values from @code{FSEEK}, -@code{SIGNAL}, and @code{SYSTEM}, append a final argument specifying -an @samp{INTEGER} -variable or array element to receive the returned status. -(For example, @samp{CALL SYSTEM('rm foo',ISTAT)}.) - -@code{FLUSH()} accepts an optional single @samp{INTEGER} argument, -since many Fortran implementations allow or require a unit number. -Currently, since @code{libf2c} -does not flush a given unit number, this argument is not used---all -units are flushed by @code{libf2c}'s implementation of @code{FLUSH()}. -Do not depend on this behavior---if you want to flush all units, -use @samp{CALL FLUSH} (that is, specify no arguments to @code{FLUSH}). - -@code{EXIT()} accepts an optional single @samp{INTEGER} argument. -If omitted, zero is the default (as in @samp{CALL EXIT(0)}). -The default might change on -configurations where the ``normal return status'' is not zero, however. -If you want to return a ``success'' status, it is best to call @code{EXIT} -with no arguments in your code, and let @code{g77} choose the appropriate -default. - @cindex -fvxt-intrinsics-delete option @cindex options, -fvxt-intrinsics-delete @item -fvxt-intrinsics-delete @@ -2093,7 +2117,7 @@ default. @cindex VXT intrinsics @cindex intrinsics, VXT Specify status of VXT intrinsics. -@samp{-fvxt-intrinsics-delete} is the default. +@samp{-fvxt-intrinsics-enable} is the default. @cindex -ffixed-line-length-@var{n} option @cindex options, -ffixed-line-length-@var{n} @@ -2160,9 +2184,10 @@ Fortran features are supported as well. With this option, many of them are rejected. Some users try to use @samp{-pedantic} to check programs for strict ANSI -conformance. They soon find that it does not do quite what they want: -it finds some non-ANSI practices, but not all---however, improvements -to @code{g77} in this area are welcome. +conformance. +They soon find that it does not do quite what they want---it finds some +non-ANSI practices, but not all. +However, improvements to @code{g77} in this area are welcome. @cindex -pedantic-errors option @cindex options, -pedantic-errors @@ -2191,7 +2216,7 @@ Inhibit all warning messages. @cindex effecting IMPLICIT NONE Warn whenever a variable, array, or function is implicitly declared. -Has an effect similar to using the @samp{IMPLICIT NONE} statement +Has an effect similar to using the @code{IMPLICIT NONE} statement in every program unit. (Some Fortran compilers provide this feature by an option named @samp{-u} or @samp{/WARNINGS=DECLARATIONS}.) @@ -2211,7 +2236,7 @@ Warn whenever a variable is unused aside from its declaration. Warn whenever an automatic variable is used without first being initialized. These warnings are possible only in optimizing compilation, -because they require data flow information that is computed only +because they require data-flow information that is computed only when optimizing. If you don't specify @samp{-O}, you simply won't get these warnings. @@ -2224,7 +2249,7 @@ arrays, even when they are in registers. Note that there might be no warning about a variable that is used only to compute a value that itself is never used, because such -computations may be deleted by data flow analysis before the warnings +computations may be deleted by data-flow analysis before the warnings are printed. These warnings are made optional because GNU Fortran is not smart @@ -2312,8 +2337,8 @@ be interpreted as @samp{X**(-(Y*Z))}. A revealing example is the constant expression @samp{2**-2*1.}, which @code{g77} evaluates to .25, while others might evaluate -it to 0., the difference being the way precedence affects type -promotion. +it to 0., the difference resulting from the way precedence affects +type promotion. (The @samp{-fpedantic} option also warns about expressions having two arithmetic operators in a row.) @@ -2331,7 +2356,7 @@ in a surprising way is @samp{-I*S}, where @var{I} holds the value @samp{-2147483648} and @var{S} holds @samp{0.5}. On many systems, negating @var{I} results in the same value, not a positive number, because it is already the -lower bound of what an @samp{INTEGER} variable can hold. +lower bound of what an @code{INTEGER(KIND=1)} variable can hold. So, the expression evaluates to a positive number, while the ``expected'' interpretation, @samp{(-I)*S}, would evaluate to a negative number. @@ -2348,15 +2373,14 @@ code. @cindex DO statement @cindex statements, DO @item -@samp{DO} loops with @samp{DO} variables that are not -of integral type---that is, using @samp{REAL} or -@samp{DOUBLE PRECISION} variables as loop control -variables. +@code{DO} loops with @code{DO} variables that are not +of integral type---that is, using @code{REAL} +variables as loop control variables. Although such loops can be written to work in the ``obvious'' way, the way @code{g77} is required by the Fortran standard to interpret such code is likely to be quite different from the way many programmers expect. -(This is true of all @samp{DO} loops, but the differences +(This is true of all @code{DO} loops, but the differences are pronounced for non-integral loop control variables.) @xref{Loops}, for more information. @@ -2372,7 +2396,8 @@ Make all warnings into errors. @item -W @cindex extra warnings @cindex warnings, extra -Turns on ``extra warnings'' and the @samp{uninitialized} option. +Turns on ``extra warnings'' and, if optimization is specified +via @samp{-O}, the @samp{-Wuninitialized} option. (This might change in future versions of @code{g77}.) ``Extra warnings'' are issued for: @@ -2391,7 +2416,7 @@ specified). @item @cindex overflow Overflows involving floating-point constants (not available -for certain configurations?). +for certain configurations). @end itemize @end table @@ -2457,12 +2482,12 @@ Produce debugging information in the operating system's native format (stabs, COFF, XCOFF, or DWARF). GDB can work with this debugging information. -@cindex COMMON blocks -@cindex EQUIVALENCE areas +@cindex common blocks +@cindex equivalence areas @cindex missing debug features Support for this option in Fortran programs is incomplete. In particular, names of variables and arrays in common blocks -or that are storage-associated via @samp{EQUIVALENCE} are +or that are storage-associated via @code{EQUIVALENCE} are unavailable to the debugger. However, version 0.5.19 of @code{g77} does provide this information @@ -2489,6 +2514,37 @@ The following flags have particular applicability when compiling Fortran programs: @table @code +@cindex -malign-double option +@cindex options, -malign-double +@item -malign-double +(Intel 386 architecture only.) + +Noticeably improves performance of @code{g77} programs making +heavy use of @code{REAL(KIND=2)} (@code{DOUBLE PRECISION}) data +on some systems. +In particular, systems using Pentium, Pentium Pro, 585, and +686 implementations +of the i386 architecture execute programs faster when +@code{REAL(KIND=2)} (@code{DOUBLE PRECISION}) data are +aligned on 64-bit boundaries +in memory. + +This option can, at least, make benchmark results more consistent +across various system configurations, versions of the program, +and data sets. + +@emph{Note:} The warning in the @code{gcc} documentation about +this option does not apply, generally speaking, to Fortran +code compiled by @code{g77}. + +@emph{Also note:} Apparently due to a @code{gcc} backend bug, +@samp{-malign-double} does not align stack-allocated data (such as +local variables neither @code{SAVE}d nor reckoned to take up too +much space to put on the stack). + +@emph{Also also note:} The negative form of @samp{-malign-double} +is @samp{-mno-align-double}, not @samp{-benign-double}. + @cindex -ffloat-store option @cindex options, -ffloat-store @item -ffloat-store @@ -2565,14 +2621,24 @@ Definitely improves performance on some code. Definitely improves performance on some code. @item -fno-move-all-movables +@cindex -fno-move-all-movables option +@cindex options, -fno-move-all-movables @item -fno-reduce-all-givs +@cindex -fno-reduce-all-givs option +@cindex options, -fno-reduce-all-givs @item -fno-rerun-loop-opt +@cindex -fno-rerun-loop-opt option +@cindex options, -fno-rerun-loop-opt Each of these might improve performance on some code. Analysis of Fortran code optimization and the resulting optimizations triggered by the above options were contributed by Toon Moene (@code{toon@@moene.indiv.nluug.nl}). +These three options are intended to be removed someday, once +they have helped determine the efficacy of various +approaches to improving the performance of Fortran code. + Please let us know how use of these options affects the performance of your production code. We're particularly interested in code that runs faster @@ -2598,14 +2664,14 @@ file before actual compilation. @xref{Preprocessor Options,,Options Controlling the Preprocessor, gcc,Using and Porting GNU CC}, for information on C preprocessor options. -@cindex INCLUDE statement -@cindex statements, INCLUDE +@cindex INCLUDE directive +@cindex directive, INCLUDE Some of these options also affect how @code{g77} processes the -@samp{INCLUDE} statement. -Since this statement is processed even when preprocessing +@code{INCLUDE} directive. +Since this directive is processed even when preprocessing is not requested, it is not described in this section. @xref{Directory Options,,Options for Directory Search}, for -information on how @code{g77} processes the @samp{INCLUDE} statement. +information on how @code{g77} processes the @code{INCLUDE} directive. @node Directory Options @section Options for Directory Search @@ -2614,14 +2680,14 @@ information on how @code{g77} processes the @samp{INCLUDE} statement. @cindex search path These options affect how the @code{cpp} preprocessor searches -for files specified via the @samp{#include} directive. +for files specified via the @code{#include} directive. Therefore, when compiling Fortran programs, they are meaningful when the preproecssor is used. -@cindex INCLUDE statement -@cindex statements, INCLUDE +@cindex INCLUDE directive +@cindex directive, INCLUDE Some of these options also affect how @code{g77} searches -for files specified via the @samp{INCLUDE} statement. +for files specified via the @code{INCLUDE} directive. These options are: @table @code @@ -2634,8 +2700,8 @@ These options are: @cindex directory search paths for inclusion @cindex inclusion, directory search paths for @cindex searching for included files -These affect interpretation of the @samp{INCLUDE} statement -(as well as of the @samp{#include} directive of the @code{cpp} +These affect interpretation of the @code{INCLUDE} directive +(as well as of the @code{#include} directive of the @code{cpp} preprocessor). Note that @samp{-I@var{dir}} must be specified @emph{without} any @@ -2645,8 +2711,8 @@ is rejected by the @code{g77} compiler (though the preprocessor supports the latter form). @c this is due to toplev.c's inflexible option processing Also note that the general behavior of @samp{-I} and -@samp{INCLUDE} is pretty much the same as of @samp{-I} with -@samp{#include} in the @code{cpp} preprocessor, with regard to +@code{INCLUDE} is pretty much the same as of @samp{-I} with +@code{#include} in the @code{cpp} preprocessor, with regard to looking for @file{header.gcc} files and other such things. @xref{Directory Options,,Options for Directory Search, @@ -2700,8 +2766,8 @@ good idea to also use @samp{-fno-automatic} with @samp{-finit-local-zero}. @cindex -fno-f2c option @cindex options, -fno-f2c @item -fno-f2c -@cindex f2c compatibility -@cindex compatibility, f2c +@cindex @code{f2c} compatibility +@cindex compatibility, @code{f2c} Do not generate code designed to be compatible with code generated by @code{f2c}. @@ -2830,7 +2896,7 @@ Ignore the @samp{#ident} directive. @item -fzeros Treat initial values of zero as if they were any other value. -As of version 0.5.18, @code{g77} normally treats @samp{DATA} and +As of version 0.5.18, @code{g77} normally treats @code{DATA} and other statements that are used specify initial values of zero for variables and arrays as if no values were actually specified, in the sense that no diagnostics regarding multiple initializations @@ -2852,7 +2918,7 @@ programs; standard-conforming programs should not be affected. @cindex -fdebug-kludge option @cindex options, -fdebug-kludge @item -fdebug-kludge -Emit information on @samp{COMMON} and @samp{EQUIVALENCE} members +Emit information on @code{COMMON} and @code{EQUIVALENCE} members that might help users of debuggers work around lack of proper debugging information on such members. @@ -2862,8 +2928,8 @@ This information consists of establishing the type and contents of each such member so that, when a debugger is asked to print the contents, the printed information provides rudimentary debugging information. This information identifies the name of the aggregate area (either the -@samp{COMMON} block name, or the @code{g77}-assigned name for the -@samp{EQUIVALENCE} name) and the offset, in bytes, of the member from +@code{COMMON} block name, or the @code{g77}-assigned name for the +@code{EQUIVALENCE} name) and the offset, in bytes, of the member from the beginning of the area. Using @code{gdb}, this information is not coherently displayed in the Fortran @@ -2873,7 +2939,7 @@ Use @samp{set language c} and @samp{set language fortran} to accomplish this. For example: -@example +@smallexample COMMON /X/A,B EQUIVALENCE (C,D) CHARACTER XX*50 @@ -2907,16 +2973,86 @@ $6 = "At (EQUIVALENCE) `__g77_equiv_xx' plus 20 bytes" $7 = "At (EQUIVALENCE) `__g77_equiv_xx' plus 1 bytes" (gdb) set language fortran (gdb) -@end example +@end smallexample +@noindent Use @samp{-fdebug-kludge} to generate this information, -which might make some programs noticably larger. +which might make some programs noticeably larger. @emph{Caution:} Future versions of @code{g77} might disregard this option (and its negative form). Current plans call for this to happen when published versions of @code{g77} and @code{gdb} exist that provide proper access to debugging information on -@samp{COMMON} and @samp{EQUIVALENCE} members. +@code{COMMON} and @code{EQUIVALENCE} members. + +@cindex -fno-emulate-complex option +@cindex options, -fno-emulate-complex +@item -fno-emulate-complex +Implement @code{COMPLEX} arithmetic using the facilities in +the @code{gcc} back end that provide direct support of +@code{complex} arithmetic, instead of emulating the arithmetic. + +@code{gcc} has some known problems in its back-end support +for @code{complex} arithmetic, due primarily to the support not being +completed as of version 2.7.2.2. +Other front ends for the @code{gcc} back end avoid this problem +by emulating @code{complex} arithmetic at a higher level, so the +back end sees arithmetic on the real and imaginary components. +To make @code{g77} more portable to systems where @code{complex} +support in the @code{gcc} back end is particularly troublesome, +@code{g77} now defaults to performing the same kinds of emulations +done by these other front ends. + +Use @samp{-fno-emulate-complex} to try the @code{complex} support +in the @code{gcc} back end, in case it works and produces faster +programs. +So far, all the known bugs seem to involve compile-time crashes, +rather than the generation of incorrect code. + +Use of this option should not affect how Fortran code compiled +by @code{g77} works in terms of its interfaces to other code, +e.g. that compiled by @code{f2c}. + +@emph{Caution:} Future versions of @code{g77} are likely to change +the default for this option to +@samp{-fno-emulate-complex}, and perhaps someday ignore both forms +of this option. + +Also, it is possible that use of the @samp{-fno-emulate-complex} option +could result in incorrect code being silently produced by @code{g77}. +But, this is generally true of compilers anyway, so, as usual, test +the programs you compile before assuming they are working. + +@cindex -falias-check option +@cindex options, -falias-check +@cindex -fargument-alias option +@cindex options, -fargument-alias +@cindex -fargument-noalias option +@cindex options, -fargument-noalias +@cindex -fno-argument-noalias-global option +@cindex options, -fno-argument-noalias-global +@item -falias-check +@item -fargument-alias +@item -fargument-noalias +@item -fno-argument-noalias-global +These options specify to what degree aliasing +(overlap) +is permitted between +arguments (passed as pointers) and @code{COMMON} (external, or +public) storage. + +The default for Fortran code, as mandated by the FORTRAN 77 and +Fortran 90 standards, is @samp{-fargument-noalias-global}. +The default for code written in the C language family is +@samp{-fargument-alias}. + +Note that, on some systems, compiling with @samp{-fforce-addr} in +effect can produce more optimal code when the default aliasing +options are in effect (and when optimization is enabled). + +@xref{Aliasing Assumed To Work}, for detailed information on the implications +of compiling Fortran code that depends on the ability to alias dummy +arguments. @end table @xref{Code Gen Options,,Options for Code Generation Conventions, @@ -2978,37 +3114,212 @@ variables. @cindex changes, user-visible @cindex user-visible changes +This section describes changes to @code{g77} that are visible +to the programmers who actually write and maintain Fortran +code they compile with @code{g77}. +Information on changes to installation procedures, +changes to the documentation, and bug fixes is +not provided here, unless it is likely to affect how +users use @code{g77}. +@xref{News,,News About GNU Fortran}, for information on +such changes to @code{g77}. + To find out about existing bugs and ongoing plans for GNU -Fortran, on Internet do @samp{finger -l fortran@@gnu.ai.mit.edu} -or whatever is the equivalent on your system. -(You might need to use the address @samp{fortran@@gate-1.gnu.ai.mit.edu} -instead, or use @samp{gate-2}, @samp{gate-3}, @samp{gate-4}, and so on, -instead of @samp{gate-1}.) - -Alternatively, retrieve @url{ftp://gnu.ai.mit.edu/g77.plan} via -anonymous ftp, or if you cannot do that, email -@samp{fortran@@gnu.ai.mit.edu} asking for a recent copy of the +Fortran, retrieve @url{ftp://alpha.gnu.ai.mit.edu/g77.plan} +or, if you cannot do that, email +@email{fortran@@gnu.ai.mit.edu} asking for a recent copy of the GNU Fortran @file{.plan} file. -(The @code{finger} command shown above obtains the most recent -copy of all these methods.) + +@heading In 0.5.20: +@itemize @bullet +@item +The @samp{-fno-typeless-boz} option is now the default. + +This option specifies that non-decimal-radix +constants using the prefixed-radix form (such as @samp{Z'1234'}) +are to be interpreted as @code{INTEGER(KIND=1)} constants. +Specify @samp{-ftypeless-boz} to cause such +constants to be interpreted as typeless. + +(Version 0.5.19 introduced @samp{-fno-typeless-boz} and +its inverse.) + +@xref{Fortran Dialect Options,,Options Controlling Fortran Dialect}, +for information on the @samp{-ftypeless-boz} option. + +@item +Options @samp{-ff90-intrinsics-enable} and +@samp{-fvxt-intrinsics-enable} now are the +defaults. + +Some programs might use names that clash with +intrinsic names defined (and now enabled) by these +options or by the new @code{libU77} intrinsics. +Users of such programs might need to compile them +differently (using, for example, @samp{-ff90-intrinsics-disable}) +or, better yet, insert appropriate @code{EXTERNAL} +statements specifying that these names are not intended +to be names of intrinsics. + +@item +The @samp{ALWAYS_FLUSH} macro is no longer defined when +building @code{libf2c}, which should result in improved +I/O performance, especially over NFS. + +@emph{Note:} If you have code that depends on the behavior +of @code{libf2c} when built with @samp{ALWAYS_FLUSH} defined, +you will have to modify @code{libf2c} accordingly before +building it from this and future versions of @code{g77}. + +@xref{Output Assumed To Flush}, for more information. + +@item +Dave Love's implementation of @code{libU77} has been +added to the version of @code{libf2c} distributed with +and built by @code{g77}. +@code{g77} now knows about the routines in this library +as intrinsics. + +@item +New option @samp{-fvxt} specifies that the +source file is written in VXT Fortran, instead of GNU Fortran. + +@xref{VXT Fortran}, for more information on the constructs +recognized when the @samp{-fvxt} option is specified. + +@item +The @samp{-fvxt-not-f90} option has been deleted, +along with its inverse, @samp{-ff90-not-vxt}. + +If you used one of these deleted options, you should +re-read the pertinent documentation to determine which +options, if any, are appropriate for compiling your +code with this version of @code{g77}. + +@xref{Other Dialects}, for more information. + +@item +The @samp{-fugly} option now issues a warning, as it +likely will be removed in a future version. + +(Enabling all the @samp{-fugly-*} options is unlikely +to be feasible, or sensible, in the future, +so users should learn to specify only those +@samp{-fugly-*} options they really need for a +particular source file.) + +@item +The @samp{-fugly-assumed} option, introduced in +version 0.5.19, has been changed to +better accommodate old and new code. +@xref{Ugly Assumed-Size Arrays}, for more information. + +@item +Related to supporting Alpha (AXP) machines, the @code{LOC()} +intrinsic and @code{%LOC()} construct now return +values of @code{INTEGER(KIND=0)} type, +as defined by the GNU Fortran language. + +This type is wide enough +(holds the same number of bits) +as the character-pointer type on the machine. + +On most systems, this won't make a noticable difference, +whereas on Alphas and other systems with 64-bit pointers, +the @code{INTEGER(KIND=0)} type is equivalent to @code{INTEGER(KIND=2)} +(often referred to as @code{INTEGER*8}) +instead of the more common @code{INTEGER(KIND=1)} +(often referred to as @code{INTEGER*4}). + +@item +Emulate @code{COMPLEX} arithmetic in the @code{g77} front +end, to avoid bugs in @code{complex} support in the +@code{gcc} back end. +New option @samp{-fno-emulate-complex} +causes @code{g77} to revert the 0.5.19 behavior. + +@item +Dummy arguments are no longer assumed to potentially alias +(overlap) +other dummy arguments or @code{COMMON} areas when any of +these are defined (assigned to) by Fortran code. + +This can result in faster and/or smaller programs when +compiling with optimization enabled, though on some +systems this effect is observed only when @samp{-fforce-addr} +also is specified. + +New options @samp{-falias-check}, @samp{-fargument-alias}, +@samp{-fargument-noalias}, +and @samp{-fno-argument-noalias-global} control the +way @code{g77} handles potential aliasing. + +@xref{Aliasing Assumed To Work}, for detailed information on why the +new defaults might result in some programs no longer working the way they +did when compiled by previous versions of @code{g77}. + +@item +New option @samp{-fugly-assign} specifies that the +same memory locations are to be used to hold the +values assigned by both statements @samp{I = 3} and +@samp{ASSIGN 10 TO I}, for example. +(Normally, @code{g77} uses a separate memory location +to hold assigned statement labels.) + +@xref{Ugly Assigned Labels}, for more information. + +@item +@code{FORMAT} and @code{ENTRY} statements now are allowed to +precede @code{IMPLICIT NONE} statements. + +@item +Enable full support of @code{INTEGER(KIND=2)} +(often referred to as @code{INTEGER*8}) +available in +@code{libf2c} and @file{f2c.h} so that @code{f2c} users +may make full use of its features via the @code{g77} +version of @file{f2c.h} and the @code{INTEGER(KIND=2)} +support routines in the @code{g77} version of @code{libf2c}. + +@item +Improve @code{g77} driver and @code{libf2c} so that @samp{g77 -v} +yields version information on the library. + +@item +The @code{SNGL} and @code{FLOAT} intrinsics now are +specific intrinsics, instead of synonyms for the +generic intrinsic @code{REAL}. + +@item +New intrinsics have been added. +These are @code{REALPART}, @code{IMAGPART}, +@code{COMPLEX}, +@code{LONG}, and @code{SHORT}. + +@item +A new group of intrinsics, @samp{gnu}, has been added +to contain the new @code{REALPART}, @code{IMAGPART}, +and @code{COMPLEX} intrinsics. +An old group, @samp{dcp}, has been removed. +@end itemize @heading In 0.5.19: @itemize @bullet @item A temporary kludge option provides bare-bones information on -@samp{COMMON} and @samp{EQUIVALENCE} members at debug time. +@code{COMMON} and @code{EQUIVALENCE} members at debug time. @xref{Code Gen Options,,Options for Code Generation Conventions}, for information on the @samp{-fdebug-kludge} option. @item New @samp{-fonetrip} option specifies FORTRAN-66-style -one-trip @samp{DO} loops. +one-trip @code{DO} loops. @item New @samp{-fno-silent} option causes names of program units to be printed as they are compiled, in a fashion similar to -UNIX @samp{f77} and @samp{f2c}. +UNIX @code{f77} and @code{f2c}. @item New @samp{-fugly-assumed} option specifies that arrays @@ -3018,7 +3329,7 @@ treated as assumed-size. @item New @samp{-fno-typeless-boz} option specifies that non-decimal-radix constants using the prefixed-radix form (such as @samp{Z'1234'}) -are to be interpreted as @samp{INTEGER} constants. +are to be interpreted as @code{INTEGER(KIND=1)} constants. @item New @samp{-ff66} option is a ``shorthand'' option that specifies @@ -3026,7 +3337,7 @@ behaviors considered appropriate for FORTRAN 66 programs. @item New @samp{-ff77} option is a ``shorthand'' option that specifies -behaviors considered appropriate for UNIX @samp{f77} programs. +behaviors considered appropriate for UNIX @code{f77} programs. @item New @samp{-fugly-comma} and @samp{-fugly-logint} options provided @@ -3037,18 +3348,18 @@ in that they do nothing more than enable (or disable) other @item Change code generation for list-directed I/O so it allows -for new versions of @samp{libf2c} that might return non-zero +for new versions of @code{libf2c} that might return non-zero status codes for some operations previously assumed to always return zero. -This change not only affects how @samp{IOSTAT=} variables +This change not only affects how @code{IOSTAT=} variables are set by list-directed I/O, it also affects whether -@samp{END=} and @samp{ERR=} labels are reached by these +@code{END=} and @code{ERR=} labels are reached by these operations. @item -Add intrinsic support for new @samp{FTELL} and @samp{FSEEK} -procedures in @samp{libf2c}. +Add intrinsic support for new @code{FTELL} and @code{FSEEK} +procedures in @code{libf2c}. @item Add options @samp{--help} and @samp{--version} to the @@ -3065,8 +3376,8 @@ The @code{BYTE} and @code{WORD} statements now are supported, to a limited extent. @item -@samp{INTEGER*1}, @samp{INTEGER*2}, @samp{INTEGER*8}, -and their @samp{LOGICAL} +@code{INTEGER*1}, @code{INTEGER*2}, @code{INTEGER*8}, +and their @code{LOGICAL} equivalents, now are supported to a limited extent. Among the missing elements are complete intrinsic and constant support. @@ -3105,9 +3416,9 @@ New option @samp{-fno-second-underscore}. @itemize @bullet @item -The @samp{ERF()} and @samp{ERFC()} intrinsics now are generic -intrinsics, mapping to @samp{ERF}/@samp{DERF} and -@samp{ERFC}/@samp{DERFC}, respectively. +The @code{ERF()} and @code{ERFC()} intrinsics now are generic +intrinsics, mapping to @code{ERF}/@code{DERF} and +@code{ERFC}/@code{DERFC}, respectively. @emph{Note:} Use @samp{INTRINSIC ERF,ERFC} in any code that might reference these as generic intrinsics, to improve the likelihood of diagnostics (instead of subtle run-time @@ -3117,7 +3428,7 @@ bugs) when using compilers that don't support these as intrinsics. New option @samp{-Wsurprising}. @item -DO loops with non-@samp{INTEGER} variables now diagnosed only when +DO loops with non-@code{INTEGER} variables now diagnosed only when @samp{-Wsurprising} specified. Previously, this was diagnosed @emph{unless} @samp{-fpedantic} or @samp{-fugly} was specified. @@ -3129,7 +3440,7 @@ Previously, this was diagnosed @emph{unless} @samp{-fpedantic} or @item @code{libf2c} changed to output a leading zero (0) digit for floating-point values output via list-directed and formatted output (to bring @code{g77} -more in line with many existing Fortran implementations---the +more into line with many existing Fortran implementations---the ANSI FORTRAN 77 standard leaves this choice to the implementation). @item @@ -3145,10 +3456,10 @@ including messages like @samp{In function `foo':} and @samp{In file included from...:}. @item -New group of intrinsics called @samp{unix}, including @samp{ABORT}, -@samp{DERF}, @samp{DERFC}, @samp{ERF}, @samp{ERFC}, @samp{EXIT}, -@samp{FLUSH}, @samp{GETARG}, @samp{GETENV}, @samp{SIGNAL}, and -@samp{SYSTEM}. +New group of intrinsics called @samp{unix}, including @code{ABORT}, +@code{DERF}, @code{DERFC}, @code{ERF}, @code{ERFC}, @code{EXIT}, +@code{FLUSH}, @code{GETARG}, @code{GETENV}, @code{SIGNAL}, and +@code{SYSTEM}. @item @samp{-funix-intrinsics-@{delete,hide,disable,enable@}} @@ -3181,98 +3492,6 @@ source-location info now is passed all the way through the compilation process instead of being lost. @end itemize -@heading In 0.5.15: - -@itemize @bullet -@item -@samp{-ffixed-line-length-@var{n}} option introduced. -@end itemize - -@heading In 0.5.14: - -@itemize @bullet -@item -Support for gcc's @samp{-I} option added. - -@item -@samp{-fbackslash} option added. - -@item -@samp{-fugly-args} option enabled by default (allows @samp{CALL FOO(4HABCD)}). - -@item -@samp{-fugly-init} option added. - -@item -@samp{-finit-local-zero} option added. - -@item -Support for the @code{gcc} option @samp{-Wimplicit} added. - -@item -@samp{-Wall} now implies @samp{-Wunused} and, when @samp{-O} is -specified, @samp{-Wuninitialized}. - -@cindex Hollerith constants -@cindex constants, Hollerith -@item -Hollerith constants as actual arguments now are passed by reference -instead of by value---so @samp{CALL FOO(4HABCD)} now is compiled exactly -the same as @samp{CALL FOO(%REF('ABCD'))}, instead of as -@samp{CALL FOO(%VAL('ABCD'))}. - -@item -Hollerith constants converted to larger types now are padded on the -right with spaces. -When converted to smaller types, warnings are issued -if non-spaces are truncated on the right. - -@item -Format specifications of arrays of types other than @samp{CHARACTER} are -allowed in I/O statements, such as when they contain Hollerith -data. - -@cindex typeless constants -@cindex constants, typeless -@item -Typeless constants as actual arguments now are passed by reference -to an @samp{INTEGER} version of the constant instead of by value. - -@item -Typeless constants converted to larger types are padded on the left -with zeros. -When converted to smaller types, warnings are issued if non-zero -bits are truncated on the left. - -@cindex %DESCR() intrinsic -@cindex intrinsics, %DESCR() -@item -@samp{%DESCR()} of a non-@samp{CHARACTER} expression treats the expression -as if it were @samp{CHARACTER}, passing both a pointer to the expression -and the length of the type of the expression in bytes, by value, in the -``hidden'' list of lengths used for @samp{CHARACTER} arguments. - -@item -The @samp{ICHAR()}, @samp{IACHAR()}, and @samp{LEN()} intrinsics now -accept character expressions involving concatenation of assumed-length -dummy arguments. - -@item -Block data program units now may contain @samp{NAMELIST}, @samp{EXTERNAL}, -@c @samp{INTRINSIC}, and @samp{VOLATILE} statements. -and @samp{INTRINSIC} statements. - -@item -Zero-length character expressions now supported. - -@item -Support for the @code{f2c} intrinsic @samp{IMAG()} added. - -@item -@samp{INCLUDE} statement restrictions, such as no continuation -lines allowed, now lifted. -@end itemize - @node Language @chapter The GNU Fortran Language @@ -3296,32 +3515,206 @@ of how it supports types, constants, and so on. Much of this is left up to the implementation by the various Fortran standards and accepted practice in the industry. +The GNU Fortran @emph{language} is described below. +Much of the material is organized along the same lines +as the ANSI FORTRAN 77 standard itself. + +@xref{Other Dialects}, for information on features @code{g77} supports +that are not part of the GNU Fortran language. + +@emph{Note}: This portion of the documentation definitely needs a lot +of work! + @menu -* Standard Support:: Degree of support for the ANSI FORTRAN 77 standard. -* Extensions:: Extensions to GNU Fortran. -* Types:: Data types. -* Constants:: Constants and their types. -* Source Form:: Form of source files (fixed, free, and so on). -* Pedantic Compilation:: Warnings about non-standard constructs. -* Case Sensitivity:: Uppercase and lowercase in source files. -* Intrinsics:: How intrinsics are grouped for easy management. -* Dialects:: Dialects supported by GNU Fortran. -* Object Compatibility:: Compatibility issues for code generated by @code{g77}. -* Distensions:: Misfeatures supported by GNU Fortran. +Relationship to the ANSI FORTRAN 77 standard: +* Direction of Language Development:: Where GNU Fortran is headed. +* Standard Support:: Degree of support for the standard. + +Extensions to the ANSI FORTRAN 77 standard: +* Conformance:: +* Notation Used:: +* Terms and Concepts:: +* Characters Lines Sequence:: +* Data Types and Constants:: +* Expressions:: +* Specification Statements:: +* Control Statements:: +* Functions and Subroutines:: +* Scope and Classes of Names:: @end menu +@node Direction of Language Development +@section Direction of Language Development +@cindex direction of language development +@cindex features, language +@cindex language features + +The purpose of the following description of the GNU Fortran +language is to promote wide portability of GNU Fortran programs. + +GNU Fortran is an evolving language, due to the +fact that @code{g77} itself is in beta test. +Some current features of the language might later +be redefined as dialects of Fortran supported by @code{g77} +when better ways to express these features are added to @code{g77}, +for example. +Such features would still be supported by +@code{g77}, but would be available only when +one or more command-line options were used. + +The GNU Fortran @emph{language} is distinct from the +GNU Fortran @emph{compilation system} (@code{g77}). + +For example, @code{g77} supports various dialects of +Fortran---in a sense, these are languages other than +GNU Fortran---though its primary +purpose is to support the GNU Fortran language, which also is +described in its documentation and by its implementation. + +On the other hand, non-GNU compilers might offer +support for the GNU Fortran language, and are encouraged +to do so. + +Currently, the GNU Fortran language is a fairly fuzzy object. +It represents something of a cross between what @code{g77} accepts +when compiling using the prevailing defaults and what this +document describes as being part of the language. + +Future versions of @code{g77} are expected to clarify the +definition of the language in the documentation. +Often, this will mean adding new features to the language, in the form +of both new documentation and new support in @code{g77}. +However, it might occasionally mean removing a feature +from the language itself to ``dialect'' status. +In such a case, the documentation be adjusted +to reflect the change, and @code{g77} itself would likely be changed +to require one or more command-line options to continue supporting +the feature. + +The development of the GNU Fortran language is intended to strike +a balance between: + +@itemize @bullet +@item +Serving as a mostly-upwards-compatible language from the +de facto UNIX Fortran dialect as supported by @code{f77}. + +@item +Offering new, well-designed language features. +Attributes of such features include +not making existing code any harder to read +(for those who might be unaware that the new +features are not in use) and +not making state-of-the-art +compilers take longer to issue diagnostics, +among others. + +@item +Supporting existing, well-written code without gratuitously +rejecting non-standard constructs, regardless of the origin +of the code (its dialect). + +@item +Offering default behavior and command-line options to reduce +and, where reasonable, eliminate the need for programmers to make +any modifications to code that already works in existing +production environments. + +@item +Diagnosing constructs that have different meanings in different +systems, languages, and dialects, while offering clear, +less ambiguous ways to express each of the different meanings +so programmers can change their code appropriately. +@end itemize + +One of the biggest practical challenges for the developers of the +GNU Fortran language is meeting the sometimes contradictory demands +of the above items. + +For example, a feature might be widely used in one popular environment, +but the exact same code that utilizes that feature might not work +as expected---perhaps it might mean something entirely different---in +another popular environment. + +Traditionally, Fortran compilers---even portable ones---have solved this +problem by simply offering the appropriate feature to users of +the respective systems. +This approach treats users of various Fortran systems and dialects +as remote ``islands'', or camps, of programmers, and assume that these +camps rarely come into contact with each other (or, +especially, with each other's code). + +Project GNU takes a radically different approach to software and language +design, in that it assumes that users of GNU software do not necessarily +care what kind of underlying system they are using, regardless +of whether they are using software (at the user-interface +level) or writing it (for example, writing Fortran or C code). + +As such, GNU users rarely need consider just what kind of underlying +hardware (or, in many cases, operating system) they are using at any +particular time. +They can use and write software designed for a general-purpose, +widely portable, heteregenous environment---the GNU environment. + +In line with this philosophy, GNU Fortran must evolve into a product +that is widely ported and portable not only in the sense that it can +be successfully built, installed, and run by users, but in the larger +sense that its users can use it in the same way, and expect largely the +same behaviors from it, regardless of the kind of system they are using +at any particular time. + +This approach constrains the solutions @code{g77} can use to resolve +conflicts between various camps of Fortran users. +If these two camps disagree about what a particular construct should +mean, @code{g77} cannot simply be changed to treat that particular construct as +having one meaning without comment (such as a warning), lest the users +expecting it to have the other meaning are unpleasantly surprised that +their code misbehaves when executed. + +The use of the ASCII backslash character in character constants is +an excellent (and still somewhat unresolved) example of this kind of +controversy. +@xref{Backslash in Constants}. +Other examples are likely to arise in the future, as @code{g77} developers +strive to improve its ability to accept an ever-wider variety of existing +Fortran code without requiring significant modifications to said code. + +Development of GNU Fortran is further constrained by the desire +to avoid requiring programmers to change their code. +This is important because it allows programmers, administrators, +and others to more faithfully evaluate and validate @code{g77} +(as an overall product and as new versions are distributed) +without having to support multiple versions of their programs +so that they continue to work the same way on their existing +systems (non-GNU perhaps, but possibly also earlier versions +of @code{g77}). + @node Standard Support @section ANSI FORTRAN 77 Standard Support @cindex ANSI FORTRAN 77 support @cindex standard support @cindex support for ANSI FORTRAN 77 +@cindex compatibility, FORTRAN 77 +@cindex FORTRAN 77 compatibility + +GNU Fortran supports ANSI FORTRAN 77 with the following caveats. +In summary, the only ANSI FORTRAN 77 features @code{g77} doesn't +support are those that are probably rarely used in actual code, +some of which are explicitly disallowed by the Fortran 90 standard. -GNU Fortran supports ANSI FORTRAN 77 with the following caveats: +@menu +* No Passing External Assumed-length:: CHAR*(*) CFUNC restriction. +* No Passing Dummy Assumed-length:: CHAR*(*) CFUNC restriction. +* No Pathological Implied-DO:: No @samp{((@dots{}, I=@dots{}), I=@dots{})}. +* No Useless Implied-DO:: No @samp{(A, I=1, 1)}. +@end menu -@itemize @bullet -@item -No passing of an external procedure as an actual argument if the procedure's -type is declared @samp{CHARACTER*(*)}. For example: +@node No Passing External Assumed-length +@subsection No Passing External Assumed-length + +@code{g77} disallows passing of an external procedure +as an actual argument if the procedure's +type is declared @code{CHARACTER*(*)}. For example: @example CHARACTER*(*) CFUNC @@ -3333,12 +3726,12 @@ END @noindent It isn't clear whether the standard considers this conforming. -Note that it is unlikely that any production Fortran code -tries to use this unsupported construct. +@node No Passing Dummy Assumed-length +@subsection No Passing Dummy Assumed-length -@item -No passing of a dummy procedure as an actual argument if the procedure's -type is declared @samp{CHARACTER*(*)}. +@code{g77} disallows passing of a dummy procedure +as an actual argument if the procedure's +type is declared @code{CHARACTER*(*)}. @example SUBROUTINE BAR(CFUNC) @@ -3351,17 +3744,16 @@ END @noindent It isn't clear whether the standard considers this conforming. -Note that it is unlikely that any production Fortran code -tries to use this unsupported construct. +@node No Pathological Implied-DO +@subsection No Pathological Implied-DO -@item -The @samp{DO} variable for an implied-@samp{DO} construct in a -@samp{DATA} statement may not be used as the @samp{DO} variable -for an outer implied-@samp{DO} construct. For example, this +The @code{DO} variable for an implied-@code{DO} construct in a +@code{DATA} statement may not be used as the @code{DO} variable +for an outer implied-@code{DO} construct. For example, this fragment is disallowed by @code{g77}: @smallexample -DATA ((A(I, I), I= 1, 10), I= 1, 10)/@dots{}/ +DATA ((A(I, I), I= 1, 10), I= 1, 10) /@dots{}/ @end smallexample @noindent @@ -3371,14 +3763,16 @@ capabilities and would have a variety of possible meanings. Note that it is @emph{very} unlikely that any production Fortran code tries to use this unsupported construct. -@item -An array element initializer in an implied-@samp{DO} construct in a -@samp{DATA} statement must contain at least one reference to the @samp{DO} -variables of each outer implied-@samp{DO} construct. For example, +@node No Useless Implied-DO +@subsection No Useless Implied-DO + +An array element initializer in an implied-@code{DO} construct in a +@code{DATA} statement must contain at least one reference to the @code{DO} +variables of each outer implied-@code{DO} construct. For example, this fragment is disallowed by @code{g77}: @example -DATA (A, I= 1, 1)/1./ +DATA (A, I= 1, 1) /1./ @end example @noindent @@ -3389,283 +3783,2098 @@ where this requirement is not met. Note that it is @emph{very} unlikely that any production Fortran code tries to use this unsupported construct. + +@node Conformance +@section Conformance + +(The following information augments or overrides the information in +Section 1.4 of ANSI X3.9-1978 FORTRAN 77 in specifying the GNU Fortran +language. +Chapter 1 of that document otherwise serves as the basis +for the relevant aspects of GNU Fortran.) + +The definition of the GNU Fortran language is akin to that of +the ANSI FORTRAN 77 language in that it does not generally require +conforming implementations to diagnose cases where programs do +not conform to the language. + +However, @code{g77} as a compiler is being developed in a way that +is intended to enable it to diagnose such cases in an easy-to-understand +manner. + +A program that conforms to the GNU Fortran language should, when +compiled, linked, and executed using a properly installed @code{g77} +system, perform as described by the GNU Fortran language definition. +Reasons for different behavior include, among others: + +@itemize @bullet +@item +Use of resources (memory---heap, stack, and so on; disk space; CPU +time; etc.) exceeds those of the system. + +@item +Range and/or precision of calculations required by the program +exceeds that of the system. + +@item +Excessive reliance on behaviors that are system-dependent +(non-portable Fortran code). + +@item +Bugs in the program. + +@item +Bug in @code{g77}. + +@item +Bugs in the system. @end itemize -In summary, the only ANSI FORTRAN 77 features @code{g77} doesn't -support are those that are probably rarely used in actual code, -some of which are explicitly disallowed by the Fortran 90 standard. +Despite these ``loopholes'', the availability of a clear specification +of the language of programs submitted to @code{g77}, as this document +is intended to provide, is considered an important aspect of providing +a robust, clean, predictable Fortran implementation. + +The definition of the GNU Fortran language, while having no special +legal status, can therefore be viewed as a sort of contract, or agreement. +This agreement says, in essence, ``if you write a program in this language, +and run it in an environment (such as a @code{g77} system) that supports +this language, the program should behave in a largely predictable way''. -@node Extensions -@section GNU Fortran Extensions -@cindex extensions -@cindex language extensions +@node Notation Used +@section Notation Used in This Chapter -GNU Fortran supports ANSI FORTRAN 77 plus: +(The following information augments or overrides the information in +Section 1.5 of ANSI X3.9-1978 FORTRAN 77 in specifying the GNU Fortran +language. +Chapter 1 of that document otherwise serves as the basis +for the relevant aspects of GNU Fortran.) + +In this chapter, ``must'' denotes a requirement, ``may'' denotes permission, +and ``must not'' and ``may not'' denote prohibition. +Terms such as ``might'', ``should'', and ``can'' generally add little or +nothing in the way of weight to the GNU Fortran language itself, +but are used to explain or illustrate the language. + +For example: + +@display +``The @code{FROBNITZ} statement must precede all executable +statements in a program unit, and may not specify any dummy +arguments. It may specify local or common variables and arrays. +Its use should be limited to portions of the program designed to +be non-portable and system-specific, because it might cause the +containing program unit to behave quite differently on different +systems.'' +@end display + +Insofar as the GNU Fortran language is specified, +the requirements and permissions denoted by the above sample statement +are limited to the placement of the statement and the kinds of +things it may specify. +The rest of the statement---the content regarding non-portable portions +of the program and the differing behavior of program units containing +the @code{FROBNITZ} statement---does not pertain the GNU Fortran +language itself. +That content offers advice and warnings about the @code{FROBNITZ} +statement. + +@emph{Remember:} The GNU Fortran language definition specifies +both what constitutes a valid GNU Fortran program and how, +given such a program, a valid GNU Fortran implementation is +to interpret that program. + +It is @emph{not} incumbent upon a valid GNU Fortran implementation +to behave in any particular way, any consistent way, or any +predictable way when it is asked to interpret input that is +@emph{not} a valid GNU Fortran program. + +Such input is said to have @dfn{undefined} behavior when +interpreted by a valid GNU Fortran implementation, though +an implementation may choose to specify behaviors for some +cases of inputs that are not valid GNU Fortran programs. + +Other notation used herein is that of the GNU texinfo format, +which is used to generate printed hardcopy, on-line hypertext +(Info), and on-line HTML versions, all from a single source +document. +This notation is used as follows: @itemize @bullet -@cindex LOC() intrinsic -@cindex intrinsics, LOC() @item -@samp{LOC()}, if @samp{-funix-intrinsics-enable} is in force. +Keywords defined by the GNU Fortran language are shown +in uppercase, as in: @code{COMMON}, @code{INTEGER}, and +@code{BLOCK DATA}. + +Note that, in practice, many Fortran programs are written +in lowercase---uppercase is used in this manual as a +means to readily distinguish keywords and sample Fortran-related +text from the prose in this document. @item -@cindex %LOC() intrinsic -@cindex intrinsics, %LOC() -@cindex %VAL() intrinsic -@cindex intrinsics, %VAL() -@cindex %REF() intrinsic -@cindex intrinsics, %REF() -@cindex %DESCR() intrinsic -@cindex intrinsics, %DESCR() -@samp{%LOC}, @samp{%VAL}, @samp{%REF}, and @samp{%DESCR}---where -@samp{%DESCR} currently means the same thing as passing the argument -as if it were a @samp{CHARACTER} variable (with the phantom -length argument appended to the argument list). +Portions of actual sample program, input, or output text +look like this: @samp{Actual program text}. + +Generally, uppercase is used for all Fortran-specific and +Fortran-related text, though this does not always include +literal text within Fortran code. + +For example: @samp{PRINT *, 'My name is Bob'}. @item -MIL-STD 1753 features (@samp{IAND}, @samp{IOR}, @samp{MVBITS}, -@samp{DO WHILE}, @samp{END DO}, and so on). +A metasyntactic variable---that is, a name used in this document +to serve as a placeholder for whatever text is used by the +user or programmer--appears as shown in the following example: + +``The @code{INTEGER @var{ivar}} statement specifies that +@var{ivar} is a variable or array of type @code{INTEGER}.'' + +In the above example, any valid text may be substituted for +the metasyntactic variable @var{ivar} to make the statement +apply to a specific instance, as long as the same text is +substituted for @emph{both} occurrences of @var{ivar}. -@cindex NAMELIST statement -@cindex statements, NAMELIST @item -@samp{NAMELIST}. +Ellipses (``@dots{}'') are used to indicate further text that +is either unimportant or expanded upon further, elsewhere. + +@item +Names of data types are in the style of Fortran 90, in most +cases. + +@xref{Kind Notation}, for information on the relationship +between Fortran 90 nomenclature (such as @code{INTEGER(KIND=1)}) +and the more traditional, less portably concise nomenclature +(such as @code{INTEGER*4}). +@end itemize + +@node Terms and Concepts +@section Fortran Terms and Concepts + +(The following information augments or overrides the information in +Chapter 2 of ANSI X3.9-1978 FORTRAN 77 in specifying the GNU Fortran +language. +Chapter 2 of that document otherwise serves as the basis +for the relevant aspects of GNU Fortran.) + +@menu +* Syntactic Items:: +* Statements Comments Lines:: +* Scope of Names and Labels:: +@end menu + +@node Syntactic Items +@subsection Syntactic Items + +(Corresponds to Section 2.2 of ANSI X3.9-1978 FORTRAN 77.) + +In GNU Fortran, a symbolic name is at least one character long, +and has no arbitrary upper limit on length. +However, names of entities requiring external linkage (such as +external functions, external subroutines, and @code{COMMON} areas) +might be restricted to some arbitrary length by the system. +Such a restriction is no more constrained than that of one +through six characters. + +Underscores (@samp{_}) are accepted in symbol names after the first +character (which must be a letter). + +@node Statements Comments Lines +@subsection Statements, Comments, and Lines + +(Corresponds to Section 2.3 of ANSI X3.9-1978 FORTRAN 77.) + +@cindex comments, trailing +@cindex trailing comments +Use of an exclamation point (@samp{!}) to begin a +trailing comment (a comment that extends to the end of the same +source line) is permitted under the following conditions: + +@itemize @bullet +@item +The exclamation point does not appear in column 6. +Otherwise, it is treated as an indicator of a continuation +line. + +@item +The exclamation point appears outside a character or hollerith +constant. +Otherwise, the exclamation point is considered part of the +constant. + +@item +The exclamation point appears to the left of any other possible +trailing comment. +That is, a trailing comment may contain exclamation points +in their commentary text. +@end itemize +@cindex semicolons +@cindex statements, separated by semicolon +Use of a semicolon (@samp{;}) as a statement separator +is permitted under the following conditions: + +@itemize @bullet @item -Most @code{f2c} intrinsics (@samp{AND}, @samp{OR}, @samp{LSHIFT}, -@samp{RSHIFT}, and so on). +The semicolon appears outside a character or hollerith +constant. +Otherwise, the semicolon is considered part of the +constant. @item -@samp{DOUBLE COMPLEX} and related intrinsics (standard and @code{f2c} -varieties). +The semicolon appears to the left of a trailing comment. +Otherwise, the semicolon is considered part of that +comment. @item -Various Fortran 90 features, such as @samp{CYCLE}, @samp{EXIT}, -@samp{SELECT CASE} (except for @samp{CHARACTER} types). +Neither a logical @code{IF} statement nor a non-construct +@code{WHERE} statement (a Fortran 90 feature) may be +followed (in the same, possibly continued, line) by +a semicolon used as a statement separator. + +This restriction avoids the confusion +that can result when reading a line such as: + +@example +IF (VALIDP) CALL FOO; CALL BAR +@end example + +@noindent +Some readers might think the @samp{CALL BAR} is executed +only if @samp{VALIDP} is @code{.TRUE.}, while others might +assume its execution is unconditional. + +(At present, @code{g77} does not diagnose code that +violates this restriction.) +@end itemize + +@node Scope of Names and Labels +@subsection Scope of Symbolic Names and Statement Labels +@cindex scope +(Corresponds to Section 2.9 of ANSI X3.9-1978 FORTRAN 77.) + +Included in the list of entities that have a scope of a +program unit are construct names (a Fortran 90 feature). +@xref{Construct Names}, for more information. + +@node Characters Lines Sequence +@section Characters, Lines, and Execution Sequence + +(The following information augments or overrides the information in +Chapter 3 of ANSI X3.9-1978 FORTRAN 77 in specifying the GNU Fortran +language. +Chapter 3 of that document otherwise serves as the basis +for the relevant aspects of GNU Fortran.) + +@menu +* Character Set:: +* Lines:: +* Continuation Line:: +* Statements:: +* Statement Labels:: +* Order:: +* INCLUDE:: +@end menu + +@node Character Set +@subsection GNU Fortran Character Set +@cindex characters + +(Corresponds to Section 3.1 of ANSI X3.9-1978 FORTRAN 77.) + +Letters include uppercase letters (the twenty-six characters +of the English alphabet) and lowercase letters (their lowercase +equivalent). +Generally, lowercase letters may be used in place of uppercase +letters, though in character and hollerith constants, they +are distinct. + +Special characters include: + +@itemize @bullet @item -Various DEC VAX/VMS FORTRAN v4.0 features (loosely called VXT extensions). +Semicolon (@samp{;}) @item -Various @code{f2c} features. +Exclamation point (@samp{!}) @item -Source files that are uppercase-only (enforced), lowercase-only -(enforced), caseless, and various other combinations as chosen via -command-line options. +Double quote (@samp{"}) @item -Arbitrary (limited only by available memory) number of continuation lines. +Backslash (@samp{\}) @item -Use of @samp{&} in column 1 to indicate a continuation line -(as supported by @code{f2c}). +Question mark (@samp{?}) @item -Dollar signs (@samp{$}) in identifiers (other than as the first character) -when the @samp{-fdollar-ok} option is specified. +Hash mark (@samp{#}) + +@item +Ampersand (@samp{&}) + +@item +Percent sign (@samp{%}) + +@item +Underscore (@samp{_}) + +@item +Open angle (@samp{<}) + +@item +Close angle (@samp{>}) + +@item +The FORTRAN 77 special characters (@key{SPC}, @samp{=}, +@samp{+}, @samp{-}, @samp{*}, @samp{/}, @samp{(}, +@samp{)}, @samp{,}, @samp{.}, @samp{$}, @samp{'}, +and @samp{:}) @end itemize -When @samp{-ff90} is specified, the language dialect changes as follows: +@cindex blanks (spaces) +Note that this document refers to @key{SPC} as @dfn{space}, +while X3.9-1978 FORTRAN 77 refers to it as @dfn{blank}. + +@node Lines +@subsection Lines +@cindex lines +@cindex source file format +@cindex source form +@cindex files, source +@cindex source code +@cindex code, source +@cindex fixed form +@cindex free form + +(Corresponds to Section 3.2 of ANSI X3.9-1978 FORTRAN 77.) + +The way a Fortran compiler views source files depends entirely on the +implementation choices made for the compiler, since those choices +are explicitly left to the implementation by the published Fortran +standards. + +The GNU Fortran language mandates a view applicable to UNIX-like +text files---files that are made up of an arbitrary number of lines, +each with an arbitrary number of characters (sometimes called stream-based +files). + +This view does not apply to types of files that are specified as +having a particular number of characters on every single line (sometimes +referred to as record-based files). + +Because a ``line in a program unit is a sequence of 72 characters'', +to quote X3.9-1978, the GNU Fortran language specifies that a +stream-based text file is translated to GNU Fortran lines as follows: @itemize @bullet @item -The type of @samp{REAL(Z)}, where @samp{Z} is type -@samp{DOUBLE COMPLEX}, is @samp{DOUBLE PRECISION} -instead of @samp{REAL}. +A newline in the file is the character that represents the end of +a line of text to the underlying system. +For example, on ASCII-based systems, a newline is the @key{NL} +character, which has ASCII value 12 (decimal). + +@item +Each newline in the file serves to end the line of text that precedes +it (and that does not contain a newline). + +@item +The end-of-file marker (@code{EOF}) also serves to end the line +of text that precedes it (and that does not contain a newline). @item -Zero-length @samp{CHARACTER} entities are accepted, -even when @samp{-fpedantic} is specified. +@cindex blanks (spaces) +Any line of text that is shorter than 72 characters is padded to that length +with spaces (called ``blanks'' in the standard). @item -Zero-size array dimensions (as in @samp{INTEGER I(10,20,4:2)}) -are accepted, -although these are not supported by @samp{libf2c}, so diagnostics -are nevertheless produced for @code{g77}. +Any line of text that is longer than 72 characters is truncated to that +length, but the truncated remainder must consist entirely of spaces. + +@item +Characters other than newline and the GNU Fortran character set +are invalid. +@end itemize + +For the purposes of the remainder of this description of the GNU +Fortran language, the translation described above has already +taken place, unless otherwise specified. + +The result of the above translation is that the source file appears, +in terms of the remainder of this description of the GNU Fortran language, +as if it had an arbitrary +number of 72-character lines, each character being among the GNU Fortran +character set. + +For example, if the source file itself has two newlines in a row, +the second newline becomes, after the above translation, a single +line containing 72 spaces. + +@node Continuation Line +@subsection Continuation Line +@cindex continuation lines, number of +@cindex lines, continuation +@cindex number of continuation lines +@cindex limits on continuation lines + +(Corresponds to Section 3.2.3 of ANSI X3.9-1978 FORTRAN 77.) + +A continuation line is any line that both + +@itemize @bullet +@item +Contains a continuation character, and + +@item +Contains only spaces in columns 1 through 5 +@end itemize + +A continuation character is any character of the GNU Fortran character set +other than space (@key{SPC}) or zero (@samp{0}) +in column 6, or a digit (@samp{0} through @samp{9}) in column +7 through 72 of a line that has only spaces to the left of that +digit. + +The continuation character is ignored as far as the content of +the statement is concerned. + +The GNU Fortran language places no limit on the number of +continuation lines in a statement. +In practice, the limit depends on a variety of factors, such as +available memory, statement content, and so on, but no +GNU Fortran system may impose an arbitrary limit. + +@node Statements +@subsection Statements + +(Corresponds to Section 3.3 of ANSI X3.9-1978 FORTRAN 77.) + +Statements may be written using an arbitrary number of continuation +lines. + +Statements may be separated using the semicolon (@samp{;}), except +that the logical @code{IF} and non-construct @code{WHERE} statements +may not be separated from subsequent statements using only a semicolon +as statement separator. + +The @code{END PROGRAM}, @code{END SUBROUTINE}, @code{END FUNCTION}, +and @code{END BLOCK DATA} statements are alternatives to the @code{END} +statement. +These alternatives may be written as normal statements---they are not +subject to the restrictions of the @code{END} statement. + +However, no statement other than @code{END} may have an initial line +that appears to be an @code{END} statement---even @code{END PROGRAM}, +for example, must not be written as: +@example + END + &PROGRAM +@end example + +@node Statement Labels +@subsection Statement Labels + +(Corresponds to Section 3.4 of ANSI X3.9-1978 FORTRAN 77.) + +A statement separated from its predecessor via a semicolon may be +labeled as follows: + +@itemize @bullet @item -@samp{DOUBLE COMPLEX} (explicit or implicit) is accepted, -even when @samp{-fpedantic} is specified. +The semicolon is followed by the label for the statement, +which in turn follows the label. @item -Substrings of constants (as in @samp{'hello'(3:5)}) are -accepted, even when @samp{-fpedantic} is specified. +The label must be no more than five digits in length. @item -@samp{DATA} statements are allowed to precede executable statements, -even when @samp{-fpedantic} specified. +The first digit of the label for the statement is not +the first non-space character on a line. +Otherwise, that character is treated as a continuation +character. +@end itemize + +A statement may have only one label defined for it. + +@node Order +@subsection Order of Statements and Lines -Note that this does not allow all possible means of specifying -further attributes via specification statements for a variable -after it has been given an initial value via @samp{DATA} or a -type-declaration statement. +(Corresponds to Section 3.5 of ANSI X3.9-1978 FORTRAN 77.) + +Generally, @code{DATA} statements may precede executable statements. +However, specification statements pertaining to any entities +initialized by a @code{DATA} statement must precede that @code{DATA} +statement. For example, after @samp{DATA I/1/}, @samp{INTEGER I} is not permitted, but @samp{INTEGER J} is permitted. +The last line of a program unit may be an @code{END} statement, +or may be: + +@itemize @bullet @item -@cindex semicolons -@cindex statements, separated by semicolon -Use of a semicolon (@samp{;}) as a statement separator -is accepted, even when @samp{-fpedantic} specified -(so @samp{CALL FOO; CALL BAR} works). +An @code{END PROGRAM} statement, if the program unit is a main program. + +@item +An @code{END SUBROUTINE} statement, if the program unit is a subroutine. + +@item +An @code{END FUNCTION} statement, if the program unit is a function. @item -Underscores (@samp{_}) are accepted in symbol names (except as the -first character, since Fortran 90 provides a different interpretation -for certain cases where that would occur---though @code{g77} does -not yet support that interpretation). +An @code{END BLOCK DATA} statement, if the program unit is a block data. @end itemize +@node INCLUDE +@subsection Including Source Text +@cindex INCLUDE + +Additional source text may be included in the processing of +the source file via the @code{INCLUDE} directive: + +@example +INCLUDE @var{filename} +@end example + +@noindent +The source text to be included is identified by @var{filename}, +which is a literal GNU Fortran character constant. +The meaning and interpretation of @var{filename} depends on the +implementation, but typically is a filename. + +(@code{g77} treats it as a filename that it searches for +in the current directory and/or directories specified +via the @samp{-I} command-line option.) + +The effect of the @code{INCLUDE} directive is as if the +included text directly replaced the directive in the source +file prior to interpretation of the program. +Included text may itself use @code{INCLUDE}. +The depth of nested @code{INCLUDE} references depends on +the implementation, but typically is a positive integer. + +This virtual replacement treats the statements and @code{INCLUDE} +directives in the included text as syntactically distinct from +those in the including text. + +Therefore, the first non-comment line of the included text +must not be a continuation line. +The included text must therefore have, after the non-comment +lines, either an initial line (statement), an @code{INCLUDE} +directive, or nothing (the end of the included text). + +Similarly, the including text may end the @code{INCLUDE} +directive with a semicolon or the end of the line, but it +cannot follow an @code{INCLUDE} directive at the end of its +line with a continuation line. +Thus, the last statement in an included text may not be +continued. + +Any statements between two @code{INCLUDE} directives on the +same line are treated as if they appeared in between the +respective included texts. +For example: + +@smallexample +INCLUDE 'A'; PRINT *, 'B'; INCLUDE 'C'; END PROGRAM +@end smallexample + +@noindent +If the text included by @samp{INCLUDE 'A'} constitutes +a @samp{PRINT *, 'A'} statement and the text included by +@samp{INCLUDE 'C'} constitutes a @samp{PRINT *, 'C'} statement, +then the output of the above sample program would be + +@example +A +B +C +@end example + +@noindent +(with suitable allowances for how an implementation defines +its handling of output). + +Included text must not include itself directly or indirectly, +regardless of whether the @var{filename} used to reference +the text is the same. + +Note that @code{INCLUDE} is @emph{not} a statement. +As such, it is neither a non-executable or executable +statement. +However, if the text it includes constitutes one or more +executable statements, then the placement of @code{INCLUDE} +is subject to effectively the same restrictions as those +on executable statements. + +An @code{INCLUDE} directive may be continued across multiple +lines as if it were a statement. +This permits long names to be used for @var{filename}. + +@node Data Types and Constants +@section Data Types and Constants + +(The following information augments or overrides the information in +Chapter 4 of ANSI X3.9-1978 FORTRAN 77 in specifying the GNU Fortran +language. +Chapter 4 of that document otherwise serves as the basis +for the relevant aspects of GNU Fortran.) + +To more concisely express the appropriate types for +entities, this document uses the more concise +Fortran 90 nomenclature such as @code{INTEGER(KIND=1)} +instead of the more traditional, but less portably concise, +byte-size-based nomenclature such as @code{INTEGER*4}, +wherever reasonable. + +When referring to generic types---in contexts where the +specific precision and range of a type are not important---this +document uses the generic type names @code{INTEGER}, @code{LOGICAL}, +@code{REAL}, @code{COMPLEX}, and @code{CHARACTER}. + +In some cases, the context requires specification of a +particular type. +This document uses the @samp{KIND=} notation to accomplish +this throughout, sometimes supplying the more traditional +notation for clarification, though the traditional notation +might not work the same way on all GNU Fortran implementations. + +Use of @samp{KIND=} makes this document more concise because +@code{g77} is able to define values for @samp{KIND=} that +have the same meanings on all systems, due to the way the +Fortran 90 standard specifies these values are to be used. + +(In particular, that standard permits an implementation to +arbitrarily assign nonnegative values. +There are four distinct sets of assignments: one to the @code{CHARACTER} +type; one to the @code{INTEGER} type; one to the @code{LOGICAL} type; +and the fourth to both the @code{REAL} and @code{COMPLEX} types. +Implementations are free to assign these values in any order, +leave gaps in the ordering of assignments, and assign more than +one value to a representation.) + +This makes @samp{KIND=} values superior to the values used +in non-standard statements such as @samp{INTEGER*4}, because +the meanings of the values in those statements vary from machine +to machine, compiler to compiler, even operating system to +operating system. + +However, use of @samp{KIND=} is @emph{not} generally recommended +when writing portable code (unless, for example, the code is +going to be compiled only via @code{g77}, which is a widely +ported compiler). +GNU Fortran does not yet have adequate language constructs to +permit use of @samp{KIND=} in a fashion that would make the +code portable to Fortran 90 implementations; and, this construct +is known to @emph{not} be accepted by many popular FORTRAN 77 +implementations, so it cannot be used in code that is to be ported +to those. + +The distinction here is that this document is able to use +specific values for @samp{KIND=} to concisely document the +types of various operations and operands. + +A Fortran program should use the FORTRAN 77 designations for the +appropriate GNU Fortran types---such as @code{INTEGER} for +@code{INTEGER(KIND=1)}, @code{REAL} for @code{REAL(KIND=1)}, +and @code{DOUBLE COMPLEX} for @code{COMPLEX(KIND=2)}---and, +where no such designations exist, make use of appropriate +techniques (preprocessor macros, parameters, and so on) +to specify the types in a fashion that may be easily adjusted +to suit each particular implementation to which the program +is ported. +(These types generally won't need to be adjusted for ports of +@code{g77}.) + +Further details regarding GNU Fortran data types and constants +are provided below. + +@menu +* Types:: +* Constants:: +* Integer Type:: +* Character Type:: +@end menu + @node Types -@section Types -@cindex types, of data -@cindex data types +@subsection Data Types -Fortran implementations have a fair amount of freedom given them by the -standard as far as how much storage space is used and how much precision -is offered by the various types such as @samp{LOGICAL}, @samp{INTEGER}, -@samp{REAL}, @samp{DOUBLE PRECISION}, @samp{COMPLEX}, and @samp{CHARACTER}. -Further, many compilers offer so-called @samp{*@var{n}} notation, but -the interpretation of @var{n} varies across compilers and target architectures. +(Corresponds to Section 4.1 of ANSI X3.9-1978 FORTRAN 77.) -The standard requires that @samp{LOGICAL}, @samp{INTEGER}, and @samp{REAL} -occupy the same amount of storage space, and that @samp{COMPLEX} and -@samp{DOUBLE PRECISION} take twice as much storage space as @samp{REAL}. -Further, it requires that @samp{COMPLEX} -entities be ordered such that when a @samp{COMPLEX} variable is -storage-associated (such as via @samp{EQUIVALENCE}) -with a two-element @samp{REAL} array named @samp{R}, @samp{R(1)} -corresponds to the real element and @samp{R(2)} to the imaginary -element of the @samp{COMPLEX} variable. -No particular requirements as to precision of any of these are placed on -the implementation, nor is the relationship of storage sizes of these -types to the @samp{CHARACTER} type specified by the standard. +GNU Fortran supports these types: -@code{g77} follows the above requirements, warning when compiling -a program requires placement of items in memory that contradict the -requirements of the target architecture. -(For example, a program can require placement of a @samp{DOUBLE PRECISION} -on a boundary that is not an even multiple of its size, but still an -even multiple of the size of a @samp{REAL} variable. -On some target architectures, using the canonical -mapping of Fortran types to underlying architectural types, such -placement is prohibited by the machine definition or -the Application Binary Interface (ABI) in force for -the configuration defined for building @code{gcc} and @code{g77}. -@code{g77} warns about such -situations when it encounters them.) +@enumerate +@item +Integer (generic type @code{INTEGER}) -@code{g77} follows consistent rules for configuring the mapping between Fortran -types, including the @samp{*@var{n}} notation, and the underlying architectural -types as accessed by a similarly-configured applicable version of the -@code{gcc} compiler. -These rules offer a widely portable, consistent Fortran/C -environment, although they might well conflict with the expectations of -users of Fortran compilers designed and written for particular -architectures. +@item +Real (generic type @code{REAL}) -These rules are based on the configuration that is in force for the -version of @code{gcc} built in the same release as @code{g77} (and -which was therefore used to build both the @code{g77} compiler -components and the @code{libf2c} run-time library): +@item +Double precision -@table @code -@cindex REAL type -@cindex types, REAL -@item REAL -Same as @samp{float} type. +@item +Complex (generic type @code{COMPLEX}) -@cindex DOUBLE PRECISION type -@cindex types, DOUBLE PRECISION -@item DOUBLE PRECISION -Same as whatever floating-point type that is twice the size -of a @samp{float}---usually, this is a @samp{double}. +@item +Logical (generic type @code{LOGICAL}) -@cindex INTEGER type -@cindex types, INTEGER -@item INTEGER -Same as an integral type that is occupies the same amount -of memory storage @samp{float}---usually, this is either -an @samp{int} or a @samp{long int}. - -@cindex LOGICAL type -@cindex types, LOGICAL -@item LOGICAL -Same @code{gcc} type as @samp{INTEGER}. - -@cindex COMPLEX type -@cindex types, COMPLEX -@item COMPLEX -Two @samp{REAL} scalars (one for the real part followed by -one for the imaginary part). +@item +Character (generic type @code{CHARACTER}) -@cindex DOUBLE COMPLEX type -@cindex types, DOUBLE COMPLEX -@item DOUBLE COMPLEX -Two @samp{DOUBLE PRECISION} scalars. +@item +Double Complex +@end enumerate + +(The types numbered 1 through 6 above are standard FORTRAN 77 types.) + +The generic types shown above are referred to in this document +using only their generic type names. +Such references usually indicate that any specific type (kind) +of that generic type is valid. + +For example, a context described in this document as accepting +the @code{COMPLEX} type also is likely to accept the +@code{DOUBLE COMPLEX} type. + +The GNU Fortran language supports three ways to specify +a specific kind of a generic type. + +@menu +* Double Notation:: As in @code{DOUBLE COMPLEX}. +* Star Notation:: As in @code{INTEGER*4}. +* Kind Notation:: As in @code{INTEGER(KIND=1)}. +@end menu + +@node Double Notation +@subsubsection Double Notation + +The GNU Fortran language supports two uses of the keyword +@code{DOUBLE} to specify a specific kind of type: + +@itemize @bullet +@item +@code{DOUBLE PRECISION}, equivalent to @code{REAL(KIND=2)} + +@item +@code{DOUBLE COMPLEX}, equivalent to @code{COMPLEX(KIND=2)} +@end itemize + +Use one of the above forms where a type name is valid. + +While use of this notation is popular, it doesn't scale +well in a language or dialect rich in intrinsic types, +as is the case for the GNU Fortran language (especially +planned future versions of it). + +After all, one rarely sees type names such as @samp{DOUBLE INTEGER}, +@samp{QUADRUPLE REAL}, or @samp{QUARTER INTEGER}. +Instead, @code{INTEGER*8}, @code{REAL*16}, and @code{INTEGER*1} +often are substituted for these, respectively, even though they +do not always have the same meanings on all systems. +(And, the fact that @samp{DOUBLE REAL} does not exist as such +is an inconsistency.) +Therefore, this document uses ``double notation'' only on occasion +for the benefit of those readers who are accustomed to it. + +@node Star Notation +@subsubsection Star Notation @cindex *@var{n} notation -@item @var{numeric-type}*@var{n} -(Where @var{numeric-type} is any type other than @samp{CHARACTER}.) -Same as whatever @code{gcc} type occupies @var{n} times the storage -space of a @code{gcc} @samp{char} item. +The following notation specifies the storage size for a type: + +@example +@var{generic-type}*@var{n} +@end example + +@noindent +@var{generic-type} must be a generic type---one of +@code{INTEGER}, @code{REAL}, @code{COMPLEX}, @code{LOGICAL}, +or @code{CHARACTER}. +@var{n} must be one or more digits comprising a decimal +integer number greater than zero. + +Use the above form where a type name is valid. + +The @samp{*@var{n}} notation specifies that the amount of storage +occupied by variables and array elements of that type is @var{n} +times the storage occupied by a @code{CHARACTER*1} variable. + +This notation might indicate a different degree of precision and/or +range for such variables and array elements, and the functions that +return values of types using this notation. +It does not limit the precision or range of values of that type +in any particular way---use explicit code to do that. + +Further, the GNU Fortran language requires no particular values +for @var{n} to be supported by an implementation via the @samp{*@var{n}} +notation. +@code{g77} supports @code{INTEGER*1} (as @code{INTEGER(KIND=3)}) +on all systems, for example, +but not all implementations are required to do so, and @code{g77} +is known to not support @code{REAL*1} on most (or all) systems. + +As a result, except for @var{generic-type} of @code{CHARACTER}, +uses of this notation should be limited to isolated +portions of a program that are intended to handle system-specific +tasks and are expected to be non-portable. + +(Standard FORTRAN 77 supports the @samp{*@var{n}} notation for +only @code{CHARACTER}, where it signifies not only the amount +of storage occupied, but the number of characters in entities +of that type. +However, almost all Fortran compilers have supported this +notation for generic types, though with a variety of meanings +for @var{n}.) + +Specifications of types using the @samp{*@var{n}} notation +always are interpreted as specifications of the appropriate +types described in this document using the @samp{KIND=@var{n}} +notation, described below. + +While use of this notation is popular, it doesn't serve well +in the context of a widely portable dialect of Fortran, such as +the GNU Fortran language. + +For example, even on one particular machine, two or more popular +Fortran compilers might well disagree on the size of a type +declared @code{INTEGER*2} or @code{REAL*16}. +Certainly there +is known to be disagreement over such things among Fortran +compilers on @emph{different} systems. + +Further, this notation offers no elegant way to specify sizes +that are not even multiples of the ``byte size'' typically +designated by @code{INTEGER*1}. +Use of ``absurd'' values (such as @code{INTEGER*1000}) would +certainly be possible, but would perhaps be stretching the original +intent of this notation beyond the breaking point in terms +of widespread readability of documentation and code making use +of it. + +Therefore, this document uses ``star notation'' only on occasion +for the benefit of those readers who are accustomed to it. + +@node Kind Notation +@subsubsection Kind Notation @cindex KIND= notation -@item @var{numeric-type}(KIND=@var{n}) -@var{n}=1 corresponds to @samp{REAL}, @samp{INTEGER}, @samp{LOGICAL}, -@samp{COMPLEX}. -@var{n}=2 corresponds to @samp{DOUBLE PRECISION}, @samp{DOUBLE COMPLEX}, -and, for integral types, @samp{char} (usually @samp{INTEGER*1} -and @samp{LOGICAL*1}). -@var{n}=3 corresponds to @samp{short} for integral types -(usually @samp{INTEGER*2} and @samp{LOGICAL*2}). -@var{n}=4 corresponds to @samp{long long} for integral types -(this usually means @samp{INTEGER*8} and @samp{LOGICAL*8}). - -Note that these are proposed correspondences and might change -in future versions of @code{g77}---avoid writing code depending -on them. + +The following notation specifies the kind-type selector of a type: + +@example +@var{generic-type}(KIND=@var{n}) +@end example + +@noindent +Use the above form where a type name is valid. + +@var{generic-type} must be a generic type---one of +@code{INTEGER}, @code{REAL}, @code{COMPLEX}, @code{LOGICAL}, +or @code{CHARACTER}. +@var{n} must be an integer initialization expression that +is a positive, nonzero value. + +Programmers are discouraged from writing these values directly +into their code. +Future versions of the GNU Fortran language will offer +facilities that will make the writing of code portable +to @code{g77} @emph{and} Fortran 90 implementations simpler. + +However, writing code that ports to existing FORTRAN 77 +implementations depends on avoiding the @samp{KIND=} construct. + +The @samp{KIND=} construct is thus useful in the context +of GNU Fortran for two reasons: + +@itemize @bullet +@item +It provides a means to specify a type in a fashion that +is portable across all GNU Fortran implementations (though +not other FORTRAN 77 and Fortran 90 implementations). + +@item +It provides a sort of Rosetta stone for this document to use +to concisely describe the types of various operations and +operands. +@end itemize + +The values of @var{n} in the GNU Fortran language are +assigned using a scheme that: + +@itemize @bullet +@item +Attempts to maximize the ability of readers +of this document to quickly familiarize themselves +with assignments for popular types + +@item +Provides a unique value for each specific desired +meaning + +@item +Provides a means to automatically assign new values so +they have a ``natural'' relationship to existing values, +if appropriate, or, if no such relationship exists, will +not interfere with future values assigned on the basis +of such relationships + +@item +Avoids using values that are similar to values used +in the existing, popular @samp{*@var{n}} notation, +to prevent readers from expecting that these implied +correspondences work on all GNU Fortran implementations +@end itemize + +The assignment system accomplishes this by assigning +to each ``fundamental meaning'' of a specific type a +unique prime number. +Combinations of fundamental meanings---for example, a type +that is two times the size of some other type---are assigned +values of @var{n} that are the products of the values for +those fundamental meanings. + +A prime value of @var{n} is never given more than one fundamental +meaning, to avoid situations where some code or system +cannot reasonably provide those meanings in the form of a +single type. + +The values of @var{n} assigned so far are: + +@table @code +@item KIND=0 +This is valid only as @code{INTEGER(KIND=0)} and +denotes the @code{INTEGER} type that has the smallest +storage size that holds a pointer on the system. + +A pointer representable by this type is capable of uniquely +addressing a @code{CHARACTER*1} variable, array, array element, +or substring. + +(Typically this is equivalent to @code{INTEGER*4} or, +on 64-bit systems, @code{INTEGER*8}. +In a compatible C implementation, it typically would +be the same size and semantics of the C type @code{void *}.) + +@item KIND=1 +This corresponds to the default types for +@code{REAL}, @code{INTEGER}, @code{LOGICAL}, @code{COMPLEX}, +and @code{CHARACTER}, as appropriate. + +These are the ``default'' types described in the Fortran 90 standard, +though that standard does not assign any particular @samp{KIND=} +value to these types. + +(Typically, these are @code{REAL*4}, @code{INTEGER*4}, +@code{LOGICAL*4}, and @code{COMPLEX*8}.) + +@item KIND=2 +This corresponds to types that occupy twice as much +storage as the default types. +@code{REAL(KIND=2)} is @code{DOUBLE PRECISION} (typically @code{REAL*8}), +@code{COMPLEX(KIND=2)} is @code{DOUBLE COMPLEX} (typically @code{COMPLEX*16}), + +These are the ``double precision'' types described in the Fortran 90 +standard, +though that standard does not assign any particular @samp{KIND=} +value to these types. + +@var{n} of 4 thus corresponds to types that occupy four times +as much storage as the default types, @var{n} of 8 to types that +occupy eight times as much storage, and so on. + +The @code{INTEGER(KIND=2)} and @code{LOGICAL(KIND=2)} types +are not necessarily supported by every GNU Fortran implementation. + +@item KIND=3 +This corresponds to types that occupy as much +storage as the default @code{CHARACTER} type, +which is the same effective type as @code{CHARACTER(KIND=1)} +(making that type effectively the same as @code{CHARACTER(KIND=3)}). + +(Typically, these are @code{INTEGER*1} and @code{LOGICAL*1}.) + +@var{n} of 6 thus corresponds to types that occupy twice as +much storage as the @var{n}=3 types, @var{n} of 12 to types +that occupy four times as much storage, and so on. + +These are not necessarily supported by every GNU Fortran +implementation. + +@item KIND=5 +This corresponds to types that occupy half the +storage as the default (@var{n}=1) types. + +(Typically, these are @code{INTEGER*2} and @code{LOGICAL*2}.) + +@var{n} of 25 thus corresponds to types that occupy one-quarter +as much storage as the default types. + +These are not necessarily supported by every GNU Fortran +implementation. @end table -Other types supported by @code{g77} -are derived from gcc types such as @samp{char}, @samp{short}, -@samp{int}, @samp{long int}, @samp{long long int}, @samp{long double}, -and so on. -That is, whatever types @samp{gcc} already supports, @code{g77} supports -now or probably will support in a future version. -The rules for the @samp{@var{numeric-type}*@var{n}} notation -apply to these types, -and new values for @samp{@var{numeric-type}(KIND=@var{n})} will be -assigned in a way that encourages clarity, consistency, and portability. +Note that these are @emph{proposed} correspondences and might change +in future versions of @code{g77}---avoid writing code depending +on them while @code{g77}, and therefore the GNU Fortran language +it defines, is in beta testing. + +Values not specified in the above list are reserved to +future versions of the GNU Fortran language. + +Implementation-dependent meanings will be assigned new, +unique prime numbers so as to not interfere with other +implementation-dependent meanings, and offer the possibility +of increasing the portability of code depending on such +types by offering support for them in other GNU Fortran +implementations. + +Other meanings that might be given unique values are: + +@itemize @bullet +@item +Types that make use of only half their storage size for +representing precision and range. + +For example, some compilers offer options that cause +@code{INTEGER} types to occupy the amount of storage +that would be needed for @code{INTEGER(KIND=2)} types, but the +range remains that of @code{INTEGER(KIND=1)}. + +@item +The IEEE single floating-point type. + +@item +Types with a specific bit pattern (endianness), such as the +little-endian form of @code{INTEGER(KIND=1)}. +These could permit, conceptually, use of portable code and +implementations on data files written by existing systems. +@end itemize + +Future @emph{prime} numbers should be given meanings in as incremental +a fashion as possible, to allow for flexibility and +expressiveness in combining types. + +For example, instead of defining a prime number for little-endian +IEEE doubles, one prime number might be assigned the meaning +``little-endian'', another the meaning ``IEEE double'', and the +value of @var{n} for a little-endian IEEE double would thus +naturally be the product of those two respective assigned values. +(It could even be reasonable to have IEEE values result from the +products of prime values denoting exponent and fraction sizes +and meanings, hidden bit usage, availability and representations +of special values such as subnormals, infinities, and Not-A-Numbers +(NaNs), and so on.) + +This assignment mechanism, while not inherently required for +future versions of the GNU Fortran language, is worth using +because it could ease management of the ``space'' of supported +types much easier in the long run. + +The above approach suggests a mechanism for specifying inheritance +of intrinsic (built-in) types for an entire, widely portable +product line. +It is certainly reasonable that, unlike programmers of other languages +offering inheritance mechanisms that employ verbose names for classes +and subclasses, along with graphical browsers to elucidate the +relationships, Fortran programmers would employ +a mechanism that works by multiplying prime numbers together +and finding the prime factors of such products. + +Most of the advantages for the above scheme have been explained +above. +One disadvantage is that it could lead to the defining, +by the GNU Fortran language, of some fairly large prime numbers. +This could lead to the GNU Fortran language being declared +``munitions'' by the United States Department of Defense. @node Constants -@section Constants +@subsection Constants @cindex constants @cindex types, constants -@code{g77} strictly assigns types to all constants not -documented as ``typeless'' (typeless constants including @samp{'1'Z}, -for example). -Context is never a determining factor for the type, and hence +(Corresponds to Section 4.2 of ANSI X3.9-1978 FORTRAN 77.) + +A @dfn{typeless constant} has one of the following forms: + +@example +'@var{binary-digits}'B +'@var{octal-digits}'O +'@var{hexadecimal-digits}'Z +'@var{hexadecimal-digits}'X +@end example + +@noindent +@var{binary-digits}, @var{octal-digits}, and @var{hexadecimal-digits} +are nonempty strings of characters in the set @samp{01}, @samp{01234567}, +and @samp{0123456789ABCDEFabcdef}, respectively. +(The value for @samp{A} (and @samp{a}) is 10, for @samp{B} and @samp{b} +is 11, and so on.) + +Typeless constants have values that depend on the context in which +they are used. + +All other constants, called @dfn{typed constants}, are interpreted---converted +to internal form---according to their inherent type. +Thus, context is @emph{never} a determining factor for the type, and hence the interpretation, of a typed constant. -Examples: @samp{1} is always type @samp{INTEGER}, -@samp{9.435784839284958} is always type @samp{REAL} (even if the -additional precision specified is lost, and even when used in a @samp{DOUBLE -PRECISION} context), @samp{1E0} is always type @samp{REAL}, and @samp{1D0} -is always type @samp{DOUBLE PRECISION}. +(All constants in the ANSI FORTRAN 77 language are typed constants.) -Many other Fortran compilers attempt to assign types to typed constants -based on their context. -This results in hard-to-find bugs, nonportable -code, and is not in the spirit (though it strictly follows the letter) -of the 77 and 90 standards. -@code{g77} will not support these dangerous -semantics, but might offer, in a future release, explicit constructs by -which a wider variety of typeless constants may be specified, and/or -user-requested warnings indicating places where @code{g77} might differ -from how other compilers assign types to constants. +For example, @samp{1} is always type @code{INTEGER(KIND=1)} in GNU +Fortran (called default INTEGER in Fortran 90), +@samp{9.435784839284958} is always type @code{REAL(KIND=1)} (even if the +additional precision specified is lost, and even when used in a +@code{REAL(KIND=2)} context), @samp{1E0} is always type @code{REAL(KIND=2)}, +and @samp{1D0} is always type @code{REAL(KIND=2)}. + +@node Integer Type +@subsection Integer Type + +(Corresponds to Section 4.3 of ANSI X3.9-1978 FORTRAN 77.) + +An integer constant also may have one of the following forms: + +@example +B'@var{binary-digits}' +O'@var{octal-digits}' +Z'@var{hexadecimal-digits}' +X'@var{hexadecimal-digits}' +@end example + +@noindent +@var{binary-digits}, @var{octal-digits}, and @var{hexadecimal-digits} +are nonempty strings of characters in the set @samp{01}, @samp{01234567}, +and @samp{0123456789ABCDEFabcdef}, respectively. +(The value for @samp{A} (and @samp{a}) is 10, for @samp{B} and @samp{b} +is 11, and so on.) + +@node Character Type +@subsection Character Type + +(Corresponds to Section 4.8 of ANSI X3.9-1978 FORTRAN 77.) + +A character constant may be delimited by a pair of double quotes +(@samp{"}) instead of apostrophes. +In this case, an apostrophe within the constant represents +a single apostrophe, while a double quote is represented in +the source text of the constant by two consecutive double +quotes with no intervening blanks. + +@cindex zero-length CHARACTER +@cindex null CHARACTER strings +@cindex empty CHARACTER strings +@cindex strings, empty +@cindex CHARACTER, null +A character constant may be empty (have a length of zero). + +A character constant may include a substring specification, +The value of such a constant is the value of the substring---for +example, the value of @samp{'hello'(3:5)} is the same +as the value of @samp{'llo'}. + +@node Expressions +@section Expressions + +(The following information augments or overrides the information in +Chapter 6 of ANSI X3.9-1978 FORTRAN 77 in specifying the GNU Fortran +language. +Chapter 6 of that document otherwise serves as the basis +for the relevant aspects of GNU Fortran.) + +@menu +* %LOC():: +@end menu + +@node %LOC() +@subsection The @code{%LOC()} Construct +@cindex %LOC() construct + +@example +%LOC(@var{arg}) +@end example + +The @code{%LOC()} construct is an expression +that yields the value of the location of its argument, +@var{arg}, in memory. +The size of the type of the expression depends on the system---typically, +it is equivalent to either @code{INTEGER(KIND=1)} or @code{INTEGER(KIND=2)}, +though it is actually type @code{INTEGER(KIND=0)}. + +The argument to @code{%LOC()} must be suitable as the +left-hand side of an assignment statement. +That is, it may not be a general expression involving +operators such as addition, subtraction, and so on, +nor may it be a constant. + +Use of @code{%LOC()} is recommended only for code that +is accessing facilities outside of GNU Fortran, such as +operating system or windowing facilities. +It is best to constrain such uses to isolated portions of +a program---portions that deal specifically and exclusively +with low-level, system-dependent facilities. +Such portions might well provide a portable interface for +use by the program as a whole, but are themselves not +portable, and should be thoroughly tested each time they +are rebuilt using a new compiler or version of a compiler. + +Do not depend on @code{%LOC()} returning a pointer that +can be safely used to @emph{define} (change) the argument. +While this might work in some circumstances, it is hard +to predict whether it will continue to work when a program +(that works using this unsafe behavior) +is recompiled using different command-line options or +a different version of @code{g77}. + +Generally, @code{%LOC()} is safe when used as an argument +to a procedure that makes use of the value of the corresponding +dummy argument only during its activation, and only when +such use is restricted to referencing (reading) the value +of the argument to @code{%LOC()}. + +@emph{Implementation Note:} Currently, @code{g77} passes +arguments (those not passed using a construct such as @code{%VAL()}) +by reference or descriptor, depending on the type of +the actual argument. +Thus, given @samp{INTEGER I}, @samp{CALL FOO(I)} would +seem to mean the same thing as @samp{CALL FOO(%LOC(I))}, and +in fact might compile to identical code. + +However, @samp{CALL FOO(%LOC(I))} emphatically means ``pass the +address of @samp{I} in memory''. +While @samp{CALL FOO(I)} might use that same approach in a +particular version of @code{g77}, another version or compiler +might choose a different implementation, such as copy-in/copy-out, +to effect the desired behavior---and which will therefore not +necessarily compile to the same code as would @samp{CALL FOO(%LOC(I))} +using the same version or compiler. + +@xref{Debugging and Interfacing}, for detailed information on +how this particular version of @code{g77} implements various +constructs. + +@node Specification Statements +@section Specification Statements + +(The following information augments or overrides the information in +Chapter 8 of ANSI X3.9-1978 FORTRAN 77 in specifying the GNU Fortran +language. +Chapter 8 of that document otherwise serves as the basis +for the relevant aspects of GNU Fortran.) + +@menu +* NAMELIST:: +* DOUBLE COMPLEX:: +@end menu + +@node NAMELIST +@subsection @code{NAMELIST} Statement +@cindex NAMELIST statement +@cindex statements, NAMELIST + +The @code{NAMELIST} statement, and related I/O constructs, are +supported by the GNU Fortran language in essentially the same +way as they are by @code{f2c}. + +@node DOUBLE COMPLEX +@subsection @code{DOUBLE COMPLEX} Statement +@cindex DOUBLE COMPLEX + +@code{DOUBLE COMPLEX} is a type-statement (and type) that +specifies the type @code{COMPLEX(KIND=2)} in GNU Fortran. + +@node Control Statements +@section Control Statements + +(The following information augments or overrides the information in +Chapter 11 of ANSI X3.9-1978 FORTRAN 77 in specifying the GNU Fortran +language. +Chapter 11 of that document otherwise serves as the basis +for the relevant aspects of GNU Fortran.) + +@menu +* DO WHILE:: +* END DO:: +* Construct Names:: +* CYCLE and EXIT:: +@end menu + +@node DO WHILE +@subsection DO WHILE +@cindex DO WHILE +@cindex MIL-STD 1753 + +The @code{DO WHILE} statement, a feature of both the MIL-STD 1753 and +Fortran 90 standards, is provided by the GNU Fortran language. + +@node END DO +@subsection END DO +@cindex END DO +@cindex MIL-STD 1753 + +The @code{END DO} statement is provided by the GNU Fortran language. + +This statement is used in one of two ways: + +@itemize @bullet +@item +The Fortran 90 meaning, in which it specifies the termination +point of a single @code{DO} loop started with a @code{DO} statement +that specifies no termination label. + +@item +The MIL-STD 1753 meaning, in which it specifies the termination +point of one or more @code{DO} loops, all of which start with a +@code{DO} statement that specify the label defined for the +@code{END DO} statement. + +This kind of @code{END DO} statement is merely a synonym for +@code{CONTINUE}, except it is permitted only when the statement +is labeled and a target of one or more labeled @code{DO} loops. + +It is expected that this use of @code{END DO} will be removed from +the GNU Fortran language in the future, though it is likely that +it will long be supported by @code{g77} as a dialect form. +@end itemize + +@node Construct Names +@subsection Construct Names +@cindex construct names + +The GNU Fortran language supports construct names as defined +by the Fortran 90 standard. +These names are local to the program unit and are defined +as follows: + +@example +@var{construct-name}: @var{block-statement} +@end example + +@noindent +Here, @var{construct-name} is the construct name itself; +its definition is connoted by the single colon (@samp{:}); and +@var{block-statement} is an @code{IF}, @code{DO}, +or @code{SELECT CASE} statement that begins a block. + +A block that is given a construct name must also specify the +same construct name in its termination statement: + +@example +END @var{block} @var{construct-name} +@end example + +@noindent +Here, @var{block} must be @code{IF}, @code{DO}, or @code{SELECT}, +as appropriate. + +@node CYCLE and EXIT +@subsection The @code{CYCLE} and @code{EXIT} Statements + +The @code{CYCLE} and @code{EXIT} statements specify that +the remaining statements in the current iteration of a +particular active (enclosing) @code{DO} loop are to be skipped. + +@code{CYCLE} specifies that these statements are skipped, +but the @code{END DO} statement that marks the end of the +@code{DO} loop be executed---that is, the next iteration, +if any, is to be started. +If the statement marking the end of the @code{DO} loop is +not @code{END DO}---in other words, if the loop is not +a block @code{DO}---the @code{CYCLE} statement does not +execute that statement, but does start the next iteration (if any). + +@code{EXIT} specifies that the loop specified by the +@code{DO} construct is terminated. + +The @code{DO} loop affected by @code{CYCLE} and @code{EXIT} +is the innermost enclosing @code{DO} loop when the following +forms are used: + +@example +CYCLE +EXIT +@end example + +Otherwise, the following forms specify the construct name +of the pertinent @code{DO} loop: + +@example +CYCLE @var{construct-name} +EXIT @var{construct-name} +@end example + +@code{CYCLE} and @code{EXIT} can be viewed as glorified @code{GO TO} +statements. +However, they cannot be easily thought of as @code{GO TO} statements +in obscure cases involving FORTRAN 77 loops. +For example: + +@smallexample + DO 10 I = 1, 5 + DO 10 J = 1, 5 + IF (J .EQ. 5) EXIT + DO 10 K = 1, 5 + IF (K .EQ. 3) CYCLE +10 PRINT *, 'I=', I, ' J=', J, ' K=', K +20 CONTINUE +@end smallexample + +@noindent +In particular, neither the @code{EXIT} nor @code{CYCLE} statements +above are equivalent to a @code{GO TO} statement to either label +@samp{10} or @samp{20}. + +To understand the effect of @code{CYCLE} and @code{EXIT} in the +above fragment, it is helpful to first translate it to its equivalent +using only block @code{DO} loops: + +@smallexample + DO I = 1, 5 + DO J = 1, 5 + IF (J .EQ. 5) EXIT + DO K = 1, 5 + IF (K .EQ. 3) CYCLE +10 PRINT *, 'I=', I, ' J=', J, ' K=', K + END DO + END DO + END DO +20 CONTINUE +@end smallexample + +Adding new labels allows translation of @code{CYCLE} and @code{EXIT} +to @code{GO TO} so they may be more easily understood by programmers +accustomed to FORTRAN coding: + +@smallexample + DO I = 1, 5 + DO J = 1, 5 + IF (J .EQ. 5) GOTO 18 + DO K = 1, 5 + IF (K .EQ. 3) GO TO 12 +10 PRINT *, 'I=', I, ' J=', J, ' K=', K +12 END DO + END DO +18 END DO +20 CONTINUE +@end smallexample + +@noindent +Thus, the @code{CYCLE} statement in the innermost loop skips over +the @code{PRINT} statement as it begins the next iteration of the +loop, while the @code{EXIT} statement in the middle loop ends that +loop but @emph{not} the outermost loop. + +@node Functions and Subroutines +@section Functions and Subroutines + +(The following information augments or overrides the information in +Chapter 15 of ANSI X3.9-1978 FORTRAN 77 in specifying the GNU Fortran +language. +Chapter 15 of that document otherwise serves as the basis +for the relevant aspects of GNU Fortran.) + +@menu +* %VAL():: +* %REF():: +* %DESCR():: +* Generics and Specifics:: +* REAL() and AIMAG() of Complex:: +* CMPLX() of DOUBLE PRECISION:: +* MIL-STD 1753:: +* f77/f2c Intrinsics:: +* Table of Intrinsic Functions:: +@end menu + +@node %VAL() +@subsection The @code{%VAL()} Construct +@cindex %VAL() construct + +@example +%VAL(@var{arg}) +@end example + +The @code{%VAL()} construct specifies that an argument, +@var{arg}, is to be passed by value, instead of by reference +or descriptor. + +@code{%VAL()} is restricted to actual arguments in +invocations of external procedures. + +Use of @code{%VAL()} is recommended only for code that +is accessing facilities outside of GNU Fortran, such as +operating system or windowing facilities. +It is best to constrain such uses to isolated portions of +a program---portions the deal specifically and exclusively +with low-level, system-dependent facilities. +Such portions might well provide a portable interface for +use by the program as a whole, but are themselves not +portable, and should be thoroughly tested each time they +are rebuilt using a new compiler or version of a compiler. + +@emph{Implementation Note:} Currently, @code{g77} passes +all arguments either by reference or by descriptor. + +Thus, use of @code{%VAL()} tends to be restricted to cases +where the called procedure is written in a language other +than Fortran that supports call-by-value semantics. +(C is an example of such a language.) + +@xref{Procedures,,Procedures (SUBROUTINE and FUNCTION)}, +for detailed information on +how this particular version of @code{g77} passes arguments +to procedures. + +@node %REF() +@subsection The @code{%REF()} Construct +@cindex %REF() construct + +@example +%REF(@var{arg}) +@end example + +The @code{%REF()} construct specifies that an argument, +@var{arg}, is to be passed by reference, instead of by +value or descriptor. + +@code{%REF()} is restricted to actual arguments in +invocations of external procedures. + +Use of @code{%REF()} is recommended only for code that +is accessing facilities outside of GNU Fortran, such as +operating system or windowing facilities. +It is best to constrain such uses to isolated portions of +a program---portions the deal specifically and exclusively +with low-level, system-dependent facilities. +Such portions might well provide a portable interface for +use by the program as a whole, but are themselves not +portable, and should be thoroughly tested each time they +are rebuilt using a new compiler or version of a compiler. + +Do not depend on @code{%REF()} supplying a pointer to the +procedure being invoked. +While that is a likely implementation choice, other +implementation choices are available that preserve Fortran +pass-by-reference semantics without passing a pointer to +the argument, @var{arg}. +(For example, a copy-in/copy-out implementation.) + +@emph{Implementation Note:} Currently, @code{g77} passes +all arguments +(other than variables and arrays of type @code{CHARACTER}) +by reference. +Future versions of, or dialects supported by, @code{g77} might +not pass @code{CHARACTER} functions by reference. + +Thus, use of @code{%REF()} tends to be restricted to cases +where @var{arg} is type @code{CHARACTER} but the called +procedure accesses it via a means other than the method +used for Fortran @code{CHARACTER} arguments. + +@xref{Procedures,,Procedures (SUBROUTINE and FUNCTION)}, for detailed information on +how this particular version of @code{g77} passes arguments +to procedures. + +@node %DESCR() +@subsection The @code{%DESCR()} Construct +@cindex %DESCR() construct + +@example +%DESCR(@var{arg}) +@end example + +The @code{%DESCR()} construct specifies that an argument, +@var{arg}, is to be passed by descriptor, instead of by +value or reference. + +@code{%DESCR()} is restricted to actual arguments in +invocations of external procedures. + +Use of @code{%DESCR()} is recommended only for code that +is accessing facilities outside of GNU Fortran, such as +operating system or windowing facilities. +It is best to constrain such uses to isolated portions of +a program---portions the deal specifically and exclusively +with low-level, system-dependent facilities. +Such portions might well provide a portable interface for +use by the program as a whole, but are themselves not +portable, and should be thoroughly tested each time they +are rebuilt using a new compiler or version of a compiler. + +Do not depend on @code{%DESCR()} supplying a pointer +and/or a length passed by value +to the procedure being invoked. +While that is a likely implementation choice, other +implementation choices are available that preserve the +pass-by-reference semantics without passing a pointer to +the argument, @var{arg}. +(For example, a copy-in/copy-out implementation.)@ +And, future versions of @code{g77} might change the +way descriptors are implemented, such as passing a +single argument pointing to a record containing the +pointer/length information instead of passing that same +information via two arguments as it currently does. + +@emph{Implementation Note:} Currently, @code{g77} passes +all variables and arrays of type @code{CHARACTER} +by descriptor. +Future versions of, or dialects supported by, @code{g77} might +pass @code{CHARACTER} functions by descriptor as well. + +Thus, use of @code{%DESCR()} tends to be restricted to cases +where @var{arg} is not type @code{CHARACTER} but the called +procedure accesses it via a means similar to the method +used for Fortran @code{CHARACTER} arguments. + +@xref{Procedures,,Procedures (SUBROUTINE and FUNCTION)}, for detailed information on +how this particular version of @code{g77} passes arguments +to procedures. + +@node Generics and Specifics +@subsection Generics and Specifics +@cindex generic intrinsics +@cindex intrinsics, generic + +The ANSI FORTRAN 77 language defines generic and specific +intrinsics. +In short, the distinctions are: + +@itemize @bullet +@item +@emph{Specific} intrinsics have +specific types for their arguments and a specific return +type. + +@item +@emph{Generic} intrinsics are treated, +on a case-by-case basis in the program's source code, +as one of several possible specific intrinsics. + +Typically, a generic intrinsic has a return type that +is determined by the type of one or more of its arguments. +@end itemize + +The GNU Fortran language generalizes these concepts somewhat, +especially by providing intrinsic subroutines and generic +intrinsics that are treated as either a specific intrinsic subroutine +or a specific intrinsic function (e.g. @code{SECOND}). + +However, GNU Fortran avoids generalizing this concept to +the point where existing code would be accepted as meaning +something possibly different than what was intended. + +For example, @code{ABS} is a generic intrinsic, so all working +code written using @code{ABS} of an @code{INTEGER} argument +expects an @code{INTEGER} return value. +Similarly, all such code expects that @code{ABS} of an @code{INTEGER*2} +argument returns an @code{INTEGER*2} return value. + +Yet, @code{IABS} is a @emph{specific} intrinsic that accepts only +an @code{INTEGER(KIND=1)} argument. +Code that passes something other than an @code{INTEGER(KIND=1)} +argument to @code{IABS} is not valid GNU Fortran code, because +it is not clear what the author intended. + +For example, if @samp{J} is @code{INTEGER(KIND=6)}, @samp{IABS(J)} +is not defined by the GNU Fortran language, because the programmer +might have used that construct to mean any of the following, subtly +different, things: + +@itemize @bullet +@item +Convert @samp{J} to @code{INTEGER(KIND=1)} first +(as if @samp{IABS(INT(J))} had been written). + +@item +Convert the result of the intrinsic to @code{INTEGER(KIND=1)} +(as if @samp{INT(ABS(J))} had been written). + +@item +No conversion (as if @samp{ABS(J)} had been written). +@end itemize + +The distinctions matter especially when types and values wider than +@code{INTEGER(KIND=1)} (such as @code{INTEGER(KIND=2)}), or when +operations performing more ``arithmetic'' than absolute-value, are involved. + +The following sample program is not a valid GNU Fortran program, but +might be accepted by other compilers. +If so, the output is likely to be revealing in terms of how a given +compiler treats intrinsics (that normally are specific) when they +are given arguments that do not conform to their stated requirements: + +@cindex JCB002 program +@smallexample + PROGRAM JCB002 +C +C Written by James Craig Burley 1997-02-20. +C Contact via Internet email: burley@@gnu.ai.mit.edu +C +C Determine how compilers handle non-standard IDIM +C on INTEGER*2 operands, which presumably can be +C extrapolated into understanding how the compiler +C generally treats specific intrinsics that are passed +C arguments not of the correct types. +C +C If your compiler implements INTEGER*2 and INTEGER +C as the same type, change all INTEGER*2 below to +C INTEGER*1. +C + INTEGER*2 I0, I4 + INTEGER I1, I2, I3 + INTEGER*2 ISMALL, ILARGE + INTEGER*2 ITOOLG, ITWO + LOGICAL L2, L3, L4 +C +C Find smallest INTEGER*2 number. +C + ISMALL=0 + 10 I0 = ISMALL-1 + IF ((I0 .GE. ISMALL) .OR. (I0+1 .NE. ISMALL)) GOTO 20 + ISMALL = I0 + GOTO 10 + 20 CONTINUE +C +C Find largest INTEGER*2 number. +C + ILARGE=0 + 30 I0 = ILARGE+1 + IF ((I0 .LE. ILARGE) .OR. (I0-1 .NE. ILARGE)) GOTO 40 + ILARGE = I0 + GOTO 30 + 40 CONTINUE +C +C Multiplying by two adds stress to the situation. +C + ITWO = 2 +C +C Need a number that, added to -2, is too wide to fit in I*2. +C + ITOOLG = ISMALL +C +C Use IDIM the straightforward way. +C + I1 = IDIM (ILARGE, ISMALL) * ITWO + ITOOLG +C +C Try first interpretation. +C + I2 = (INT (ILARGE) - INT (ISMALL)) * ITWO + ITOOLG +C +C Try second interpretation. +C + I3 = (INT (ILARGE - ISMALL)) * ITWO + ITOOLG +C +C Try third interpretation. +C + I4 = (ILARGE - ISMALL) * ITWO + ITOOLG +C +C Print results. +C + PRINT *, 'ILARGE=', ILARGE + PRINT *, 'ITWO=', ITWO + PRINT *, 'ITOOLG=', ITOOLG + PRINT *, 'ISMALL=', ISMALL + PRINT *, 'I1=', I1 + PRINT *, 'I2=', I2 + PRINT *, 'I3=', I3 + PRINT *, 'I4=', I4 + PRINT * + L2 = (I1 .EQ. I2) + L3 = (I1 .EQ. I3) + L4 = (I1 .EQ. I4) + IF (L2 .AND. .NOT.L3 .AND. .NOT.L4) THEN + PRINT *, 'Interp 1: IDIM(I*2,I*2) => IDIM(INT(I*2),INT(I*2))' + STOP + END IF + IF (L3 .AND. .NOT.L2 .AND. .NOT.L4) THEN + PRINT *, 'Interp 2: IDIM(I*2,I*2) => INT(DIM(I*2,I*2))' + STOP + END IF + IF (L4 .AND. .NOT.L2 .AND. .NOT.L3) THEN + PRINT *, 'Interp 3: IDIM(I*2,I*2) => DIM(I*2,I*2)' + STOP + END IF + PRINT *, 'Results need careful analysis.' + END +@end smallexample + +It is possible that a future version of the GNU Fortran language +will permit specific intrinsic invocations with wrong-typed +arguments (such as @code{IDIM} in the above example) if the vast +majority of production compilers agree on the interpretation of +such invocations. + +Especially if you know of a compiler that does not implement +interpretation 3 above (output @samp{Interp 3: @dots{}}), please +let us know the details (compiler product, version, machine, results, +and so on). + +@node REAL() and AIMAG() of Complex +@subsection @code{REAL()} and @code{AIMAG()} of Complex +@cindex REAL intrinsic +@cindex intrinsics, REAL +@cindex AIMAG intrinsic +@cindex intrinsics, AIMAG + +The GNU Fortran language disallows @code{REAL(@var{expr})} +and @code{AIMAG(@var{expr})}, +where @var{expr} is any @code{COMPLEX} type other than @code{COMPLEX(KIND=1)}, +except when they are used in the following way: + +@example +REAL(REAL(@var{expr})) +REAL(AIMAG(@var{expr})) +@end example + +@noindent +The above forms explicitly specify that the desired effect +is to convert the real or imaginary part of @var{expr}, which might +be some @code{REAL} type other than @code{REAL(KIND=1)}, +to type @code{REAL(KIND=1)}, +and have that serve as the value of the expression. + +The GNU Fortran language offers clearly named intrinsics to extract the +real and imaginary parts of a complex entity without any +conversion: + +@example +REALPART(@var{expr}) +IMAGPART(@var{expr}) +@end example + +To express the above using typical extended FORTRAN 77, +use the following constructs +(when @var{expr} is @code{COMPLEX(KIND=2)}): + +@example +DBLE(@var{expr}) +DIMAG(@var{expr}) +@end example + +The FORTRAN 77 language offers no way +to explicitly specify the real and imaginary parts of a complex expression of +arbitrary type, apparently as a result of requiring support for +only one @code{COMPLEX} type (@code{COMPLEX(KIND=1)}). +The concepts of converting an expression to type @code{REAL(KIND=1)} and +of extracting the real part of a complex expression were +thus ``smooshed'' by FORTRAN 77 into a single intrinsic, since +they happened to have the exact same effect in that language +(due to having only one @code{COMPLEX} type). + +@emph{Note:} When @samp{-ff90} is in effect, +@code{g77} treats @samp{REAL(@var{expr})}, where @var{expr} is of +type @code{COMPLEX}, as @samp{REALPART(@var{expr})}, +whereas with @samp{-fugly-complex -fno-f90} in effect, it is +treated as @samp{REAL(REALPART(@var{expr}))}. + +@xref{Ugly Complex Part Extraction}, for more information. + +@node CMPLX() of DOUBLE PRECISION +@subsection @code{CMPLX()} of @code{DOUBLE PRECISION} +@cindex CMPLX intrinsic +@cindex intrinsics, CMPLX + +In accordance with Fortran 90 and at least some (perhaps all) +other compilers, the GNU Fortran language defines @code{CMPLX()} +as always returning a result that is type @code{COMPLEX(KIND=1)}. + +This means @samp{CMPLX(D1,D2)}, where @samp{D1} and @samp{D2} +are @code{REAL(KIND=2)} (@code{DOUBLE PRECISION}), is treated as: + +@example +CMPLX(SNGL(D1), SNGL(D2)) +@end example + +The GNU Fortran language also provides the @code{DCMPLX()} intrinsic, +which is provided by some FORTRAN 77 compilers to construct +a @code{DOUBLE COMPLEX} entity from of @code{DOUBLE PRECISION} +operands. +However, this solution does not scale well when more @code{COMPLEX} types +(having various precisions and ranges) are offered by Fortran implementations. + +Fortran 90 extends the @code{CMPLX()} intrinsic by adding +an extra argument used to specify the desired kind of complex +result. +However, this solution is somewhat awkward to use. + +The GNU Fortran language provides a simple way to build a complex +value out of two numbers, with the precise type of the value +determined by the types of the two numbers (via the usual +type-promotion mechanism): + +@example +COMPLEX(@var{real}, @var{imag}) +@end example + +When @var{real} and @var{imag} are the same @code{REAL} types, @code{COMPLEX()} +performs no conversion other than to put them together to form a +complex result of the same (complex version of real) type. + +@xref{Complex Intrinsic}, for more information. + +@node MIL-STD 1753 +@subsection MIL-STD 1753 Support +@cindex MIL-STD 1753 + +The GNU Fortran language includes the MIL-STD 1753 intrinsics +@code{BTEST}, @code{IAND}, @code{IBCLR}, @code{IBITS}, +@code{IBSET}, @code{IEOR}, @code{IOR}, @code{ISHFT}, +@code{ISHFTC}, @code{MVBITS}, and @code{NOT}. + +@node f77/f2c Intrinsics +@subsection @code{f77}/@code{f2c} Intrinsics + +The bit-manipulation intrinsics supported by traditional +@code{f77} and by @code{f2c} are available in the GNU Fortran language. +These include @code{AND}, @code{LSHIFT}, @code{OR}, @code{RSHIFT}, +and @code{XOR}. + +Also supported are the intrinsics @code{CDABS}, +@code{CDCOS}, @code{CDEXP}, @code{CDLOG}, @code{CDSIN}, +@code{CDSQRT}, @code{DCMPLX}, @code{DCONJG}, @code{DFLOAT}, +@code{DIMAG}, @code{DREAL}, and @code{IMAG}, +@code{ZABS}, @code{ZCOS}, @code{ZEXP}, @code{ZLOG}, @code{ZSIN}, +and @code{ZSQRT}. + +@node Table of Intrinsic Functions +@subsection Table of Intrinsic Functions +@cindex intrinsics, table of +@cindex table of intrinsics + +(Corresponds to Section 15.10 of ANSI X3.9-1978 FORTRAN 77.) + +The GNU Fortran language adds various functions, subroutines, types, +and arguments to the set of intrinsic functions in ANSI FORTRAN 77. +The complete set of intrinsics supported by the GNU Fortran language +is described below. + +Note that a name is not treated as that of an intrinsic if it is +specified in an @code{EXTERNAL} statement in the same program unit; +if a command-line option is used to disable the groups to which +the intrinsic belongs; or if the intrinsic is not named in an +@code{INTRINSIC} statement and a command-line option is used to +hide the groups to which the intrinsic belongs. + +So, it is recommended that any reference in a program unit to +an intrinsic procedure that is not a standard FORTRAN 77 +intrinsic be accompanied by an appropriate @code{INTRINSIC} +statement in that program unit. +This sort of defensive programming makes it more +likely that an implementation will issue a diagnostic rather +than generate incorrect code for such a reference. + +The terminology used below is based on that of the Fortran 90 +standard, so that the text may be more concise and accurate: + +@itemize @bullet +@item +@code{OPTIONAL} means the argument may be omitted. + +@item +@samp{A-1, A-2, @dots{}, A-n} means more than one argument +(generally named @samp{A}) may be specified. + +@item +@samp{scalar} means the argument must not be an array (must +be a variable or array element, or perhaps a constant if expressions +are permitted). + +@item +@samp{DIMENSION(4)} means the argument must be an array having 4 elements. + +@item +@code{INTENT(IN)} means the argument must be an expression +(such as a constant or a variable that is defined upon invocation +of the intrinsic). + +@item +@code{INTENT(OUT)} means the argument must be definable by the +invocation of the intrinsic (that is, must not be a constant nor +an expression involving operators other than array reference and +substring reference). + +@item +@code{INTENT(INOUT)} means the argument must be defined prior to, +and definable by, invocation of the intrinsic (a combination of +the requirements of @code{INTENT(IN)} and @code{INTENT(OUT)}. +@end itemize + +@ifinfo +(Note that the blank lines appearing in the menu below +are not intentional---they result from a bug in the +GNU @code{makeinfo} program@dots{}a program that, if it +did not exist, this document would be in far worse shape!) +@end ifinfo + +@c The actual documentation for intrinsics comes from +@c intdoc.texi, which in turn is automatically generated +@c from the internal g77 tables in intrin.def _and_ the +@c largely hand-written text in intdoc.h. So, if you want +@c to change or add to existing documentation on intrinsics, +@c you probably want to edit intdoc.h. +@c +@set familyF77 +@set familyGNU +@set familyASC +@set familyMIL +@set familyF90 +@clear familyVXT +@clear familyFVZ +@set familyF2C +@set familyF2U +@include intdoc.texi + +@node Scope and Classes of Names +@section Scope and Classes of Symbolic Names +@cindex symbolic names +@cindex scope + +(The following information augments or overrides the information in +Chapter 18 of ANSI X3.9-1978 FORTRAN 77 in specifying the GNU Fortran +language. +Chapter 18 of that document otherwise serves as the basis +for the relevant aspects of GNU Fortran.) + +@menu +* Underscores in Symbol Names:: +@end menu + +@node Underscores in Symbol Names +@subsection Underscores in Symbol Names +@cindex underscores + +Underscores (@samp{_}) are accepted in symbol names after the first +character (which must be a letter). + +@node Other Dialects +@chapter Other Dialects + +GNU Fortran supports a variety of features that are not +considered part of the GNU Fortran language itself, but +are representative of various dialects of Fortran that +@code{g77} supports in whole or in part. + +Any of the features listed below might be disallowed by +@code{g77} unless some command-line option is specified. +Currently, some of the features are accepted using the +default invocation of @code{g77}, but that might change +in the future. + +@emph{Note: This portion of the documentation definitely needs a lot +of work!} + +@menu +* Source Form:: Details of fixed-form and free-form source. +* Trailing Comment:: Use of @samp{/*} to start a comment. +* Debug Line:: Use of @samp{D} in column 1. +* Dollar Signs:: Use of @samp{$} in symbolic names. +* Case Sensitivity:: Uppercase and lowercase in source files. +* VXT Fortran:: @dots{}versus the GNU Fortran language. +* Fortran 90:: @dots{}versus the GNU Fortran language. +* Pedantic Compilation:: Enforcing the standard. +* Distensions:: Misfeatures supported by GNU Fortran. +@end menu @node Source Form @section Source Form @@ -3677,37 +5886,51 @@ from how other compilers assign types to constants. @cindex fixed form @cindex free form -The @samp{-ffree-form} (aka @samp{-fno-fixed-form}) and @samp{-ffixed-form} -(aka @samp{-fno-free-form}) command-line options govern how the -source file is interpreted. +GNU Fortran accepts programs written in either fixed form or +free form. + Fixed form -corresponds to classic ANSI FORTRAN 77 (plus popular extensions, such as +corresponds to ANSI FORTRAN 77 (plus popular extensions, such as allowing tabs) and Fortran 90's fixed form. + Free form corresponds to Fortran 90's free form (though possibly not entirely up-to-date, and without complaining about some things that for which Fortran 90 requires -diagnostics, such as @samp{R = 3 . 1}). +diagnostics, such as the spaces in the constant in @samp{R = 3 . 1}). The way a Fortran compiler views source files depends entirely on the -implementation choices made for the compiler. +implementation choices made for the compiler, since those choices +are explicitly left to the implementation by the published Fortran +standards. GNU Fortran currently tries to be somewhat like a few popular compilers (@code{f2c}, DEC Fortran, and so on), though a cleaner default definition along with more flexibility offered by command-line options is likely to be offered in version 0.6. -Here are some facts regarding the way @code{g77} interprets source lines: +This section describes how @code{g77} interprets source lines. -@itemize @bullet +@menu +* Carriage Returns:: Carriage returns ignored. +* Tabs:: Tabs converted to spaces. +* Short Lines:: Short lines padded with spaces (fixed-form only). +* Long Lines:: Long lines truncated. +* Ampersands:: Special Continuation Lines. +@end menu + +@node Carriage Returns +@subsection Carriage Returns @cindex carriage returns -@item + Carriage returns (@samp{\r}) in source lines are ignored. This is somewhat different from @code{f2c}, which seems to treat them as spaces outside character/Hollerith constants, and encodes them as @samp{\r} inside such constants. +@node Tabs +@subsection Tabs @cindex tab characters -@item + A source line with a @key{TAB} character anywhere in it is treated as entirely significant---however long it is---instead of ending in column 72 (for fixed-form source) or 132 (for free-form source). @@ -3720,7 +5943,7 @@ position as if it had been affected by the canonical tab positioning. translates tabs to the appropriate number of spaces (a la the default for the UNIX @code{expand} command) before doing any other processing, other than (currently) noting whether a tab was found on a line and using this -info to decide how to interpret the length of the line and continued +information to decide how to interpret the length of the line and continued constants. Note that this default behavior probably will change for version 0.6, @@ -3737,9 +5960,17 @@ and perhaps even an option will be added to specify the truncated-line behavior to which some Digital compilers default (and which affects the way continued character/Hollerith constants are interpreted). -@item -Source lines shorter than the applicable fixed length are treated as +@node Short Lines +@subsection Short Lines +@cindex short source lines +@cindex space-padding +@cindex spaces +@cindex source lines, short +@cindex lines, short + +Source lines shorter than the applicable fixed-form length are treated as if they were padded with spaces to that length. +(None of this is relevant to source files written in free form.) This affects only continued character and Hollerith constants, and is a different @@ -3755,124 +5986,72 @@ specify the alternate behavior as well. Note that this padding cannot apply to lines that are effectively of infinite length---such lines are specified using command-line options like @samp{-ffixed-line-length-none}, for example. -@end itemize -@node Pedantic Compilation -@section Pedantic Compilation -@cindex pedantic compilation -@cindex compilation, pedantic +@node Long Lines +@subsection Long Lines +@cindex long source lines +@cindex truncation +@cindex lines, long +@cindex source lines, long -The @samp{-fpedantic} command-line option specifies that @code{g77} -is to warn about certain non-standard constructs. -This is useful for finding -some extensions @code{g77} accepts that other compilers might not accept. -(Note that the @samp{-pedantic} and @samp{-pedantic-errors} options -always imply @samp{-fpedantic}.) - -With @samp{-ff90} in force along with @samp{-fpedantic}, some constructs are -accepted that result in diagnostics when @samp{-fno-f90} and -@samp{-fpedantic} are both in force. -@xref{Extensions,,GNU Fortran Extensions}, for information on those constructs. - -The constructs for which @code{g77} issues diagnostics when @samp{-fpedantic} -and @samp{-fno-f90} are in force are: - -@itemize @bullet -@item -Automatic arrays, as in @samp{REAL A(N)}, where @samp{A} -is not a dummy argument. - -@item -@samp{READ (5), I} and @samp{WRITE (10), J}---the standard disallows the -comma in each case, while allowing it in @samp{READ 10, I}, but many -compilers (including @code{f2c}) allow the superfluous comma. - -@item -@samp{DOUBLE COMPLEX}, either explicitly (via explicit or @samp{IMPLICIT} -statement) or implicitly (as in @samp{C*D}, where @samp{C} is @samp{COMPLEX} -and @samp{D} is @samp{DOUBLE PRECISION}, which is prohibited by the -standard because it should produce a non-standard @samp{DOUBLE COMPLEX} -result). - -@item -Automatic conversion of numeric -expressions to @samp{INTEGER} in contexts such as: +Source lines longer than the applicable length are truncated to that +length. +Currently, @code{g77} does not warn if the truncated characters are +not spaces, to accommodate existing code written for systems that +treated truncated text as commentary (especially in columns 73 through 80). -@itemize -- -@item -Array-reference indexes. -@item -Alternate-return values. -@item -Computed @samp{GOTO}. -@item -@samp{FORMAT} run-time expressions (not yet supported). -@item -Dimension lists in specification statements. -@item -Numbers for I/O statements (such as @samp{READ (UNIT=3.2), I}) -@item -Sizes of @samp{CHARACTER} entities in specification statements. -@item -Kind types in specification entities (a Fortran 90 feature). -@item -Initial, terminal, and incrementation parameters for implied-@samp{DO} -constructs in @samp{DATA} statements. -@end itemize +@node Ampersands +@subsection Ampersand Continuation Line +@cindex ampersand continuation line +@cindex continuation line, ampersand -@item -Automatic conversion of @samp{LOGICAL} expressions to @samp{INTEGER} -in contexts such as arithmetic @samp{IF} (where @samp{COMPLEX} -expressions are disallowed anyway). +A @samp{&} in column 1 of fixed-form source denotes an arbitrary-length +continuation line, imitating the behavior of @code{f2c}. -@item -Substring operators applied to character constants and named -constants (such as @samp{PRINT *,'hello'(3:5)}, which would print @samp{llo}). +@node Trailing Comment +@section Trailing Comment -@item -Null argument passed to statement function (as in @samp{PRINT *,FOO(,3)}). +@code{g77} supports use of @samp{/*} to start a trailing +comment. +In the GNU Fortran language, @samp{!} is used for this purpose. -@item -Differences between program units regarding whether a given @samp{COMMON} -area is @samp{SAVE}d (for targets where program units in a single source -file are ``glued'' together as they typically are for UNIX development -environments). +@samp{/*} is not in the GNU Fortran language +because the use of @samp{/*} in a program might +suggest to some readers that a block, not trailing, comment is +started (and thus ended by @samp{*/}, not end of line), +since that is the meaning of @samp{/*} in C. -@item -Differences between named-@samp{COMMON}-block sizes between program units. +Also, such readers might think they can use @samp{//} to start +a trailing comment as an alternative to @samp{/*}, but +@samp{//} already denotes concatenation, and such a ``comment'' +might actually result in a program that compiles without +error (though it would likely behave incorrectly). -@item -Specification statements following first @samp{DATA} statement (normally -@samp{DATA I/1/} may be followed by @samp{INTEGER J}, though not -@samp{INTEGER I}, but @samp{-fpedantic} disables use of both cases. +@node Debug Line +@section Debug Line +@cindex debug line -@item -Semicolon as statement separator (as in @samp{CALL FOO; CALL BAR}). -@c -@c @item -@c Comma before list of I/O items in @samp{WRITE} -@c @c, @samp{ENCODE}, @samp{DECODE}, and @samp{REWRITE} -@c statements, as with @samp{READ} (as explained above). +Use of @samp{D} or @samp{d} as the first character (column 1) of +a source line denotes a debug line. -@item -Use of @samp{&} in column 1 of fixed-form source (indicates continuation). +In turn, a debug line is treated as either a comment line +or a normal line, depending on whether debug lines are enabled. -@item -Use of @samp{CHARACTER} constants to initialize numeric entities, and vice -versa. +When treated as a comment line, a line beginning with @samp{D} or +@samp{d} is treated as if it the first character was @samp{C} or @samp{c}, respectively. +When treated as a normal line, such a line is treated as if +the first character was @key{SPC} (space). -@item -Expressions having two arithmetic operators in a row, such -as @samp{X*-Y}. -@end itemize +(Currently, @code{g77} provides no means for treating debug +lines as normal lines.) -If @samp{-fpedantic} is specified along with @samp{-ff90}, the -following constructs result in diagnostics: +@node Dollar Signs +@section Dollar Signs in Symbol Names +@cindex dollar sign +@cindex $ -@itemize @bullet -@item -Use of semicolons on line with INCLUDE statement. -@end itemize +Dollar signs (@samp{$}) are allow in symbol names (after the first character) +when the @samp{-fdollar-ok} option is specified. @node Case Sensitivity @section Case Sensitivity @@ -3897,9 +6076,10 @@ None of these settings have any effect on the contents of comments or of character or Hollerith constants. Note that things like the @samp{E} in the statement @samp{CALL FOO(3.2E10)} and the @samp{TO} in @samp{ASSIGN 10 TO LAB} -are considered built-in keywords. +are considered built-in keywords, and so are affected by +these settings. -Low-level switches are identified in this discussion thusly: +Low-level switches are identified in this section as follows: @itemize @w{} @item A @@ -3957,28 +6137,28 @@ Allow InitialCaps Only (see Note 2) @end itemize @end itemize -Note 1: @code{g77} eventually will support @samp{NAMELIST} in a manner that is +Note 1: @code{g77} eventually will support @code{NAMELIST} in a manner that is consistent with these source switches---in the sense that input will be expected to meet the same requirements as source code in terms of matching symbol names and keywords (for the exponent letters). -Currently, however, @samp{NAMELIST} is supported @samp{libf2c}, -which uppercases @samp{NAMELIST} input and symbol names for matching. -This means not only that @samp{NAMELIST} output currently shows symbol +Currently, however, @code{NAMELIST} is supported by @code{libf2c}, +which uppercases @code{NAMELIST} input and symbol names for matching. +This means not only that @code{NAMELIST} output currently shows symbol (and keyword) names in uppercase even if lower-case source -conversion (option A2) is selected, but that @samp{NAMELIST} cannot be +conversion (option A2) is selected, but that @code{NAMELIST} cannot be adequately supported when source case preservation (option A0) is selected. If A0 is selected, a warning message will be -output for each @samp{NAMELIST} statement to this effect. +output for each @code{NAMELIST} statement to this effect. The behavior of the program is undefined at run time if two or more symbol names -appear in a given @samp{NAMELIST} such that the names are identical +appear in a given @code{NAMELIST} such that the names are identical when converted to upper case (e.g. @samp{NAMELIST /X/ VAR, Var, var}). For complete and total elegance, perhaps there should be a warning when option A2 is selected, since the output of NAMELIST is currently -in uppercase but will someday be lowercase (when a @samp{libg77} is written), +in uppercase but will someday be lowercase (when a @code{libg77} is written), but that seems to be overkill for a product in beta test. Note 2: Rules for InitialCaps names are: @@ -4147,15 +6327,896 @@ All remaining combinations are useless in that they prevent successful compilation of non-null source files (source files with something other than comments). -@node Intrinsics -@section Intrinsics +@node VXT Fortran +@section VXT Fortran + +@cindex VXT extensions +@cindex extensions, VXT +@code{g77} supports certain constructs that +have different meanings in VXT Fortran than they +do in the GNU Fortran language. + +Generally, this manual uses the invented term VXT Fortran to refer +VAX FORTRAN (circa v4). +That compiler offered many popular features, though not necessarily +those that are specific to the VAX processor architecture, +the VMS operating system, +or Digital Equipment Corporation's Fortran product line. +(VAX and VMS probably are trademarks of Digital Equipment +Corporation.) + +An extension offered by a Digital Fortran product that also is +offered by several other Fortran products for different kinds of +systems is probably going to be considered for inclusion in @code{g77} +someday, and is considered a VXT Fortran feature. + +The @samp{-fvxt} option generally specifies that, where +the meaning of a construct is ambiguous (means one thing +in GNU Fortran and another in VXT Fortran), the VXT Fortran +meaning is to be assumed. + +@menu +* Double Quote Meaning:: @samp{"2000} as octal constant. +* Exclamation Point:: @samp{!} in column 6. +@end menu + +@node Double Quote Meaning +@subsection Meaning of Double Quote +@cindex double quotes +@cindex character constants +@cindex constants, character +@cindex octal constants +@cindex constants, octal + +@code{g77} treats double-quote (@samp{"}) +as beginning an octal constant of @code{INTEGER(KIND=1)} type +when the @code{-fvxt} option is specified. +The form of this octal constant is + +@example +"@var{octal-digits} +@end example + +@noindent +where @var{octal-digits} is a nonempty string of characters in +the set @samp{01234567}. + +For example, the @code{-fvxt} option permits this: + +@example +PRINT *, "20 +END +@end example + +@noindent +The above program would print the value @samp{16}. + +@xref{Integer Type}, for information on the preferred construct +for integer constants specified using GNU Fortran's octal notation. + +(In the GNU Fortran language, the double-quote character (@samp{"}) +delimits a character constant just as does apostrophe (@samp{'}). +There is no way to allow +both constructs in the general case, since statements like +@samp{PRINT *,"2000 !comment?"} would be ambiguous.) + +@node Exclamation Point +@subsection Meaning of Exclamation Point in Column 6 +@cindex exclamation points +@cindex continuation character +@cindex characters, continuation +@cindex comment character +@cindex characters, comment + +@code{g77} treats an exclamation point (@samp{!}) in column 6 of +a fixed-form source file +as a continuation character rather than +as the beginning of a comment +(as it does in any other column) +when the @code{-fvxt} option is specified. + +The following program, when run, prints a message indicating +whether it is interpreted according to GNU Fortran (and Fortran 90) +rules or VXT Fortran rules: + +@smallexample +C234567 (This line begins in column 1.) + I = 0 + !1 + IF (I.EQ.0) PRINT *, ' I am a VXT Fortran program' + IF (I.EQ.1) PRINT *, ' I am a Fortran 90 program' + IF (I.LT.0 .OR. I.GT.1) PRINT *, ' I am a HAL 9000 computer' + END +@end smallexample + +(In the GNU Fortran and Fortran 90 languages, exclamation point is +a valid character and, unlike space (@key{SPC}) or zero (@samp{0}), +marks a line as a continuation line when it appears in column 6.) + +@node Fortran 90 +@section Fortran 90 +@cindex compatibility, Fortran 90 +@cindex Fortran 90 compatibility + +The GNU Fortran language includes a number of features that are +part of Fortran 90, even when the @samp{-ff90} option is not specified. +The features enabled by @samp{-ff90} are intended to be those that, +when @samp{-ff90} is not specified, would have another +meaning to @code{g77}---usually meaning something invalid in the +GNU Fortran language. + +So, the purpose of @samp{-ff90} is not to specify whether @code{g77} is +to gratuitously reject Fortran 90 constructs. +The @samp{-pedantic} option specified with @samp{-fno-f90} is intended +to do that, although its implementation is certainly incomplete at +this point. + +When @samp{-ff90} is specified: + +@itemize @bullet +@item +The type of @samp{REAL(@var{expr})} and @samp{AIMAG(@var{expr})}, +where @var{expr} is @code{COMPLEX} type, +is the same type as the real part of @var{expr}. + +For example, assuming @samp{Z} is type @code{COMPLEX(KIND=2)}, +@samp{REAL(Z)} would return a value of type @code{REAL(KIND=2)}, +not of type @code{REAL(KIND=1)}, since @samp{-ff90} is specified. +@end itemize + +@node Pedantic Compilation +@section Pedantic Compilation +@cindex pedantic compilation +@cindex compilation, pedantic + +The @samp{-fpedantic} command-line option specifies that @code{g77} +is to warn about code that is not standard-conforming. +This is useful for finding +some extensions @code{g77} accepts that other compilers might not accept. +(Note that the @samp{-pedantic} and @samp{-pedantic-errors} options +always imply @samp{-fpedantic}.) + +With @samp{-fno-f90} in force, ANSI FORTRAN 77 is used as the standard +for conforming code. +With @samp{-ff90} in force, Fortran 90 is used. + +The constructs for which @code{g77} issues diagnostics when @samp{-fpedantic} +and @samp{-fno-f90} are in force are: + +@itemize @bullet +@item +Automatic arrays, as in + +@example +SUBROUTINE X(N) +REAL A(N) +@dots{} +@end example + +@noindent +where @samp{A} is not listed in any @code{ENTRY} statement, +and thus is not a dummy argument. + +@item +The commas in @samp{READ (5), I} and @samp{WRITE (10), J}. + +These commas are disallowed by FORTRAN 77, but, while strictly +superfluous, are syntactically elegant, +especially given that commas are required in statements such +as @samp{READ 99, I} and @samp{PRINT *, J}. +Many compilers permit the superfluous commas for this reason. + +@item +@code{DOUBLE COMPLEX}, either explicitly or implicitly. + +An explicit use of this type is via a @code{DOUBLE COMPLEX} or +@code{IMPLICIT DOUBLE COMPLEX} statement, for examples. + +An example of an implicit use is the expression @samp{C*D}, +where @samp{C} is @code{COMPLEX(KIND=1)} +and @samp{D} is @code{DOUBLE PRECISION}. +This expression is prohibited by ANSI FORTRAN 77 +because the rules of promotion would suggest that it +produce a @code{DOUBLE COMPLEX} result---a type not +provided for by that standard. + +@item +Automatic conversion of numeric +expressions to @code{INTEGER(KIND=1)} in contexts such as: + +@itemize -- +@item +Array-reference indexes. +@item +Alternate-return values. +@item +Computed @code{GOTO}. +@item +@code{FORMAT} run-time expressions (not yet supported). +@item +Dimension lists in specification statements. +@item +Numbers for I/O statements (such as @samp{READ (UNIT=3.2), I}) +@item +Sizes of @code{CHARACTER} entities in specification statements. +@item +Kind types in specification entities (a Fortran 90 feature). +@item +Initial, terminal, and incrementation parameters for implied-@code{DO} +constructs in @code{DATA} statements. +@end itemize + +@item +Automatic conversion of @code{LOGICAL} expressions to @code{INTEGER} +in contexts such as arithmetic @code{IF} (where @code{COMPLEX} +expressions are disallowed anyway). + +@item +Zero-size array dimensions, as in: + +@example +INTEGER I(10,20,4:2) +@end example + +@item +Zero-length @code{CHARACTER} entities, as in: + +@example +PRINT *, '' +@end example + +@item +Substring operators applied to character constants and named +constants, as in: + +@example +PRINT *, 'hello'(3:5) +@end example + +@item +Null arguments passed to statement function, as in: + +@example +PRINT *, FOO(,3) +@end example + +@item +Disagreement among program units regarding whether a given @code{COMMON} +area is @code{SAVE}d (for targets where program units in a single source +file are ``glued'' together as they typically are for UNIX development +environments). + +@item +Disagreement among program units regarding the size of a +named @code{COMMON} block. + +@item +Specification statements following first @code{DATA} statement. + +(In the GNU Fortran language, @samp{DATA I/1/} may be followed by @samp{INTEGER J}, +but not @samp{INTEGER I}. +The @samp{-fpedantic} option disallows both of these.) + +@item +Semicolon as statement separator, as in: + +@example +CALL FOO; CALL BAR +@end example +@c +@c @item +@c Comma before list of I/O items in @code{WRITE} +@c @c, @code{ENCODE}, @code{DECODE}, and @code{REWRITE} +@c statements, as with @code{READ} (as explained above). + +@item +Use of @samp{&} in column 1 of fixed-form source (to indicate continuation). + +@item +Use of @code{CHARACTER} constants to initialize numeric entities, and vice +versa. + +@item +Expressions having two arithmetic operators in a row, such +as @samp{X*-Y}. +@end itemize + +If @samp{-fpedantic} is specified along with @samp{-ff90}, the +following constructs result in diagnostics: + +@itemize @bullet +@item +Use of semicolon as a statement separator on a line +that has an @code{INCLUDE} directive. +@end itemize + +@node Distensions +@section Distensions +@cindex distensions +@cindex ugly features +@cindex features, ugly + +The @samp{-fugly-*} command-line options determine whether certain +features supported by VAX FORTRAN and other such compilers, but considered +too ugly to be in code that can be changed to use safer and/or more +portable constructs, are accepted. +These are humorously referred to as ``distensions'', +extensions that just plain look ugly in the harsh light of day. + +@emph{Note:} The @samp{-fugly} option, which currently serves +as shorthand to enable all of the distensions below, is likely to +be removed in a future version of @code{g77}. +That's because it's likely new distensions will be added that +conflict with existing ones in terms of assigning meaning to +a given chunk of code. +(Also, it's pretty clear that users should not use @samp{-fugly} +as shorthand when the next release of @code{g77} might add a +distension to that that causes their existing code, when recompiled, +to behave differently---perhaps even fail to compile or run +correctly.) + +@menu +* Ugly Implicit Argument Conversion:: Disabled via @samp{-fno-ugly-args}. +* Ugly Assumed-Size Arrays:: Enabled via @samp{-fugly-assumed}. +* Ugly Null Arguments:: Enabled via @samp{-fugly-comma}. +* Ugly Complex Part Extraction:: Enabled via @samp{-fugly-complex}. +* Ugly Conversion of Initializers:: Disabled via @samp{-fno-ugly-init}. +* Ugly Integer Conversions:: Enabled via @samp{-fugly-logint}. +* Ugly Assigned Labels:: Enabled via @samp{-fugly-assign}. +@end menu + +@node Ugly Implicit Argument Conversion +@subsection Implicit Argument Conversion +@cindex Hollerith constants +@cindex constants, Hollerith + +The @samp{-fno-ugly-args} option disables +passing typeless and Hollerith constants as actual arguments +in procedure invocations. +For example: + +@example +CALL FOO(4HABCD) +CALL BAR('123'O) +@end example + +@noindent +These constructs can be too easily used to create non-portable +code, but are not considered as ``ugly'' as others. +Further, they are widely used in existing Fortran source code +in ways that often are quite portable. +Therefore, they are enabled by default. + +@node Ugly Assumed-Size Arrays +@subsection Ugly Assumed-Size Arrays +@cindex arrays, assumed-size +@cindex assumed-size arrays +@cindex DIMENSION X(1) + +The @samp{-fugly-assumed} option enables +the treatment of any array with a final dimension specified as @samp{1} +as an assumed-size array, as if @samp{*} had been specified +instead. + +For example, @samp{DIMENSION X(1)} is treated as if it +had read @samp{DIMENSION X(*)} if @samp{X} is listed as +a dummy argument in a preceding @code{SUBROUTINE}, @code{FUNCTION}, +or @code{ENTRY} statement in the same program unit. + +Use an explicit lower bound to avoid this interpretation. +For example, @samp{DIMENSION X(1:1)} is never treated as if +it had read @samp{DIMENSION X(*)} or @samp{DIMENSION X(1:*)}. +Nor is @samp{DIMENSION X(2-1)} affected by this option, +since that kind of expression is unlikely to have been +intended to designate an assumed-size array. + +This option is used to prevent warnings being issued about apparent +out-of-bounds reference such as @samp{X(2) = 99}. + +It also prevents the array from being used in contexts that +disallow assumed-size arrays, such as @samp{PRINT *,X}. +In such cases, a diagnostic is generated and the source file is +not compiled. + +The construct affected by this option is used only in old code +that pre-exists the widespread acceptance of adjustable and assumed-size +arrays in the Fortran community. + +@emph{Note:} This option does not affect how @samp{DIMENSION X(1)} is +treated if @samp{X} is listed as a dummy argument only +@emph{after} the @code{DIMENSION} statement (presumably in +an @code{ENTRY} statement). +For example, @samp{-fugly-assumed} has no effect on the +following program unit: + +@example +SUBROUTINE X +REAL A(1) +RETURN +ENTRY Y(A) +PRINT *, A +END +@end example + +@node Ugly Complex Part Extraction +@subsection Ugly Complex Part Extraction +@cindex complex values +@cindex real part +@cindex imaginary part + +The @samp{-fugly-complex} option enables +use of the @code{REAL()} and @code{AIMAG()} +intrinsics with arguments that are +@code{COMPLEX} types other than @code{COMPLEX(KIND=1)}. + +With @samp{-ff90} in effect, these intrinsics return +the unconverted real and imaginary parts (respectively) +of their argument. + +With @samp{-fno-f90} in effect, these intrinsics convert +the real and imaginary parts to @code{REAL(KIND=1)}, and return +the result of that conversion. + +Due to this ambiguity, the GNU Fortran language defines +these constructs as invalid, except in the specific +case where they are entirely and solely passed as an +argument to an invocation of the @code{REAL()} intrinsic. +For example, + +@example +REAL(REAL(Z)) +@end example + +@noindent +is permitted even when @samp{Z} is @code{COMPLEX(KIND=2)} +and @samp{-fno-ugly-complex} is in effect, because the +meaning is clear. + +@code{g77} enforces this restriction, unless @samp{-fugly-complex} +is specified, in which case the appropriate interpretation is +chosen and no diagnostic is issued. + +@xref{CMPAMBIG}, for information on how to cope with existing +code with unclear expectations of @code{REAL()} and @code{AIMAG()} +with @code{COMPLEX(KIND=2)} arguments. + +@xref{RealPart Intrinsic}, for information on the @code{REALPART()} +intrinsic, used to extract the real part of a complex expression +without conversion. +@xref{ImagPart Intrinsic}, for information on the @code{IMAGPART()} +intrinsic, used to extract the imaginary part of a complex expression +without conversion. + +@node Ugly Null Arguments +@subsection Ugly Null Arguments +@cindex trailing commas +@cindex commas, trailing +@cindex null arguments +@cindex arguments, null + +The @samp{-fugly-comma} option enables +use of a single trailing comma to mean ``pass an extra trailing null +argument'' in a list of actual arguments to a procedure other than a +statement function, and use of an empty list of arguments to +mean ``pass a single null argument''. + +@cindex omitting arguments +@cindex arguments, omitting +(Null arguments often are used in some procedure-calling +schemes to indicate omitted arguments.) + +For example, @samp{CALL FOO(,)} means ``pass +two null arguments'', rather than ``pass one null argument''. +Also, @samp{CALL BAR()} means ``pass one null argument''. + +This construct is considered ``ugly'' because it does not +provide an elegant way to pass a single null argument +that is syntactically distinct from passing no arguments. +That is, this construct changes the meaning of code that +makes no use of the construct. + +So, with @samp{-fugly-comma} in force, @samp{CALL FOO()} +and @samp{I = JFUNC()} pass a single null argument, instead +of passing no arguments as required by the Fortran 77 and +90 standards. + +@emph{Note:} Many systems gracefully allow the case +where a procedure call passes one extra argument that the +called procedure does not expect. + +So, in practice, there might be no difference in +the behavior of a program that does @samp{CALL FOO()} +or @samp{I = JFUNC()} and is compiled with @samp{-fugly-comma} +in force as compared to its behavior when compiled +with the default, @samp{-fno-ugly-comma}, in force, +assuming @samp{FOO} and @samp{JFUNC} do not expect any +arguments to be passed. + +@node Ugly Conversion of Initializers +@subsection Ugly Conversion of Initializers + +The constructs disabled by @samp{-fno-ugly-init} are: + +@itemize @bullet +@cindex Hollerith constants +@cindex constants, Hollerith +@item +Use of Hollerith and typeless constants in contexts where they set +initial (compile-time) values for variables, arrays, and named +constants---that is, @code{DATA} and @code{PARAMETER} statements, plus +type-declaration statements specifying initial values. + +Here are some sample initializations that are disabled by the +@samp{-fno-ugly-init} option: + +@example +PARAMETER (VAL='9A304FFE'X) +REAL*8 STRING/8HOUTPUT00/ +DATA VAR/4HABCD/ +@end example + +@cindex character constants +@cindex constants, character +@item +In the same contexts as above, use of character constants to initialize +numeric items and vice versa (one constant per item). + +Here are more sample initializations that are disabled by the +@samp{-fno-ugly-init} option: + +@example +INTEGER IA +CHARACTER BELL +PARAMETER (IA = 'A') +PARAMETER (BELL = 7) +@end example + +@item +Use of Hollerith and typeless constants on the right-hand side +of assignment statements to numeric types, and in other +contexts (such as passing arguments in invocations of +intrinsic procedures and statement functions) that +are treated as assignments to known types (the dummy +arguments, in these cases). + +Here are sample statements that are disabled by the +@samp{-fno-ugly-init} option: + +@example +IVAR = 4HABCD +PRINT *, IMAX0(2HAB, 2HBA) +@end example +@end itemize + +The above constructs, when used, +can tend to result in non-portable code. +But, they are widely used in existing Fortran code in ways +that often are quite portable. +Therefore, they are enabled by default. + +@node Ugly Integer Conversions +@subsection Ugly Integer Conversions + +The constructs enabled via @samp{-fugly-logint} are: + +@itemize @bullet +@item +Automatic conversion between @code{INTEGER} and @code{LOGICAL} as +dictated by +context (typically implies nonportable dependencies on how a +particular implementation encodes @code{.TRUE.} and @code{.FALSE.}). + +@item +Use of a @code{LOGICAL} variable in @code{ASSIGN} and assigned-@code{GOTO} +statements. +@end itemize + +The above constructs are disabled by default because use +of them tends to lead to non-portable code. +Even existing Fortran code that uses that often turns out +to be non-portable, if not outright buggy. + +Some of this is due to differences among implementations as +far as how @code{.TRUE.} and @code{.FALSE.} are encoded as +@code{INTEGER} values---Fortran code that assumes a particular +coding is likely to use one of the above constructs, and is +also likely to not work correctly on implementations using +different encodings. + +@xref{Equivalence Versus Equality}, for more information. + +@node Ugly Assigned Labels +@subsection Ugly Assigned Labels +@cindex ASSIGN statement +@cindex statements, ASSIGN +@cindex assigned labels +@cindex pointers + +The @samp{-fugly-assign} option forces @code{g77} to use the +same storage for assigned labels as it would for a normal +assignment to the same variable. + +For example, consider the following code fragment: + +@example +I = 3 +ASSIGN 10 TO I +@end example + +@noindent +Normally, for portability and improved diagnostics, @code{g77} +reserves distinct storage for a ``sibling'' of @samp{I}, used +only for @code{ASSIGN} statements to that variable (along with +the corresponding assigned-@code{GOTO} and assigned-@samp{FORMAT}-I/O +statements that reference the variable). + +However, some code (that violates the ANSI FORTRAN 77 standard) +attempts to copy assigned labels among variables involved with +@code{ASSIGN} statements, as in: + +@example +ASSIGN 10 TO I +ISTATE(5) = I +@dots{} +J = ISTATE(ICUR) +GOTO J +@end example + +@noindent +Such code doesn't work under @code{g77} unless @samp{-fugly-assign} +is specified on the command-line, ensuring that the value of @code{I} +referenced in the second line is whatever value @code{g77} uses +to designate statement label @samp{10}, so the value may be +copied into the @samp{ISTATE} array, later retrieved into a +variable of the appropriate type (@samp{J}), and used as the target of +an assigned-@code{GOTO} statement. + +@emph{Note:} To avoid subtle program bugs, +when @samp{-fugly-assign} is specified, +@code{g77} requires the type of variables +specified in assigned-label contexts +@emph{must} be the same type returned by @code{%LOC()}. +On many systems, this type is effectively the same +as @code{INTEGER(KIND=1)}, while, on others, it is +effectively the same as @code{INTEGER(KIND=2)}. + +Do @emph{not} depend on @code{g77} actually writing valid pointers +to these variables, however. +While @code{g77} currently chooses that implementation, it might +be changed in the future. + +@xref{Assigned Statement Labels,,Assigned Statement Labels (ASSIGN and GOTO)}, +for implementation details on assigned-statement labels. + +@node Compiler +@chapter The GNU Fortran Compiler + +The GNU Fortran compiler, @code{g77}, supports programs written +in the GNU Fortran language and in some other dialects of Fortran. + +Some aspects of how @code{g77} works are universal regardless +of dialect, and yet are not properly part of the GNU Fortran +language itself. +These are described below. + +@emph{Note: This portion of the documentation definitely needs a lot +of work!} + +@menu +* Compiler Types:: +* Compiler Constants:: +* Compiler Intrinsics:: +@end menu + +@node Compiler Types +@section Compiler Types +@cindex types, of data +@cindex data types + +Fortran implementations have a fair amount of freedom given them by the +standard as far as how much storage space is used and how much precision +and range is offered by the various types such as @code{LOGICAL(KIND=1)}, +@code{INTEGER(KIND=1)}, @code{REAL(KIND=1)}, @code{REAL(KIND=2)}, +@code{COMPLEX(KIND=1)}, and @code{CHARACTER}. +Further, many compilers offer so-called @samp{*@var{n}} notation, but +the interpretation of @var{n} varies across compilers and target architectures. + +The standard requires that @code{LOGICAL(KIND=1)}, @code{INTEGER(KIND=1)}, +and @code{REAL(KIND=1)} +occupy the same amount of storage space, and that @code{COMPLEX(KIND=1)} +and @code{REAL(KIND=2)} take twice as much storage space as @code{REAL(KIND=1)}. +Further, it requires that @code{COMPLEX(KIND=1)} +entities be ordered such that when a @code{COMPLEX(KIND=1)} variable is +storage-associated (such as via @code{EQUIVALENCE}) +with a two-element @code{REAL(KIND=1)} array named @samp{R}, @samp{R(1)} +corresponds to the real element and @samp{R(2)} to the imaginary +element of the @code{COMPLEX(KIND=1)} variable. + +(Few requirements as to precision or ranges of any of these are +placed on the implementation, nor is the relationship of storage sizes of +these types to the @code{CHARACTER} type specified, by the standard.) + +@code{g77} follows the above requirements, warning when compiling +a program requires placement of items in memory that contradict the +requirements of the target architecture. +(For example, a program can require placement of a @code{REAL(KIND=2)} +on a boundary that is not an even multiple of its size, but still an +even multiple of the size of a @code{REAL(KIND=1)} variable. +On some target architectures, using the canonical +mapping of Fortran types to underlying architectural types, such +placement is prohibited by the machine definition or +the Application Binary Interface (ABI) in force for +the configuration defined for building @code{gcc} and @code{g77}. +@code{g77} warns about such +situations when it encounters them.) + +@code{g77} follows consistent rules for configuring the mapping between Fortran +types, including the @samp{*@var{n}} notation, and the underlying architectural +types as accessed by a similarly-configured applicable version of the +@code{gcc} compiler. +These rules offer a widely portable, consistent Fortran/C +environment, although they might well conflict with the expectations of +users of Fortran compilers designed and written for particular +architectures. + +These rules are based on the configuration that is in force for the +version of @code{gcc} built in the same release as @code{g77} (and +which was therefore used to build both the @code{g77} compiler +components and the @code{libf2c} run-time library): + +@table @code +@cindex REAL(KIND=1) type +@cindex types, REAL(KIND=1) +@item REAL(KIND=1) +Same as @code{float} type. + +@cindex REAL(KIND=2) type +@cindex types, REAL(KIND=2) +@item REAL(KIND=2) +Same as whatever floating-point type that is twice the size +of a @code{float}---usually, this is a @code{double}. + +@cindex INTEGER(KIND=1) type +@cindex types, INTEGER(KIND=1) +@item INTEGER(KIND=1) +Same as an integral type that is occupies the same amount +of memory storage as @code{float}---usually, this is either +an @code{int} or a @code{long int}. + +@cindex LOGICAL(KIND=1) type +@cindex types, LOGICAL(KIND=1) +@item LOGICAL(KIND=1) +Same @code{gcc} type as @code{INTEGER(KIND=1)}. + +@cindex INTEGER(KIND=2) type +@cindex types, INTEGER(KIND=2) +@item INTEGER(KIND=2) +Twice the size, and usually nearly twice the range, +as @code{INTEGER(KIND=1)}---usually, this is either +a @code{long int} or a @code{long long int}. + +@cindex LOGICAL(KIND=2) type +@cindex types, LOGICAL(KIND=2) +@item LOGICAL(KIND=2) +Same @code{gcc} type as @code{INTEGER(KIND=2)}. + +@cindex INTEGER(KIND=3) type +@cindex types, INTEGER(KIND=3) +@item INTEGER(KIND=3) +Same @code{gcc} type as signed @code{char}. + +@cindex LOGICAL(KIND=3) type +@cindex types, LOGICAL(KIND=3) +@item LOGICAL(KIND=3) +Same @code{gcc} type as @code{INTEGER(KIND=3)}. + +@cindex INTEGER(KIND=6) type +@cindex types, INTEGER(KIND=6) +@item INTEGER(KIND=6) +Twice the size, and usually nearly twice the range, +as @code{INTEGER(KIND=3)}---usually, this is +a @code{short}. + +@cindex LOGICAL(KIND=6) type +@cindex types, LOGICAL(KIND=6) +@item LOGICAL(KIND=6) +Same @code{gcc} type as @code{INTEGER(KIND=6)}. + +@cindex COMPLEX(KIND=1) type +@cindex types, COMPLEX(KIND=1) +@item COMPLEX(KIND=1) +Two @code{REAL(KIND=1)} scalars (one for the real part followed by +one for the imaginary part). + +@cindex COMPLEX(KIND=2) type +@cindex types, COMPLEX(KIND=2) +@item COMPLEX(KIND=2) +Two @code{REAL(KIND=2)} scalars. + +@cindex *@var{n} notation +@item @var{numeric-type}*@var{n} +(Where @var{numeric-type} is any type other than @code{CHARACTER}.)@ +Same as whatever @code{gcc} type occupies @var{n} times the storage +space of a @code{gcc} @code{char} item. + +@cindex DOUBLE PRECISION type +@cindex types, DOUBLE PRECISION +@item DOUBLE PRECISION +Same as @code{REAL(KIND=2)}. + +@cindex DOUBLE COMPLEX type +@cindex types, DOUBLE COMPLEX +@item DOUBLE COMPLEX +Same as @code{COMPLEX(KIND=2)}. +@end table + +Note that the above are proposed correspondences and might change +in future versions of @code{g77}---avoid writing code depending +on them. + +Other types supported by @code{g77} +are derived from gcc types such as @code{char}, @code{short}, +@code{int}, @code{long int}, @code{long long int}, @code{long double}, +and so on. +That is, whatever types @code{gcc} already supports, @code{g77} supports +now or probably will support in a future version. +The rules for the @samp{@var{numeric-type}*@var{n}} notation +apply to these types, +and new values for @samp{@var{numeric-type}(KIND=@var{n})} will be +assigned in a way that encourages clarity, consistency, and portability. + +@node Compiler Constants +@section Compiler Constants +@cindex constants +@cindex types, constants + +@code{g77} strictly assigns types to @emph{all} constants not +documented as ``typeless'' (typeless constants including @samp{'1'Z}, +for example). +Many other Fortran compilers attempt to assign types to typed constants +based on their context. +This results in hard-to-find bugs, nonportable +code, and is not in the spirit (though it strictly follows the letter) +of the 77 and 90 standards. + +@code{g77} might offer, in a future release, explicit constructs by +which a wider variety of typeless constants may be specified, and/or +user-requested warnings indicating places where @code{g77} might differ +from how other compilers assign types to constants. + +@xref{Context-Sensitive Constants}, for more information on this issue. + +@node Compiler Intrinsics +@section Compiler Intrinsics + +@code{g77} offers an ever-widening set of intrinsics. +Currently these all are procedures (functions and subroutines). + +Some of these intrinsics are unimplemented, but their names reserved +to reduce future problems with existing code as they are implemented. +Others are implemented as part of the GNU Fortran language, while +yet others are provided for compatibility with other dialects of +Fortran but are not part of the GNU Fortran language. + +To manage these distinctions, @code{g77} provides intrinsic @emph{groups}, +a facility that is simply an extension of the intrinsic groups provided +by the GNU Fortran language. + +@menu +* Intrinsic Groups:: How intrinsics are grouped for easy management. +* Other Intrinsics:: Intrinsics other than those in the GNU + Fortran language. +@end menu + +@node Intrinsic Groups +@subsection Intrinsic Groups @cindex groups of intrinsics @cindex intrinsics, groups A given specific intrinsic belongs in one or more groups. -Each group -is deleted, disabled, hidden, or enabled by default or a command-line -option. The meaning of each term follows. +Each group is deleted, disabled, hidden, or enabled +by default or a command-line option. +The meaning of each term follows. @table @b @cindex deleted intrinsics @@ -4167,7 +7228,7 @@ No intrinsics are recognized as belonging to that group. @cindex intrinsics, disabled @item Disabled Intrinsics are recognized as belonging to the group, but -references to them (other than via the @samp{INTRINSIC} statement) +references to them (other than via the @code{INTRINSIC} statement) are disallowed through that group. @cindex hidden intrinsics @@ -4175,7 +7236,7 @@ are disallowed through that group. @item Hidden Intrinsics in that group are recognized and enabled (if implemented) @emph{only} if the first mention of the actual name of an intrinsic -in a program unit is in an @samp{INTRINSIC} statement. +in a program unit is in an @code{INTRINSIC} statement. @cindex enabled intrinsics @cindex intrinsics, enabled @@ -4213,14 +7274,14 @@ that group do not exist at all, whereas disabling it tells @code{g77} to recognize them as (disabled) intrinsics in intrinsic-like contexts. Hiding a group is like enabling it, but the intrinsic must be first -named in an @samp{INTRINSIC} statement to be considered a reference to the +named in an @code{INTRINSIC} statement to be considered a reference to the intrinsic rather than to an external procedure. This might be the ``safest'' way to treat a new group of intrinsics when compiling old code, because it allows the old code to be generally written as if those new intrinsics never existed, but to be changed to use them -by inserting @samp{INTRINSIC} statements in the appropriate places. -However, it should be the goal of development to use @samp{EXTERNAL} +by inserting @code{INTRINSIC} statements in the appropriate places. +However, it should be the goal of development to use @code{EXTERNAL} for all names of external procedures that might be intrinsic names. If an intrinsic is in more than one group, it is enabled if any of its @@ -4229,7 +7290,7 @@ any of its containing groups are hidden; if not so hidden, it is disabled if any of its containing groups are disabled; if not so disabled, it is deleted. This extra complication is necessary because some intrinsics, -such as @samp{IBITS}, belong to more than one group, and hence should be +such as @code{IBITS}, belong to more than one group, and hence should be enabled if any of the groups to which they belong are enabled, and so on. @@ -4238,84 +7299,61 @@ The groups are: @cindex intrinsics, groups of @cindex groups of intrinsics @table @code -@item dcp -@samp{DOUBLE COMPLEX} intrinsics from the standards (F77, F90). +@item gnu +Intrinsics the GNU Fortran language supports that are extensions to +the Fortran standards (77 and 90). + @item f2c Intrinsics supported by AT&T's @code{f2c} converter and/or @code{libf2c}. + @item f90 Fortran 90 intrinsics. + @item mil -MIL-STD 1753 intrinsics (@samp{MVBITS}, @samp{IAND}, @samp{BTEST}, and so on). +MIL-STD 1753 intrinsics (@code{MVBITS}, @code{IAND}, @code{BTEST}, and so on). + @item unix -UNIX intrinsics (@samp{IARGC}, @samp{EXIT}, @samp{ERF}, and so on). +UNIX intrinsics (@code{IARGC}, @code{EXIT}, @code{ERF}, and so on). + @item vxt VAX/VMS FORTRAN (current as of v4) intrinsics. @end table -@node Dialects -@section GNU Fortran Dialects -@cindex language dialects -@cindex dialects of language -@cindex Fortran 90 features -@cindex VXT features - -The @samp{-fvxt-not-f90} and @samp{-ff90-not-vxt} command-line options -control how @code{g77} interprets certain tokens and constructs that -have different meanings in VAX FORTRAN (circa v4) and Fortran 90. -@cindex VXT extensions -@cindex extensions, VXT -(Generally, this manual uses the invented acronym VXT to refer -to many popular VAX FORTRAN extensions, though not necessarily -those that are specific to the VAX processor architecture or the -VMS operating system. -An extension offered by a Digital Fortran product that also is -offered by several other Fortran products for different kinds of -systems is probably going to be considered for inclusion in @code{g77} -someday, and is considered a VXT extension.) +@node Other Intrinsics +@subsection Other Intrinsics +@cindex intrinsics, others +@cindex other intrinsics -When @samp{-ff90-not-vxt} is specified, the following interpretations are made -(and, when @samp{-fvxt-not-f90} is in effect, the opposite interpretations -are made): +@code{g77} supports intrinsics other than those in the GNU Fortran +language proper. +This set of intrinsics is described below. -@itemize @bullet -@cindex double quotes -@cindex character constants -@cindex constants, character -@cindex octal constants -@cindex constants, octal -@item -Double-quote character (@samp{"}) delimits character constant just as does -apostrophe (@samp{'}), rather than beginning an octal constant of -@samp{INTEGER} type. - -@cindex exclamation points -@cindex continuation character -@cindex characters, continuation -@cindex comment character -@cindex characters, comment -@item -An exclamation point (@samp{!}) in column 5 of fixed-form source file -treated as a continuation character rather than the beginning of a comment -(as it does in any other column). +@ifinfo +(Note that the blank lines appearing in the menu below +are not intentional---they result from a bug in the +@code{makeinfo} program.) +@end ifinfo -@cindex TYPE statement -@cindex statements, TYPE -@item -@samp{TYPE FOO} and @samp{TYPE (FOO), BAR} -statements are recognized as the Fortran 90 variety, not I/O statements. -(However, the F90 variety is @emph{not} supported, so this really just -ensures that @code{g77} will produce a diagnostic instead of trying to -implement the VXT @samp{TYPE} statement---which currently is not supported -either.) -@end itemize +@c The actual documentation for intrinsics comes from +@c intdoc.texi, which in turn is automatically generated +@c from the internal g77 tables in intrin.def _and_ the +@c largely hand-written text in intdoc.h. So, if you want +@c to change or add to existing documentation on intrinsics, +@c you probably want to edit intdoc.h. +@c +@clear familyF77 +@clear familyGNU +@clear familyASC +@clear familyMIL +@clear familyF90 +@set familyVXT +@set familyFVZ +@clear familyF2C +@clear familyF2U +@include intdoc.texi -@node Object Compatibility -@section Object Compatibility -@cindex object code -@cindex code, object -@cindex compatibility, @code{f2c} -@cindex f2c compatibility -@cindex compilers, compatibility +@node Other Compilers +@chapter Other Compilers An individual Fortran source file can be compiled to an object (@file{*.o}) file instead of to the final @@ -4326,7 +7364,7 @@ version of the program is needed. However, it introduces the issue of @dfn{object compatibility} across the various object files (and libraries, or @file{*.a} files) that are linked together to produce any particular -exectable file. +executable file. Object compatibility is an issue when combining, in one program, Fortran code compiled by more than one compiler @@ -4336,7 +7374,7 @@ disagree on how to transform the names of procedures, there will normally be errors when linking such programs. Worse, if the compilers agree on naming, but disagree on issues like how to pass parameters, return arguments, and lay out -@samp{COMMON} areas, the earliest detected errors might be the +@code{COMMON} areas, the earliest detected errors might be the incorrect results produced by the program (and that assumes these errors are detected, which is not always the case). @@ -4351,8 +7389,8 @@ to @code{f2c} internals, will produce object files that are incompatible with @code{g77}.) For example, a Fortran string subroutine -argument will become two arguments on the C side: a @samp{char *} -and an @samp{int} length. +argument will become two arguments on the C side: a @code{char *} +and an @code{int} length. Much of this compatibility results from the fact that @code{g77} uses the same run-time library, @code{libf2c}, used by @@ -4363,31 +7401,34 @@ is object-compatible with @code{libf2c} and current @code{g77}, and some might offer such compatibility only when explicitly selected via a command-line option to the compiler. +@emph{Note: This portion of the documentation definitely needs a lot +of work!} + @menu * Dropping f2c Compatibility:: When speed is more important. -* Other Compilers:: Interoperation with code from other compilers. +* Compilers Other Than f2c:: Interoperation with code from other compilers. @end menu @node Dropping f2c Compatibility -@subsection Dropping f2c Compatibility +@section Dropping @code{f2c} Compatibility Specifying @samp{-fno-f2c} allows @code{g77} to generate, in some cases, faster code, by not needing to allow to the possibility of linking with code compiled by @code{f2c}. -For example, this affects how @samp{REAL}, @samp{COMPLEX}, and -@samp{DOUBLE COMPLEX} functions are called. +For example, this affects how @code{REAL(KIND=1)}, +@code{COMPLEX(KIND=1)}, and @code{COMPLEX(KIND=2)} functions are called. With @samp{-fno-f2c}, they are compiled as returning the appropriate @code{gcc} type -(@samp{float}, @samp{__complex__ float}, @samp{__complex__ double}, +(@code{float}, @code{__complex__ float}, @code{__complex__ double}, in many configurations). With @samp{-ff2c} in force, they are compiled differently (with perhaps slower run-time performance) to accommodate the restrictions inherent in @code{f2c}'s use of K&R -C as an intermediate language---@samp{REAL} functions return double, -while @samp{COMPLEX} functions return -@samp{void} and use an extra argument pointing to a place for the functions to +C as an intermediate language---@code{REAL(KIND=1)} functions +return C's @code{double} type, while @code{COMPLEX} functions return +@code{void} and use an extra argument pointing to a place for the functions to return their values. It is possible that, in some cases, leaving @samp{-ff2c} in force @@ -4418,23 +7459,22 @@ carefully watch for any announcements about changes to the (thus requiring recompilation). It is probable that a future version of @code{g77} will not, -by default, generate object files compatible with @code{f2c} and not -use @code{libf2c}. +by default, generate object files compatible with @code{f2c}, +and that version probably would no longer use @code{libf2c}. If you expect to depend on this compatibility in the long term, use the options @samp{-ff2c -ff2c-library} when compiling all of the applicable code. -This should either cause @code{g77} to produce compatible code -(at the expense of the availability of some features and -performance), or at the very least trigger -compiler warning messages, in future versions of @code{g77}. +This should cause future versions of @code{g77} either to produce +compatible code (at the expense of the availability of some features and +performance), or at the very least, to produce diagnostics. -@node Other Compilers -@subsection Other Compilers +@node Compilers Other Than f2c +@section Compilers Other Than @code{f2c} On systems with Fortran compilers other than @code{f2c} and @code{g77}, code compiled by @code{g77} is not expected to work well with code compiled by the native compiler. -(This is true for @code{f2c}-compiled objects as well.) +(This is true for @code{f2c}-compiled objects as well.)@ Libraries compiled with the native compiler probably will have to be recompiled with @code{g77} to be used with @code{g77}-compiled code. @@ -4474,221 +7514,159 @@ would have to add @samp{-L/usr/lang/SCx.x -lF77 -lV77} to the link command. @end itemize -@node Distensions -@section Distensions -@cindex distensions -@cindex ugly features -@cindex features, ugly +@node Other Languages +@chapter Other Languages -The @samp{-fugly-*} command-line options determine whether certain -features supported by VAX FORTRAN and other such compilers, but considered -too ugly to be in code that can be changed to use safer and/or more -portable constructs, are accepted. -These are humorously referred to as ``distensions'', -extensions that just plain look ugly in the harsh light of day. +@emph{Note: This portion of the documentation definitely needs a lot +of work!} @menu -* Ugly Implicit Argument Conversion:: Disabled via @samp{-fno-ugly-args}. -* Ugly Assumed-Size Arrays:: Enabled via @samp{-fugly-assumed}. -* Ugly Null Arguments:: Enabled via @samp{-fugly-comma}. -* Ugly Conversion of Initializers:: Disabled via @samp{-fno-ugly-init}. -* Ugly Integer Conversions:: Enabled via @samp{-fugly-logint}. +* Interoperating with C and C++:: @end menu -@node Ugly Implicit Argument Conversion -@subsection Implicit Argument Conversion - -The construct disabled via @samp{-fno-ugly-args} is: - -@itemize @bullet -@cindex Hollerith constants -@cindex constants, Hollerith -@item -Passing of typeless and Hollerith constants as actual arguments -in procedure invocations. - -For example, @samp{CALL FOO(4HABCD)}. - -This construct can be too easily used to create non-portable -code, but is not considered as ``ugly'' as others. -Further, it is widely used in existing Fortran source code -in ways that often are quite portable. -Therefore, it is enabled by default. -@end itemize - -@cindex arrays, assumed-size -@cindex assumed-size arrays -@cindex DIMENSION X(1) -@node Ugly Assumed-Size Arrays -@subsection Ugly Assumed-Size Arrays - -The construct enabled via @samp{-fugly-assumed} is: - -@itemize @bullet -@item -Treatment of any array with a final dimension specified as @samp{1} -as an assumed-size array, as if @samp{*} had been specified -instead. - -For example, @samp{DIMENSION X(1)} is treated as if it -had read @samp{DIMENSION X(*)}. - -Use an explicit lower bound to avoid this interpretation. -For example, @samp{DIMENSION X(1:1)} is never treated as if -it had read @samp{DIMENSION X(*)} or @samp{DIMENSION X(1:*)}. - -This option prevents a warning being issued about an apparent -out-of-bounds reference such as @samp{X(2) = 99}. - -It also prevents the array from being used in contexts that -disallow assumed-size arrays, such as @samp{PRINT *,X}. - -This construct is used only in very old code that pre-exists -the widespread acceptance of adjustable and assumed-size -arrays in the Fortran community. -@end itemize - -@cindex trailing commas -@cindex commas, trailing -@cindex null arguments -@cindex arguments, null -@node Ugly Null Arguments -@subsection Ugly Null Arguments - -The construct enabled via @samp{-fugly-comma} is: - -@itemize @bullet -@item -Use of a single trailing comma to mean ``pass an extra trailing null -argument'' in a list of actual arguments to a procedure other than a -statement function, and an empty list of arguments to -mean ``pass a single null argument''. - -@cindex omitting arguments -@cindex arguments, omitting -(Null arguments often are used in some procedure-calling -schemes to indicate omitted arguments.) - -For example, @samp{CALL FOO(,)} means ``pass -two null arguments'', rather than ``pass one null argument''. -Also, @samp{CALL BAR()} means ``pass one null argument''. - -This construct is considered ``ugly'' because it does not -provide an elegant way to pass a single null argument -that is syntactically distinct from passing no arguments. -That is, this construct changes the meaning of code that -makes no use of the construct. - -So, with @samp{-fugly-comma} in force, @samp{CALL FOO()} -and @samp{I = JFUNC()} pass a single null argument, instead -of passing no arguments as required by the Fortran 77 and -90 standards. - -@emph{Note:} Many systems gracefully allow the case -where a procedure call passes one extra argument that the -called procedure does not expect. - -So, in practice, there might be no difference in -the behavior of a program that does @samp{CALL FOO()} -or @samp{I = JFUNC()} and is compiled with @samp{-fugly-comma} -in force as compared to its behavior when compiled -with the default, @samp{-fno-ugly-comma}, in force, -assuming @samp{FOO} and @samp{JFUNC} do not expect any -arguments to be passed. -@end itemize - -@node Ugly Conversion of Initializers -@subsection Ugly Conversion of Initializers - -The constructs disabled by @samp{-fno-ugly-init} are: - -@itemize @bullet -@cindex Hollerith constants -@cindex constants, Hollerith -@item -Use of Hollerith and typeless constants in contexts where they set -initial (compile-time) values for variables, arrays, and named -constants---that is, @samp{DATA} and @samp{PARAMETER} statements, plus -type-declaration statements specifying initial values. - -Here are some sample initializations that are disabled by the -@samp{-fno-ugly-init} option: - -@example -PARAMETER (VAL='9A304FFE'X) -REAL*8 STRING/8HOUTPUT00/ -DATA VAR/4HABCD/ -@end example - -@cindex character constants -@cindex constants, character -@item -In the same contexts as above, use of character constants to initialize -numeric items and vice versa (one constant per item). - -Here are more sample initializations that are disabled by the -@samp{-fno-ugly-init} option: - -@example -INTEGER IA -CHARACTER BELL -PARAMETER (IA = 'A') -PARAMETER (BELL = 7) -@end example - -@item -Use of Hollerith and typeless constants on the right-hand side -of assignment statements to numeric types, and in other -contexts (such as passing arguments in invocations of -intrinsic procedures and statement functions) that -are treated as assignments to known types (the dummy -arguments, in these cases). - -Here are sample statements that are disabled by the -@samp{-fno-ugly-init} option: - -@example -IVAR = 4HABCD -PRINT *, IMAX0(2HAB, 2HBA) -@end example -@end itemize - -The above constructs, when used, -can tend to result in non-portable code. -But, they are widely used in existing Fortran code in ways -that often are quite portable. -Therefore, they are enabled by default. - -@node Ugly Integer Conversions -@subsection Ugly Integer Conversions +@node Interoperating with C and C++ +@section Tools and advice for interoperating with C and C++ + +@cindex C, linking with +@cindex C++, linking with +@cindex linking with C +The following discussion assumes that you are running @code{g77} in @code{f2c} +compatibility mode, i.e.@ not using @samp{-fno-f2c}. +It provides some +advice about quick and simple techniques for linking Fortran and C (or +C++), the most common requirement. +For the full story consult the +description of code generation. +@xref{Debugging and Interfacing}. + +When linking Fortran and C, it's usually best to use @code{g77} to do +the linking so that the correct libraries are included (including the +maths one). +If you're linking with C++ you will want to add +@samp{-lstdc++}, @samp{-lg++} or whatever. +If you need to use another +driver program (or @code{ld} directly), +you can find out what linkage +options @code{g77} passes by running @samp{g77 -v}. -The constructs enabled via @samp{-fugly-logint} are: - -@itemize @bullet -@item -Automatic conversion between @samp{INTEGER} and @samp{LOGICAL} as -dictated by -context (typically implies nonportable dependencies on how a -particular implementation encodes @samp{.TRUE.} and @samp{.FALSE.}). - -@item -Use of a @samp{LOGICAL} variable in @samp{ASSIGN} and assigned-@samp{GOTO} -statements. -@end itemize - -The above constructs are disabled by default because use -of them tends to lead to non-portable code. -Even existing Fortran code that uses that often turns out -to be non-portable, if not outright buggy. - -Some of this is due to differences among implementations as -far as how @samp{.TRUE.} and @samp{.FALSE.} are encoded as -@samp{INTEGER} values---Fortran code that assumes a particular -coding is likely to use one of the above constructs, and is -also likely to not work correctly on implementations using -different encodings. +@menu +* C Interfacing Tools:: +* C Access to Type Information:: +* f2c Skeletons and Prototypes:: +* C++ Considerations:: +* Startup Code:: +@end menu -@xref{Equivalence Versus Equality}, for more information. +@node C Interfacing Tools +@subsection C Interfacing Tools +@pindex f2c +@cindex cfortran.h +@cindex Netlib +Even if you don't actually use it as a compiler, @samp{f2c} from +@url{ftp://ftp.netlib.org/f2c/src}, can be a useful tool when you're +interfacing (linking) Fortran and C@. +@xref{f2c Skeletons and Prototypes,,Generating Skeletons and Prototypes with @code{f2c}}. + +To use @code{f2c} for this purpose you only need retrieve and +build the @file{src} directory from the distribution, consult the +@file{README} instructions there for machine-specifics, and install the +@code{f2c} program on your path. + +Something else that might be useful is @samp{cfortran.h} from +@url{ftp://zebra/desy.de/cfortran}. +This is a fairly general tool which +can be used to generate interfaces for calling in both directions +between Fortran and C@. +It can be used in @code{f2c} mode with +@code{g77}---consult its documentation for details. + +@node C Access to Type Information +@subsection Accessing Type Information in C + +@cindex types, Fortran/C +Generally, C code written to link with +@code{g77} code---calling and/or being +called from Fortran---should @samp{#include <f2c.h>} to define the C +versions of the Fortran types. +Don't assume Fortran @code{INTEGER} types +correspond to C @samp{int}s, for instance; instead, declare them as +@code{integer}, a type defined by @file{f2c.h}. +@file{f2c.h} is installed where @code{gcc} will find it by +default, assuming you use a copy of @code{gcc} compatible with +@code{g77}, probably built at the same time as @code{g77}. + +@node f2c Skeletons and Prototypes +@subsection Generating Skeletons and Prototypes with @code{f2c} + +@pindex f2c +@cindex -fno-second-underscore +A simple and foolproof way to write @code{g77}-callable C routines---e.g.@ to +interface with an existing library---is to write a file (named, for +example, @file{fred.f}) of dummy Fortran +skeletons comprising just the declaration of the routine(s) and dummy +arguments plus @samp{END} statements. +Then run @code{f2c} on file @file{fred.f} to produce @file{fred.c} +into which you can edit +useful code, confident the calling sequence is correct, at least. +(There are some errors otherwise commonly made in generating C +interfaces with f2c conventions, such as not using @code{doublereal} as +the return type of a @code{REAL} @code{FUNCTION}.) + +@pindex ftnchek +@code{f2c} also can help with calling Fortran from C, using its +@samp{-P} option to generate C prototypes appropriate for calling the +Fortran.@footnote{The files generated like this can also be used for +inter-unit consistency checking of dummy and actual arguments, although +the @samp{ftnchek} tool from @url{ftp://ftp.netlib.org/fortran} is +probably better for this purpose.} +If the Fortran code containing any +routines to be called from C is in file @file{joe.f}, use the command +@kbd{f2c -P joe.f} to generate the file @file{joe.P} containing +prototype information. +@code{#include} this in the C which has to call +the Fortran routines to make sure you get it right. + +@xref{Arrays,,Arrays (DIMENSION}, for information on the differences +between the way Fortran (including compilers like @code{g77}) and +C handle arrays. + +@node C++ Considerations +@subsection C++ Considerations + +@cindex C++ +@code{f2c} can be used to generate suitable code for compilation with a +C++ system using the @samp{-C++} option. +The important thing about linking @code{g77}-compiled +code with C++ is that the prototypes for the @code{g77} +routines must specify C linkage to avoid name mangling. +So, use an @samp{extern "C"} declaration. +@code{f2c}'s @samp{-C++} option will take care +of this when generating skeletons or prototype files as above, and also +avoid clashes with C++ reserved words in addition to those in C@. + +@node Startup Code +@subsection Startup Code + +@cindex startup code +@cindex runtime initialization +@cindex initialization, runtime +Unlike with some runtime systems, it shouldn't be necessary (unless there are +bugs) to use a Fortran main program to ensure the +runtime---specifically the i/o system---is initialized. +However, to use +the @code{g77} intrinsics @code{GETARG()} and @code{IARGC()} the +@code{main()} routine from the @file{libf2c} library must be used, either +explicitly or implicitly by using a Fortran main program. +This +@code{main()} program calls @code{MAIN__()} (where the names are C-type +@code{extern} names, i.e.@ not mangled). +You need to provide this +nullary procedure as the entry point for your C code if using +@file{libf2c}'s @code{main}. +In some cases it might be necessary to +provide a dummy version of this to avoid linkers complaining about +failure to resolve @code{MAIN__()} if linking against @file{libf2c} and +not using @code{main()} from it. @include install.texi @@ -4737,20 +7715,221 @@ are installed, because new versions can change the behaviors described in this section. @menu -* Names:: Naming of user-defined variables, procedures, etc. * Main Program Unit:: How @code{g77} compiles a main program unit. -* Arrays:: Dealing with (possibly multi-dimensional) arrays. * Procedures:: How @code{g77} constructs parameter lists for procedures. -* Adjustable Arrays:: Special consideration for adjustable arrays. -* Alternate Returns:: How @code{g77} handles alternate returns. * Functions:: Functions returning floating-point or character data. +* Names:: Naming of user-defined variables, procedures, etc. * Common Blocks:: Accessing common variables while debugging. -* Local Equivalence Areas:: Accessing @samp{EQUIVALENCE} while debugging. -* Alternate Entry Points:: How @code{g77} implements alternate @samp{ENTRY}. -* Assigned Statement Labels:: How @code{g77} handles @samp{ASSIGN}. +* Local Equivalence Areas:: Accessing @code{EQUIVALENCE} while debugging. +* Complex Variables:: How @code{g77} performs complex arithmetic. +* Arrays:: Dealing with (possibly multi-dimensional) arrays. +* Adjustable Arrays:: Special consideration for adjustable arrays. +* Alternate Entry Points:: How @code{g77} implements alternate @code{ENTRY}. +* Alternate Returns:: How @code{g77} handles alternate returns. +* Assigned Statement Labels:: How @code{g77} handles @code{ASSIGN}. +* Run-time Library Errors:: Meanings of some @code{IOSTAT=} values. @end menu +@node Main Program Unit +@section Main Program Unit (PROGRAM) +@cindex PROGRAM statement +@cindex statements, PROGRAM + +When @code{g77} compiles a main program unit, it gives it the public +procedure name @samp{MAIN__}. +The @code{libf2c} library has the actual @code{main()} procedure +as is typical of C-based environments, and +it is this procedure that performs some initial start-up +activity and then calls @samp{MAIN__}. + +Generally, @code{g77} and @code{libf2c} are designed so that you need not +include a main program unit written in Fortran in your program---it +can be written in C or some other language. +Especially for I/O handling, this is the case, although @code{g77} version 0.5.16 +includes a bug fix for @code{libf2c} that solved a problem with using the +@code{OPEN} statement as the first Fortran I/O activity in a program +without a Fortran main program unit. + +However, if you don't intend to use @code{g77} (or @code{f2c}) to compile +your main program unit---that is, if you intend to compile a @code{main()} +procedure using some other language---you should carefully +examine the code for @code{main()} in @code{libf2c}, found in the source +file @file{gcc/f/runtime/libF77/main.c}, to see what kinds of things +might need to be done by your @code{main()} in order to provide the +Fortran environment your Fortran code is expecting. + +@cindex IARGC() intrinsic +@cindex intrinsics, IARGC() +@cindex GETARG() intrinsic +@cindex intrinsics, GETARG() +For example, @code{libf2c}'s @code{main()} sets up the information used by +the @code{IARGC} and @code{GETARG} intrinsics. +Bypassing @code{libf2c}'s @code{main()} +without providing a substitute for this activity would mean +that invoking @code{IARGC} and @code{GETARG} would produce undefined +results. + +@cindex debugging +@cindex main program unit, debugging +@cindex main() +@cindex MAIN__() +@cindex .gdbinit +When debugging, one implication of the fact that @code{main()}, which +is the place where the debugged program ``starts'' from the +debugger's point of view, is in @code{libf2c} is that you won't be +starting your Fortran program at a point you recognize as your +Fortran code. + +The standard way to get around this problem is to set a break +point (a one-time, or temporary, break point will do) at +the entrance to @samp{MAIN__}, and then run the program. +A convenient way to do so is to add the @code{gdb} command + +@example +tbreak MAIN__ +@end example + +@noindent +to the file @file{.gdbinit} in the directory in which you're debugging +(using @code{gdb}). + +After doing this, the debugger will see the current execution +point of the program as at the beginning of the main program +unit of your program. + +Of course, if you really want to set a break point at some +other place in your program and just start the program +running, without first breaking at @samp{MAIN__}, +that should work fine. + +@node Procedures +@section Procedures (SUBROUTINE and FUNCTION) +@cindex procedures +@cindex SUBROUTINE statement +@cindex statements, SUBROUTINE +@cindex FUNCTION statement +@cindex statements, FUNCTION +@cindex signature of procedures + +Currently, @code{g77} passes arguments via reference---specifically, +by passing a pointer to the location in memory of a variable, array, +array element, a temporary location that holds the result of evaluating an +expression, or a temporary or permanent location that holds the value +of a constant. + +Procedures that accept @code{CHARACTER} arguments are implemented by +@code{g77} so that each @code{CHARACTER} argument has two actual arguments. + +The first argument occupies the expected position in the +argument list and has the user-specified name. +This argument +is a pointer to an array of characters, passed by the caller. + +The second argument is appended to the end of the user-specified +calling sequence and is named @samp{__g77_length_@var{x}}, where @var{x} +is the user-specified name. +This argument is of the C type @code{ftnlen} +(see @file{gcc/f/runtime/f2c.h.in} for information on that type) and +is the number of characters the caller has allocated in the +array pointed to by the first argument. + +A procedure will ignore the length argument if @samp{X} is not declared +@code{CHARACTER*(*)}, because for other declarations, it knows the +length. +Not all callers necessarily ``know'' this, however, which +is why they all pass the extra argument. + +The contents of the @code{CHARACTER} argument are specified by the +address passed in the first argument (named after it). +The procedure can read or write these contents as appropriate. + +When more than one @code{CHARACTER} argument is present in the argument +list, the length arguments are appended in the order +the original arguments appear. +So @samp{CALL FOO('HI','THERE')} is implemented in +C as @samp{foo("hi","there",2,5);}, ignoring the fact that @code{g77} +does not provide the trailing null bytes on the constant +strings (@code{f2c} does provide them, but they are unnecessary in +a Fortran environment, and you should not expect them to be +there). + +Note that the above information applies to @code{CHARACTER} variables and +arrays @strong{only}. +It does @strong{not} apply to external @code{CHARACTER} +functions or to intrinsic @code{CHARACTER} functions. +That is, no second length argument is passed to @samp{FOO} in this case: + +@example +CHARACTER X +EXTERNAL X +CALL FOO(X) +@end example + +@noindent +Nor does @samp{FOO} expect such an argument in this case: + +@example +SUBROUTINE FOO(X) +CHARACTER X +EXTERNAL X +@end example + +Because of this implementation detail, if a program has a bug +such that there is disagreement as to whether an argument is +a procedure, and the type of the argument is @code{CHARACTER}, subtle +symptoms might appear. + +@node Functions +@section Functions (FUNCTION and RETURN) +@cindex functions +@cindex FUNCTION statement +@cindex statements, FUNCTION +@cindex RETURN statement +@cindex statements, RETURN +@cindex return type of functions + +@code{g77} handles in a special way functions that return the following +types: + +@itemize @bullet +@item +@code{CHARACTER} +@item +@code{COMPLEX} +@item +@code{REAL(KIND=1)} +@end itemize + +For @code{CHARACTER}, @code{g77} implements a subroutine (a C function +returning @code{void}) +with two arguments prepended: @samp{__g77_result}, which the caller passes +as a pointer to a @code{char} array expected to hold the return value, +and @samp{__g77_length}, which the caller passes as an @code{ftnlen} value +specifying the length of the return value as declared in the calling +program. +For @code{CHARACTER*(*)}, the called function uses @samp{__g77_length} +to determine the size of the array that @samp{__g77_result} points to; +otherwise, it ignores that argument. + +For @code{COMPLEX}, when @samp{-ff2c} is in +force, @code{g77} implements +a subroutine with one argument prepended: @samp{__g77_result}, which the +caller passes as a pointer to a variable of the type of the function. +The called function writes the return value into this variable instead +of returning it as a function value. +When @samp{-fno-f2c} is in force, +@code{g77} implements a @code{COMPLEX} function as @code{gcc}'s +@samp{__complex__ float} or @samp{__complex__ double} function +(or an emulation thereof, when @samp{-femulate-complex} is in effect), +returning the result of the function in the same way as @code{gcc} would. + +For @code{REAL(KIND=1)}, when @samp{-ff2c} is in force, @code{g77} implements +a function that actually returns @code{REAL(KIND=2)} (typically +C's @code{double} type). +When @samp{-fno-f2c} is in force, @code{REAL(KIND=1)} +functions return @code{float}. + @node Names @section Names @cindex symbol names @@ -4775,13 +7954,15 @@ the transformation certainly improves the chances of colliding with incompatible externals written in other languages---but that might be intentional. -@cindex -fno-underscoring -@cindex -fno-second-underscore +@cindex -fno-underscoring option +@cindex options, -fno-underscoring +@cindex -fno-second-underscore option +@cindex options, -fno-underscoring When @samp{-funderscoring} is in force, any name (external or local) that already has at least one underscore in it is implemented by @code{g77} by appending two underscores. (This second underscore can be disabled via the -@samp{-fno-second-underscore} option.) +@samp{-fno-second-underscore} option.)@ External names are changed this way for @code{f2c} compatibility. Local names are changed this way to avoid collisions with external names that are different in the source code---@code{f2c} does the same thing, but @@ -4794,6 +7975,7 @@ For example: Max_Cost = 0 @end example +@cindex debugging @noindent Here, a user would, in the debugger, refer to this variable using the name @samp{max_cost__} (or @samp{MAX_COST__} or @samp{Max_Cost__}, @@ -4847,67 +8029,155 @@ of names, resulting in the name @samp{FOO_} or @samp{Foo_} being given to the procedure instead of @samp{foo_}, and the @samp{-fno-underscoring} option could be used to inhibit the appending of the underscore to the name. -@node Main Program Unit -@section Main Program Unit (PROGRAM) -@cindex PROGRAM statement -@cindex statements, PROGRAM +@node Common Blocks +@section Common Blocks (COMMON) +@cindex common blocks +@cindex COMMON statement +@cindex statements, COMMON -When @code{g77} compiles a main program unit, it gives it the public -procedure name @samp{MAIN__}. -The @code{libf2c} library has the actual @samp{main()} procedure -as is typical of C-based environments, and -it is this procedure that performs some initial start-up -activity and then calls @samp{MAIN__}. +@code{g77} names and lays out @code{COMMON} areas the same way f2c does, +for compatibility with f2c. -Generally, @code{g77} and @code{libf2c} are designed so that you need not -include a main program unit written in Fortran in your program---it -can be written in C or some other language. -Especially for I/O handling, this is the case, although @code{g77-0.5.16} -includes a bug fix for @code{libf2c} that solved a problem with using the -@samp{OPEN} statement as the first Fortran I/O activity in a program -without a Fortran main program unit. +Currently, @code{g77} does not emit ``true'' debugging information for +members of a @code{COMMON} area, due to an apparent bug in the GBE. -However, if you don't intend to use @code{g77} (or @code{f2c}) to compile -your main program unit---that is, if you intend to compile a @samp{main()} -procedure using some other language---you should carefully -examine the code for @samp{main()} in @code{libf2c}, found in the source -file @file{gcc/f/runtime/libF77/main.c}, to see what kinds of things -might need to be done by your @samp{main()} in order to provide the -Fortran environment your Fortran code is expecting. +(As of Version 0.5.19, @code{g77} emits debugging information for such +members in the form of a constant string specifying the base name of +the aggregate area and the offset of the member in bytes from the start +of the area. +Use the @samp{-fdebug-kludge} option to enable this behavior. +In @code{gdb}, use @samp{set language c} before printing the value +of the member, then @samp{set language fortran} to restore the default +language, since @code{gdb} doesn't provide a way to print a readable +version of a character string in Fortran language mode. -@cindex IARGC() intrinsic -@cindex intrinsics, IARGC() -@cindex GETARG() intrinsic -@cindex intrinsics, GETARG() -For example, @code{libf2c}'s @samp{main()} sets up the information used by -the @samp{IARGC} and @samp{GETARG} intrinsics. -Bypassing @code{libf2c}'s @samp{main()} -without providing a substitute for this activity would mean -that invoking @samp{IARGC} and @samp{GETARG} would produce undefined -results. +This kludge will be removed in a future version of @code{g77} that, +in conjunction with a contemporary version of @code{gdb}, +properly supports Fortran-language debugging, including access +to members of @code{COMMON} areas.) -@cindex debugging -@cindex main program unit, debugging -@cindex main() -@cindex MAIN__() -When debugging, one implication of the fact that @samp{main()}, which -is the place where the debugged program ``starts'' from the -debugger's point of view, is in @code{libf2c} is that you won't be -starting your Fortran program at a point you recognize as your -Fortran code. +@xref{Code Gen Options,,Options for Code Generation Conventions}, +for information on the @samp{-fdebug-kludge} option. -The standard way to get around this problem is to set a break -point (a one-time, or temporary, break point will do) at -the entrance to @samp{MAIN__}, and then run the program. +Moreover, @code{g77} currently implements a @code{COMMON} area such that its +type is an array of the C @code{char} data type. -After doing this, the debugger will see the current execution -point of the program as at the beginning of the main program -unit of your program. +So, when debugging, you must know the offset into a @code{COMMON} area +for a particular item in that area, and you have to take into +account the appropriate multiplier for the respective sizes +of the types (as declared in your code) for the items preceding +the item in question as compared to the size of the @code{char} type. -Of course, if you really want to set a break point at some -other place in your program and just start the program -running, without first breaking at @samp{MAIN__}, -that should work fine. +For example, using default implicit typing, the statement + +@example +COMMON I(15), R(20), T +@end example + +@noindent +results in a public 144-byte @code{char} array named @samp{_BLNK__} +with @samp{I} placed at @samp{_BLNK__[0]}, @samp{R} at @samp{_BLNK__[60]}, +and @samp{T} at @samp{_BLNK__[140]}. +(This is assuming that the target machine for +the compilation has 4-byte @code{INTEGER(KIND=1)} and @code{REAL(KIND=1)} +types.) + +@node Local Equivalence Areas +@section Local Equivalence Areas (EQUIVALENCE) +@cindex equivalence areas +@cindex local equivalence areas +@cindex EQUIVALENCE statement +@cindex statements, EQUIVALENCE + +@code{g77} treats storage-associated areas involving a @code{COMMON} +block as explained in the section on common blocks. + +A local @code{EQUIVALENCE} area is a collection of variables and arrays +connected to each other in any way via @code{EQUIVALENCE}, none of which are +listed in a @code{COMMON} statement. + +Currently, @code{g77} does not emit ``true'' debugging information for +members in a local @code{EQUIVALENCE} area, due to an apparent bug in the GBE. + +(As of Version 0.5.19, @code{g77} does emit debugging information for such +members in the form of a constant string specifying the base name of +the aggregate area and the offset of the member in bytes from the start +of the area. +Use the @samp{-fdebug-kludge} option to enable this behavior. +In @code{gdb}, use @samp{set language c} before printing the value +of the member, then @samp{set language fortran} to restore the default +language, since @code{gdb} doesn't provide a way to print a readable +version of a character string in Fortran language mode. + +This kludge will be removed in a future version of @code{g77} that, +in conjunction with a contemporary version of @code{gdb}, +properly supports Fortran-language debugging, including access +to members of @code{EQUIVALENCE} areas.) + +@xref{Code Gen Options,,Options for Code Generation Conventions}, +for information on the @samp{-fdebug-kludge} option. + +Moreover, @code{g77} implements a local @code{EQUIVALENCE} area such that its +type is an array of the C @code{char} data type. + +The name @code{g77} gives this array of @code{char} type is @samp{__g77_equiv_@var{x}}, +where @var{x} is the name of the item that is placed at the beginning (offset 0) +of this array. +If more than one such item is placed at the beginning, @var{x} is +the name that sorts to the top in an alphabetical sort of the list of +such items. + +When debugging, you must therefore access members of @code{EQUIVALENCE} +areas by specifying the appropriate @samp{__g77_equiv_@var{x}} +array section with the appropriate offset. +See the explanation of debugging @code{COMMON} blocks +for info applicable to debugging local @code{EQUIVALENCE} areas. + +(@emph{Note:} @code{g77} version 0.5.18 and earlier chose the name +for @var{x} using a different method when more than one name was +in the list of names of entities placed at the beginning of the +array. +Though the documentation specified that the first name listed in +the @code{EQUIVALENCE} statements was chosen for @var{x}, @code{g77} +in fact chose the name using a method that was so complicated, +it seemed easier to change it to an alphabetical sort than to describe the +previous method in the documentation.) + +@node Complex Variables +@section Complex Variables (COMPLEX) +@cindex complex variables +@cindex imaginary part of complex +@cindex COMPLEX statement +@cindex statements, COMPLEX + +As of 0.5.20, @code{g77} defaults to handling @code{COMPLEX} types +(and related intrinsics, constants, functions, and so on) +in a manner that +makes direct debugging involving these types in Fortran +language mode difficult. + +Essentially, @code{g77} implements these types using an +internal construct similar to C's @code{struct}, at least +as seen by the @code{gcc} back end. + +Currently, the back end, when outputting debugging info with +the compiled code for the assembler to digest, does not detect +these @code{struct} types as being substitutes for Fortran +complex. +As a result, the Fortran language modes of debuggers such as +@code{gdb} see these types as C @code{struct} types, which +they might or might not support. + +Until this is fixed, switch to C language mode to work with +entities of @code{COMPLEX} type and then switch back to Fortran language +mode afterward. +(In @code{gdb}, this is accomplished via @samp{set lang c} and +either @samp{set lang fortran} or @samp{set lang auto}.) + +@emph{Note:} Compiling with the @samp{-fno-emulate-complex} option +avoids the debugging problem, but is known to cause other problems +like compiler crashes and generation of incorrect code, so it is +not recommended. @node Arrays @section Arrays (DIMENSION) @@ -4992,77 +8262,6 @@ corresponding lower bounds). You know, maybe nobody really needs to use arrays. -@node Procedures -@section Procedures (SUBROUTINE and FUNCTION) -@cindex procedures -@cindex SUBROUTINE statement -@cindex statements, SUBROUTINE -@cindex FUNCTION statement -@cindex statements, FUNCTION -@cindex signature of procedures - -Procedures that accept @samp{CHARACTER} arguments are implemented by -@code{g77} so that each @samp{CHARACTER} argument has two actual arguments. - -The first argument occupies the expected position in the -argument list and has the user-specified name. -This argument -is a pointer to an array of characters, passed by the caller. - -The second argument is appended to the end of the user-specified -calling sequence and is named @samp{__g77_length_@var{x}}, where @var{x} -is the user-specified name. -This argument is of the C type @samp{ftnlen} -(see @file{gcc/f/runtime/f2c.h.in} for information on that type) and -is the number of characters the caller has allocated in the -array pointed to by the first argument. - -A procedure will ignore the length argument if @samp{X} is not declared -@samp{CHARACTER*(*)}, because for other declarations, it knows the -length. -Not all callers necessarily ``know'' this, however, which -is why they all pass the extra argument. - -The contents of the @samp{CHARACTER} argument are specified by the -address passed in the first argument (named after it). -The procedure can read or write these contents as appropriate. - -When more than one @samp{CHARACTER} argument is present in the argument -list, the length arguments are appended in the order -the orginal arguments appear. -So @samp{CALL FOO('HI','THERE')} is implemented in -C as @samp{foo("hi","there",2,5);}, ignoring the fact that @code{g77} -does not provide the trailing null bytes on the constant -strings (@code{f2c} does provide them, but they are unnecessary in -a Fortran environment, and you should not expect them to be -there). - -Note that the above information applies to @samp{CHARACTER} variables and -arrays @strong{only}. -It does @strong{not} apply to external @samp{CHARACTER} -functions or to intrinsic @samp{CHARACTER} functions. -That is, no second length argument is passed to @samp{FOO} in this case: - -@example -CHARACTER X -EXTERNAL X -CALL FOO(X) -@end example - -@noindent -Nor does @samp{FOO} expect such an argument in this case: - -@example -SUBROUTINE FOO(X) -CHARACTER X -EXTERNAL X -@end example - -Because of this implementation detail, if a program has a bug -such that there is disagreement as to whether an argument is -a procedure, and the type of the argument is @samp{CHARACTER}, subtle -symptoms might appear. - @node Adjustable Arrays @section Adjustable Arrays (DIMENSION) @cindex arrays, adjustable @@ -5109,7 +8308,7 @@ Note that this shows that while the value of @samp{N} was successfully changed, the size of the @samp{A} array remained at 5 elements. To support this, @code{g77} generates code that executes before any user -code (and before the internally generated computed @samp{GOTO} to handle +code (and before the internally generated computed @code{GOTO} to handle alternate entry points, as described below) that evaluates each (nonconstant) expression in the list of subscripts for an array, and saves the result of each such evaluation to be used when @@ -5129,206 +8328,21 @@ account the possibility that a dummy adjustable array is not actually passed to the actual entry point being invoked at that time. In that case, the public procedure implementing the entry point passes to the master private procedure implementing all the -code for the entry points a @samp{NULL} pointer where a pointer to that +code for the entry points a @code{NULL} pointer where a pointer to that adjustable array would be expected. The @code{g77}-generated code doesn't attempt to evaluate any of the expressions in the subscripts -for an array if the pointer to that array is @samp{NULL} at run time in +for an array if the pointer to that array is @code{NULL} at run time in such cases. (Don't depend on this particular implementation -by writing code that purposely passes @samp{NULL} pointers where the +by writing code that purposely passes @code{NULL} pointers where the callee expects adjustable arrays, even if you know the callee -won't reference the arrays---nor should you pass @samp{NULL} pointers +won't reference the arrays---nor should you pass @code{NULL} pointers for any dummy arguments used in calculating the bounds of such arrays or leave undefined any values used for that purpose in COMMON---because the way @code{g77} implements these things might change in the future!) -@node Alternate Returns -@section Alternate Returns (SUBROUTINE and RETURN) -@cindex subroutines -@cindex alternate returns -@cindex SUBROUTINE statement -@cindex statements, SUBROUTINE -@cindex RETURN statement -@cindex statements, RETURN - -Subroutines with alternate returns (e.g. @samp{SUBROUTINE X(*)} and -@samp{CALL X(*50)}) are implemented by @code{g77} as functions returning -the C @samp{int} type. -The actual alternate-return arguments are omitted from the calling sequence. -Instead, the caller uses -the return value to do a rough equivalent of the Fortran -computed-@samp{GOTO} statement, as in @samp{GOTO (50), X()} in the -example above (where @samp{X} is quietly declared as an @samp{INTEGER} -function), and the callee just returns whatever integer -is specified in the @samp{RETURN} statement for the subroutine -For example, @samp{RETURN 1} is implemented as @samp{X = 1} followed -by @samp{RETURN} -in C, and @samp{RETURN} by itself is @samp{X = 0} and @samp{RETURN}). - -@node Functions -@section Functions (FUNCTION and RETURN) -@cindex functions -@cindex FUNCTION statement -@cindex statements, FUNCTION -@cindex RETURN statement -@cindex statements, RETURN -@cindex return type of functions - -@code{g77} handles in a special way functions that return the following -types: - -@itemize @bullet -@item -@samp{CHARACTER} -@item -@samp{COMPLEX} (and @samp{DOUBLE COMPLEX}) -@item -@samp{REAL} -@end itemize - -For @samp{CHARACTER}, @code{g77} implements a subroutine (a C function -returning @samp{void}) -with two arguments prepended: @samp{__g77_result}, which the caller passes -as a pointer to a @samp{char} array expected to hold the return value, -and @samp{__g77_length}, which the caller passes as an @samp{ftnlen} value -specifying the length of the return value as declared in the calling -program. -For @samp{CHARACTER}*(*), the called function uses @samp{__g77_length} -to determine the size of the array that @samp{__g77_result} points to; -otherwise, it ignores that argument. - -For @samp{COMPLEX} and @samp{DOUBLE COMPLEX}, when @samp{-ff2c} is in -force, @code{g77} implements -a subroutine with one argument prepended: @samp{__g77_result}, which the -caller passes as a pointer to a variable of the type of the function. -The called function writes the return value into this variable instead -of returning it as a function value. -When @samp{-fno-f2c} is in force, -@code{g77} implements a @samp{COMPLEX} function as @code{gcc}'s -@samp{__complex__ float} function, -returning the result of the function in the same way as @code{gcc} would, -and implements a @samp{DOUBLE COMPLEX} function similarly. - -For @samp{REAL}, when @samp{-ff2c} is in force, @code{g77} implements -a function that actually returns @samp{DOUBLE PRECISION} (usually -C's @samp{double} type). -When @samp{-fno-f2c} is in force, @samp{REAL} functions return @samp{float}. - -@node Common Blocks -@section Common Blocks (COMMON) -@cindex common blocks -@cindex COMMON statement -@cindex statements, COMMON - -@code{g77} names and lays out @samp{COMMON} areas the same way f2c does, -for compatibility with f2c. - -Currently, @code{g77} does not emit ``true'' debugging information for -members of a @samp{COMMON} area, due to an apparent bug in the GBE. - -(As of Version 0.5.19, @code{g77} emits debugging information for such -members in the form of a constant string specifying the base name of -the aggregate area and the offset of the member in bytes from the start -of the area. -Use the @samp{-fdebug-kludge} option to enable this behavior. -In @code{gdb}, use @samp{set language c} before printing the value -of the member, then @samp{set language fortran} to restore the default -language, since @code{gdb} doesn't provide a way to print a readable -version of a character string in Fortran language mode. - -This kludge will be removed in a future version of @code{g77} that, -in conjunction with a contemporary version of @code{gdb}, -properly supports Fortran-language debugging, including access -to members of @samp{COMMON} areas.) - -@xref{Code Gen Options,,Options for Code Generation Conventions}, -for information on the @samp{-fdebug-kludge} option. - -Moreover, @code{g77} currently implements a @samp{COMMON} area such that its -type is an array of the C @samp{char} data type. - -So, when debugging, you must know the offset into a @samp{COMMON} area -for a particular item in that area, and you have to take into -account the appropriate multiplier for the respective sizes -of the types (as declared in your code) for the items preceding -the item in question as compared to the size of the @samp{char} type. - -For example, using default implicit typing, the statement - -@example -COMMON I(15), R(20), T -@end example - -@noindent -results in a public 144-byte @samp{char} array named @samp{_BLNK__} -with @samp{I} placed at @samp{_BLNK__[0]}, @samp{R} at @samp{_BLNK__[60]}, -and @samp{T} at @samp{_BLNK__[140]}. -(This is assuming that the target machine for -the compilation has 4-byte @samp{INTEGER} and @samp{REAL} types.) - -@node Local Equivalence Areas -@section Local Equivalence Areas (EQUIVALENCE) -@cindex equivalence areas -@cindex local equivalence areas -@cindex EQUIVALENCE statement -@cindex statements, EQUIVALENCE - -@code{g77} treats storage-associated areas involving a @samp{COMMON} -block as explained in the section on common blocks. - -A local @samp{EQUIVALENCE} area is a collection of variables and arrays -connected to each other in any way via @samp{EQUIVALENCE}, none of which are -listed in a @samp{COMMON} statement. - -Currently, @code{g77} does not emit ``true'' debugging information for -members in a local @samp{EQUIVALENCE} area, due to an apparent bug in the GBE. - -(As of Version 0.5.19, @code{g77} does emit debugging information for such -members in the form of a constant string specifying the base name of -the aggregate area and the offset of the member in bytes from the start -of the area. -Use the @samp{-fdebug-kludge} option to enable this behavior. -In @code{gdb}, use @samp{set language c} before printing the value -of the member, then @samp{set language fortran} to restore the default -language, since @code{gdb} doesn't provide a way to print a readable -version of a character string in Fortran language mode. - -This kludge will be removed in a future version of @code{g77} that, -in conjunction with a contemporary version of @code{gdb}, -properly supports Fortran-language debugging, including access -to members of @samp{EQUIVALENCE} areas.) - -@xref{Code Gen Options,,Options for Code Generation Conventions}, -for information on the @samp{-fdebug-kludge} option. - -Moreover, @code{g77} implements a local @samp{EQUIVALENCE} area such that its -type is an array of the C @samp{char} data type. - -The name @code{g77} gives this array of @samp{char} type is @samp{__g77_equiv_@var{x}}, -where @var{x} is the name of the item that is placed at the beginning (offset 0) -of this array. -If more than one such item is placed at the beginning, @var{x} is -the name that sorts to the top in an alphabetical sort of the list of -such items. - -When debugging, you must therefore access members of @samp{EQUIVALENCE} -areas by specifying the appropriate @samp{__g77_equiv_@var{x}} -array section with the appropriate offset. -See the explanation of debugging @samp{COMMON} blocks -for info applicable to debugging local @samp{EQUIVALENCE} areas. - -(@emph{Note:} @code{g77} version 0.5.18 and earlier chose the name -for @var{x} using a different method when more than one name was -in the list of names of entities placed at the beginning of the -array. -Though the documentation specified that the first name listed in -the @samp{EQUIVALENCE} statements was chosen for @var{x}, @code{g77} -in fact chose the name using a method that was so complicated, -it seemed easier to change it to an alphabetical sort than to describe the -previous method in the documentation.) - @node Alternate Entry Points @section Alternate Entry Points (ENTRY) @cindex alternate entry points @@ -5339,20 +8353,20 @@ previous method in the documentation.) The GBE does not understand the general concept of alternate entry points as Fortran provides via the ENTRY statement. @code{g77} gets around this by using an approach to compiling procedures -having at least one @samp{ENTRY} statement that is almost identical to the +having at least one @code{ENTRY} statement that is almost identical to the approach used by @code{f2c}. (An alternate approach could be used that would probably generate faster, but larger, code that would also be a bit easier to debug.) -Information on how @code{g77} implements @samp{ENTRY} is provided for those +Information on how @code{g77} implements @code{ENTRY} is provided for those trying to debug such code. The choice of implementation seems unlikely to affect code (compiled in other languages) that interfaces to such code. @code{g77} compiles exactly one public procedure for the primary entry -point of a procedure plus each @samp{ENTRY} point it specifies, as usual. +point of a procedure plus each @code{ENTRY} point it specifies, as usual. That is, in terms of the public interface, there is no difference between @@ -5376,7 +8390,7 @@ The difference between the above two cases lies in the code compiled for the @samp{X} and @samp{Y} procedures themselves, plus the fact that, for the second case, an extra internal procedure is compiled. -For every Fortran procedure with at least one @samp{ENTRY} +For every Fortran procedure with at least one @code{ENTRY} statement, @code{g77} compiles an extra procedure named @samp{__g77_masterfun_@var{x}}, where @var{x} is the name of the primary entry point (which, in the above case, @@ -5395,37 +8409,36 @@ It contains a single integer argument named @samp{__g77_which_entrypoint}, passed by value (as in Fortran's @samp{%VAL()} intrinsic), specifying the entry point index---0 for the primary entry point, 1 for the -first entry point (the first @samp{ENTRY} statement encountered), 2 for +first entry point (the first @code{ENTRY} statement encountered), 2 for the second entry point, and so on. -It also contains, for functions returning @samp{CHARACTER} and -(when @samp{-ff2c} is in effect) @samp{COMPLEX} functions, +It also contains, for functions returning @code{CHARACTER} and +(when @samp{-ff2c} is in effect) @code{COMPLEX} functions, and for functions returning different types among the -@samp{ENTRY} statements (e.g. @samp{REAL FUNCTION R()} +@code{ENTRY} statements (e.g. @samp{REAL FUNCTION R()} containing @samp{ENTRY I()}), an argument named @samp{__g77_result} that is expected at run time to contain a pointer to where to store the result of the entry point. -For @samp{CHARACTER} functions, this +For @code{CHARACTER} functions, this storage area is an array of the appropriate number of characters; -for @samp{COMPLEX} functions, it is the appropriate area for the return -type (currently either @samp{COMPLEX} or @samp{DOUBLE COMPLEX}); for multiple- -return-type functions, it is a union of all the supported return -types (which cannot include @samp{CHARACTER}, since combining @samp{CHARACTER} -and non-@samp{CHARACTER} return types via @samp{ENTRY} in a single function +for @code{COMPLEX} functions, it is the appropriate area for the return +type; for multiple-return-type functions, it is a union of all the supported return +types (which cannot include @code{CHARACTER}, since combining @code{CHARACTER} +and non-@code{CHARACTER} return types via @code{ENTRY} in a single function is not supported by @code{g77}). -For @samp{CHARACTER} functions, the @samp{__g77_result} argument is followed +For @code{CHARACTER} functions, the @samp{__g77_result} argument is followed by yet another argument named @samp{__g77_length} that, at run time, specifies the caller's expected length of the returned value. -Note that only @samp{CHARACTER*(*)} functions and entry points actually +Note that only @code{CHARACTER*(*)} functions and entry points actually make use of this argument, even though it is always passed by -all callers of public @samp{CHARACTER} functions (since the caller does not -generally know whether such a function is @samp{CHARACTER*(*)} or whether +all callers of public @code{CHARACTER} functions (since the caller does not +generally know whether such a function is @code{CHARACTER*(*)} or whether there are any other callers that don't have that information). The rest of the argument list is the union of all the arguments specified for all the entry points (in their usual forms, e.g. -@samp{CHARACTER} arguments have extra length arguments, all appended at +@code{CHARACTER} arguments have extra length arguments, all appended at the end of this list). This is considered the ``master list'' of arguments. @@ -5454,7 +8467,7 @@ Getting back to the public procedures (@samp{x} and @samp{Y} in the original example), those procedures are fairly simple. Their interfaces are just like they would be if they were self-contained procedures -(without @samp{ENTRY}), of course, since that is what the callers +(without @code{ENTRY}), of course, since that is what the callers expect. Their code consists of simply calling the private procedure, described above, with the appropriate extra arguments @@ -5464,7 +8477,7 @@ all the supported returnable non-character types). For arguments that are not listed for a given entry point that are listed for other entry points, and therefore that are in the ``master list'' -for the private procedure, null pointers (in C, the @samp{NULL} macro) +for the private procedure, null pointers (in C, the @code{NULL} macro) are passed. Also, for entry points that are part of a multiple-type- returning function, code is compiled after the call of the private @@ -5490,6 +8503,29 @@ as explained above, and the way in which return values are handled might well be different from how they would be handled for an equivalent single-entry function. +@node Alternate Returns +@section Alternate Returns (SUBROUTINE and RETURN) +@cindex subroutines +@cindex alternate returns +@cindex SUBROUTINE statement +@cindex statements, SUBROUTINE +@cindex RETURN statement +@cindex statements, RETURN + +Subroutines with alternate returns (e.g. @samp{SUBROUTINE X(*)} and +@samp{CALL X(*50)}) are implemented by @code{g77} as functions returning +the C @code{int} type. +The actual alternate-return arguments are omitted from the calling sequence. +Instead, the caller uses +the return value to do a rough equivalent of the Fortran +computed-@code{GOTO} statement, as in @samp{GOTO (50), X()} in the +example above (where @samp{X} is quietly declared as an @code{INTEGER(KIND=1)} +function), and the callee just returns whatever integer +is specified in the @code{RETURN} statement for the subroutine +For example, @samp{RETURN 1} is implemented as @samp{X = 1} followed +by @samp{RETURN} +in C, and @samp{RETURN} by itself is @samp{X = 0} and @samp{RETURN}). + @node Assigned Statement Labels @section Assigned Statement Labels (ASSIGN and GOTO) @cindex assigned statement labels @@ -5500,11 +8536,11 @@ for an equivalent single-entry function. @cindex statements, GOTO For portability to machines where a pointer (such as to a label, -which is how @code{g77} implements @samp{ASSIGN} and its cousin, the assigned -@samp{GOTO}) is wider (bitwise) than an @samp{INTEGER}, @code{g77} does not -necessarily use -the same memory location to hold the @samp{ASSIGN}ed value of a variable -as it does the numerical value in that variable, unless the +which is how @code{g77} implements @code{ASSIGN} and its relatives, +the assigned-@code{GOTO} and assigned-@code{FORMAT}-I/O statements) +is wider (bitwise) than an @code{INTEGER(KIND=1)}, @code{g77} +uses a different memory location to hold the @code{ASSIGN}ed value of a variable +than it does the numerical value in that variable, unless the variable is wide enough (can hold enough bits). In particular, while @code{g77} implements @@ -5514,7 +8550,7 @@ I = 10 @end example @noindent -as, in C notation, @samp{i = 10;}, it might implement +as, in C notation, @samp{i = 10;}, it implements @example ASSIGN 10 TO I @@ -5527,7 +8563,7 @@ of the Fortran label @samp{10} to make the syntax C-like; @code{g77} doesn't actually generate the name @samp{L10} or any other name like that, since debuggers cannot access labels anyway). -While this currently means that an @samp{ASSIGN} statement might not +While this currently means that an @code{ASSIGN} statement does not overwrite the numeric contents of its target variable, @emph{do not} write any code depending on this feature. @code{g77} has already changed this implementation across @@ -5539,10 +8575,67 @@ in a program unit that does @samp{ASSIGN 10 TO I}, that probably means @code{g77} has decided it can store the pointer to the label directly into @samp{I} itself. -(Currently, @code{g77} always chooses to make the separate variable, -to improve the likelihood that @samp{-O -Wuninitialized} will -diagnose failures to do things like @samp{GOTO I} without -@samp{ASSIGN 10 TO I} despite doing @samp{I=5}.) +@xref{Ugly Assigned Labels}, for information on a command-line option +to force @code{g77} to use the same storage for both normal and +assigned-label uses of a variable. + +@node Run-time Library Errors +@section Run-time Library Errors +@cindex IOSTAT= +@cindex error values +@cindex error messages +@cindex messages, run-time +@cindex I/O, errors + +The @code{libf2c} library currently has the following table to relate +error code numbers, returned in @code{IOSTAT=} variables, to messages. +This information should, in future versions of this document, be +expanded upon to include detailed descriptions of each message. + +In line with good coding practices, any of the numbers in the +list below should @emph{not} be directly written into Fortran +code you write. +Instead, make a separate @code{INCLUDE} file that defines +@code{PARAMETER} names for them, and use those in your code, +so you can more easily change the actual numbers in the future. + +The information below is culled from the definition +of @samp{F_err} in @file{f/runtime/libI77/err.c} in the +@code{g77} source tree. + +@example +100: "error in format" +101: "illegal unit number" +102: "formatted io not allowed" +103: "unformatted io not allowed" +104: "direct io not allowed" +105: "sequential io not allowed" +106: "can't backspace file" +107: "null file name" +108: "can't stat file" +109: "unit not connected" +110: "off end of record" +111: "truncation failed in endfile" +112: "incomprehensible list input" +113: "out of free space" +114: "unit not connected" +115: "read unexpected character" +116: "bad logical input field" +117: "bad variable type" +118: "bad namelist name" +119: "variable not in namelist" +120: "no end record" +121: "variable count incorrect" +122: "subscript for scalar variable" +123: "invalid array section" +124: "substring out of bounds" +125: "subscript out of bounds" +126: "can't read file" +127: "can't write file" +128: "'new' file exists" +129: "can't append to file" +130: "non-positive record number" +@end example @node Collected Fortran Wisdom @chapter Collected Fortran Wisdom @@ -5565,7 +8658,7 @@ Those using @code{g77} to compile existing, ``legacy'' code. Users writing new code generally understand most of the necessary aspects of Fortran to write ``mainstream'' code, but often need help deciding how to handle problems, such as the construction -of libraries containing @samp{BLOCK DATA}. +of libraries containing @code{BLOCK DATA}. Users dealing with ``legacy'' code sometimes don't have much experience with Fortran, but believe that the code they're compiling @@ -5578,106 +8671,194 @@ coping with existing, ``legacy'' Fortran code, and with writing new code as well. @menu -* Overly Convenient Options:: Temptations to avoid, habits to not form. +* Advantages Over f2c:: If @code{f2c} is so great, why @code{g77}? * Block Data and Libraries:: How @code{g77} solves a common problem. -* Faster Programs:: Everybody wants these, but at what cost? +* Loops:: Fortran @code{DO} loops surprise many people. * Working Programs:: Getting programs to work should be done first. -* Loops:: Fortran @samp{DO} loops surprise many people. -* Advantages Over f2c:: If @code{f2c} is so great, why @code{g77}? +* Overly Convenient Options:: Temptations to avoid, habits to not form. +* Faster Programs:: Everybody wants these, but at what cost? @end menu -@node Overly Convenient Options -@section Overly Convenient Command-line Options -@cindex overly convenient options -@cindex options, overly convenient +@node Advantages Over f2c +@section Advantages Over f2c -These options should be used only as a quick-and-dirty way to determine -how well your program will run under different compilation models -without having to change the source. -Some are more problematic -than others, depending on how portable and maintainable you want the -program to be (and, of course, whether you are allowed to change it -at all is crucial). +Without @code{f2c}, @code{g77} would have taken much longer to +do and probably not been as good for quite a while. +Sometimes people who notice how much @code{g77} depends on, and +documents encouragement to use, @code{f2c} ask why @code{g77} +was created if @code{f2c} already existed. -You should not continue to use these command-line options to compile -a given program, but rather should make changes to the source code: +This section gives some basic answers to these questions, though it +is not intended to be comprehensive. -@table @code -@cindex -finit-local-zero option -@cindex options, -finit-local-zero -@item -finit-local-zero -(This option specifies that any uninitialized local variables -and arrays have default initialization to binary zeros.) +@menu +* Language Extensions:: Features used by Fortran code. +* Compiler Options:: Features helpful during development. +* Compiler Speed:: Speed of the compilation process. +* Program Speed:: Speed of the generated, optimized code. +* Ease of Debugging:: Debugging ease-of-use at the source level. +* Character and Hollerith Constants:: A byte saved is a byte earned. +@end menu -Many other compilers do this automatically, which means lots of -Fortran code developed with those compilers depends on it. +@node Language Extensions +@subsection Language Extensions -It is safer (and probably -would produce a faster program) to find the variables and arrays that -need such initialization and provide it explicitly via @samp{DATA}, so that -@samp{-finit-local-zero} is not needed. +@code{g77} offers several extensions to the Fortran language that @code{f2c} +doesn't. -Consider using @samp{-Wuninitialized} (which requires @samp{-O}) to -find likely candidates, but -do not specify @samp{-finit-local-zero} or @samp{-fno-automatic}, -or this technique won't work. +However, @code{f2c} offers a few that @code{g77} doesn't, like +fairly complete support for @code{INTEGER*2}. +It is expected that @code{g77} will offer some or all of these missing +features at some time in the future. +(Version 0.5.18 of @code{g77} offers some rudimentary support for some +of these features.) -@cindex -fno-automatic option -@cindex options, -fno-automatic -@item -fno-automatic -(This option specifies that all local variables and arrays -are to be treated as if they were named in @samp{SAVE} statements.) +@node Compiler Options +@subsection Compiler Options -Many other compilers do this automatically, which means lots of -Fortran code developed with those compilers depends on it. +@code{g77} offers a whole bunch of compiler options that @code{f2c} doesn't. -The effect of this is that all non-automatic variables and arrays -are made static, that is, not placed on the stack or in heap storage. -This might cause a buggy program to appear to work better. -If so, rather than relying on this command-line option (and hoping all -compilers provide the equivalent one), add @samp{SAVE} -statements to some or all program unit sources, as appropriate. -Consider using @samp{-Wuninitialized} (which requires @samp{-O}) -to find likely candidates, but -do not specify @samp{-finit-local-zero} or @samp{-fno-automatic}, -or this technique won't work. +However, @code{f2c} offers a few that @code{g77} doesn't, like an +option to generate code to check array subscripts at run time. +It is expected that @code{g77} will offer some or all of these +missing options at some time in the future. -The default is @samp{-fautomatic}, which tells @code{g77} to try -and put variables and arrays on the stack (or in fast registers) -where possible and reasonable. -This tends to make programs faster. +@node Compiler Speed +@subsection Compiler Speed -@cindex automatic arrays -@cindex arrays, automatic -@emph{Note:} Automatic variables and arrays are not affected -by this option. -These are variables and arrays that are @emph{necessarily} automatic, -either due to explicit statements, or due to the way they are -declared. -Examples include local variables and arrays not given the -@samp{SAVE} attribute in procedures declared @samp{RECURSIVE}, -and local arrays declared with non-constant bounds (automatic -arrays). -Currently, @code{g77} supports only automatic arrays, not -@samp{RECURSIVE} procedures or other means of explicitly -specifying that variables or arrays are automatic. +Saving the steps of writing and then rereading C code is a big reason +why @code{g77} should be able to compile code much faster than using +@code{f2c} in conjunction with the equivalent invocation of @code{gcc}. -@cindex -fugly option -@cindex options, -fugly -@item -fugly -Fix the source code so that @samp{-fno-ugly} will work. -Note that, for many programs, it is difficult to practically -avoid using the features enabled via @samp{-fugly-init}, and these -features pose the lowest risk of writing nonportable code, among the -various ``ugly'' features. +However, due to @code{g77}'s youth, lots of self-checking is still being +performed. +As a result, this improvement is as yet unrealized +(though the potential seems to be there for quite a big speedup +in the future). +It is possible that, as of version 0.5.18, @code{g77} +is noticeably faster compiling many Fortran source files than using +@code{f2c} in conjunction with @code{gcc}. -@cindex -f@var{group}-intrinsics-hide option -@cindex options, -f@var{group}-intrinsics-hide -@item -f@var{group}-intrinsics-hide -Change the source code to use @samp{EXTERNAL} for any external procedure -that might be the name of an intrinsic. -It is easy to find these using @samp{-f@var{group}-intrinsics-disable}. -@end table +@node Program Speed +@subsection Program Speed + +@code{g77} has the potential to better optimize code than @code{f2c}, +even when @code{gcc} is used to compile the output of @code{f2c}, +because @code{f2c} must necessarily +translate Fortran into a somewhat lower-level language (C) that cannot +preserve all the information that is potentially useful for optimization, +while @code{g77} can gather, preserve, and transmit that information directly +to the GBE. + +For example, @code{g77} implements @code{ASSIGN} and assigned +@code{GOTO} using direct assignment of pointers to labels and direct +jumps to labels, whereas @code{f2c} maps the assigned labels to +integer values and then uses a C @code{switch} statement to encode +the assigned @code{GOTO} statements. + +However, as is typical, theory and reality don't quite match, at least +not in all cases, so it is still the case that @code{f2c} plus @code{gcc} +can generate code that is faster than @code{g77}. + +Version 0.5.18 of @code{g77} offered default +settings and options, via patches to the @code{gcc} +back end, that allow for better program speed, though +some of these improvements also affected the performance +of programs translated by @code{f2c} and then compiled +by @code{g77}'s version of @code{gcc}. + +Version 0.5.20 of @code{g77} offers further performance +improvements, at least one of which (alias analysis) is +not generally applicable to @code{f2c} (though @code{f2c} +could presumably be changed to also take advantage of +this new capability of the @code{gcc} back end, assuming +this is made available in an upcoming release of @code{gcc}). + +@node Ease of Debugging +@subsection Ease of Debugging + +Because @code{g77} compiles directly to assembler code like @code{gcc}, +instead of translating to an intermediate language (C) as does @code{f2c}, +support for debugging can be better for @code{g77} than @code{f2c}. + +However, although @code{g77} might be somewhat more ``native'' in terms of +debugging support than @code{f2c} plus @code{gcc}, there still are a lot +of things ``not quite right''. +Many of the important ones should be resolved in the near future. + +For example, @code{g77} doesn't have to worry about reserved names +like @code{f2c} does. +Given @samp{FOR = WHILE}, @code{f2c} must necessarily +translate this to something @emph{other} than +@samp{for = while;}, because C reserves those words. + +However, @code{g77} does still uses things like an extra level of indirection +for @code{ENTRY}-laden procedures---in this case, because the back end doesn't +yet support multiple entry points. + +Another example is that, given + +@example +COMMON A, B +EQUIVALENCE (B, C) +@end example + +@noindent +the @code{g77} user should be able to access the variables directly, by name, +without having to traverse C-like structures and unions, while @code{f2c} +is unlikely to ever offer this ability (due to limitations in the +C language). + +However, due to apparent bugs in the back end, @code{g77} currently doesn't +take advantage of this facility at all---it doesn't emit any debugging +information for @code{COMMON} and @code{EQUIVALENCE} areas, +other than information +on the array of @code{char} it creates (and, in the case +of local @code{EQUIVALENCE}, names) for each such area. + +Yet another example is arrays. +@code{g77} represents them to the debugger +using the same ``dimensionality'' as in the source code, while @code{f2c} +must necessarily convert them all to one-dimensional arrays to fit +into the confines of the C language. +However, the level of support +offered by debuggers for interactive Fortran-style access to arrays +as compiled by @code{g77} can vary widely. +In some cases, it can actually +be an advantage that @code{f2c} converts everything to widely supported +C semantics. + +In fairness, @code{g77} could do many of the things @code{f2c} does +to get things working at least as well as @code{f2c}---for now, +the developers prefer making @code{g77} work the +way they think it is supposed to, and finding help improving the +other products (the back end of @code{gcc}; @code{gdb}; and so on) +to get things working properly. + +@node Character and Hollerith Constants +@subsection Character and Hollerith Constants +@cindex character constants +@cindex constants, character +@cindex Hollerith constants +@cindex constants, Hollerith +@cindex trailing null byte +@cindex null byte, trailing +@cindex zero byte, trailing + +To avoid the extensive hassle that would be needed to avoid this, +@code{f2c} uses C character constants to encode character and Hollerith +constants. +That means a constant like @samp{'HELLO'} is translated to +@samp{"hello"} in C, which further means that an extra null byte is +present at the end of the constant. +This null byte is superfluous. + +@code{g77} does not generate such null bytes. +This represents significant +savings of resources, such as on systems where @file{/dev/null} or +@file{/dev/zero} represent bottlenecks in the systems' performance, +because @code{g77} simply asks for fewer zeros from the operating +system than @code{f2c}. @node Block Data and Libraries @section Block Data and Libraries @@ -5685,16 +8866,16 @@ It is easy to find these using @samp{-f@var{group}-intrinsics-disable}. @cindex BLOCK DATA statement @cindex statements, BLOCK DATA @cindex libraries, containing BLOCK DATA -@cindex f2c compatibility -@cindex compatibility +@cindex @code{f2c} compatibility +@cindex compatibility, @code{f2c} To ensure that block data program units are linked, especially a concern when they are put into libraries, give each one a name (as in @samp{BLOCK DATA FOO}) and make sure there is an @samp{EXTERNAL FOO} statement in every program unit that uses any common block -initialized by the corresponding @samp{BLOCK DATA}. -@code{g77} currently compiles a @samp{BLOCK DATA} as if it were a -@samp{SUBROUTINE}, +initialized by the corresponding @code{BLOCK DATA}. +@code{g77} currently compiles a @code{BLOCK DATA} as if it were a +@code{SUBROUTINE}, that is, it generates an actual procedure having the appropriate name. The procedure does nothing but return immediately if it happens to be called. @@ -5712,7 +8893,7 @@ shipped. issue a warning that @samp{FOO} is not otherwise referenced, and for @samp{BLOCK DATA FOO}, f2c doesn't generate a dummy procedure with the name @samp{FOO}. -The upshot is that you shouldn't mix @samp{f2c} and @code{g77} in +The upshot is that you shouldn't mix @code{f2c} and @code{g77} in this particular case. If you use f2c to compile @samp{BLOCK DATA FOO}, then any @code{g77}-compiled program unit that says @samp{EXTERNAL FOO} @@ -5733,118 +8914,47 @@ that might not link @samp{BLOCK DATA FOO} under some circumstances, most of them appear to do so once @samp{EXTERNAL FOO} is present in the appropriate program units. -@node Faster Programs -@section Faster Programs -@cindex speeding up programs -@cindex programs, speeding up - -Aside from the usual @samp{gcc} options, such as @samp{-O}, -@samp{-ffast-math}, and so on, consider trying: - -@table @code -@cindex -fno-f2c option -@cindex options, -fno-f2c -@item -fno-f2c -@cindex f2c compatibility -@cindex compatibility -Use this if you aren't linking with any code compiled using -@code{f2c}. -(Note that @code{libf2c} is @emph{not} an example of code -that is compiled using @code{f2c}---it is compiled by a C -compiler, usually @code{gcc}.) -@end table - -If you're using @samp{-fno-automatic} already, you probably -should change your code to allow compilation with @samp{-fautomatic} -(the default), to allow the program to run faster. - -Similarly, you should be able to use @samp{-fno-init-local-zero} -(the default) instead of @samp{-finit-local-zero}. -This is because it is rare that every variable affected by these -options in a given program actually needs to -be so affected. - -For example, @samp{-fno-automatic}, which effectively @samp{SAVE}s -every local non-automatic variable and array, affects even things like -@samp{DO} iteration -variables, which rarely need to be @samp{SAVE}d, and this often reduces -run-time performances. -Similarly, @samp{-fno-init-local-zero} forces such -variables to be initialized to zero---when @samp{SAVE}d (such as when -@samp{-fno-automatic}), this by itself generally affects only -startup time for a program, but when not @samp{SAVE}d, -it can slow down the procedure every time it is called. - -@xref{Overly Convenient Options,,Overly Convenient Command-Line Options}, -for information on the @samp{-fno-automatic} and -@samp{-finit-local-zero} options and how to convert -their use into selective changes in your own code. - -@node Working Programs -@section Working Programs - -Getting Fortran programs to work in the first place can be -quite a challenge---even when the programs already work on -other systems, or when using other compilers. +Here is the recommended approach to modifying a program containing +a program unit such as the following: -@code{g77} offers some options that might be useful for -tracking down bugs in such programs. -@xref{Option Summary}, for a summary of these and other -options, and cross-references for each such option to -the pertinent material in this manual. - -@table @code -@item -finit-local-zero -A program that works better when compiled with this option -is depending on a particular system's, or compiler's, tendency -to initialize some variables to zero. -It might be worthwhile finding such cases and fixing them. - -@item -fno-automatic -A program that works better when compiled with this option -is depending on not having to use the @samp{SAVE} statement -as required by the Fortran standard. -It might be worthwhile finding such cases and fixing them. +@example +BLOCK DATA FOO +COMMON /VARS/ X, Y, Z +DATA X, Y, Z / 3., 4., 5. / +END +@end example -@item -Wimplicit -This might catch failures to properly specify the types of -variables, arrays, and functions in the code. -However, in code that makes heavy use of Fortran's -implicit-typing facility, this option might produce so -many warnings about cases that are working, it would be -hard to find the one or two that represent bugs. +@noindent +If the above program unit might be placed in a library module, then +ensure that every program unit in every program that references that +particular @code{COMMON} area uses the @code{EXTERNAL} statement +to force the area to be initialized. -@item -Wunused -This can find bugs involving implicitly typing, sometimes -more easily than using -Wimplicit in code that makes -heavy use of implicit typing. -An unused variable or array might indicate that the -spelling for its declaration is different from that of -its intended uses. +For example, change a program unit that starts with -@item -Wuninitialized -This can find bugs involving uninitialized variables, which -can in turn result from misspellings in declaration statements. +@example +INTEGER FUNCTION CURX() +COMMON /VARS/ X, Y, Z +CURX = X +END +@end example -@item -Wsurprising -This can find bugs involving expression evaluation or in -the way @samp{DO} loops with non-integral iteration variables -are handled. -Cases found by this option might indicate a difference of -interpretation between the author of the code involved, and -a standard-conforming compiler such as @code{g77}. -Such a difference might produce actual bugs. +@noindent +so that it uses the @code{EXTERNAL} statement, as in: -In any case, changing the code to explicitly do what the -programmer might have expected it to do, so @code{g77} and -other compilers are more likely to follow the programmer's -expectations, might be worthwhile, especially if such changes -make the program work better. +@example +INTEGER FUNCTION CURX() +COMMON /VARS/ X, Y, Z +EXTERNAL FOO +CURX = X +END +@end example -@item -W -It is possible that the ``extra'' warnings enabled by this -option could expose bugs in the code. -@end table +@noindent +That way, @samp{CURX} is compiled by @code{g77} (and many other +compilers) so that the linker knows it must include @samp{FOO}, +the @code{BLOCK DATA} program unit that sets the initial values +for the variables in @samp{VAR}, in the executable program. @node Loops @section Loops @@ -5853,11 +8963,11 @@ option could expose bugs in the code. @cindex trips, number of @cindex number of trips -The meaning of a @samp{DO} loop in Fortran is precisely specified +The meaning of a @code{DO} loop in Fortran is precisely specified in the Fortran standard@dots{}and is quite different from what many programmers might expect. -In particular, Fortran @samp{DO} loops are implemented as if +In particular, Fortran @code{DO} loops are implemented as if the number of trips through the loop is calculated @emph{before} the loop is entered. @@ -5868,6 +8978,7 @@ The number of trips for a loop is calculated from the @var{start}, DO @var{iter} = @var{start}, @var{end}, @var{increment} @end example +@noindent The trip count is evaluated using a fairly simple formula based on the three values following the @samp{=} in the statement, and it is that trip count that is effectively @@ -5890,14 +9001,14 @@ not executed at all. The type used to @emph{calculate} the trip count the same type as @var{iter}, but the final calculation, and thus the type of the trip -count itself, always is @samp{INTEGER}. +count itself, always is @code{INTEGER(KIND=1)}. @end itemize These two items mean that there are loops that cannot -be written in straightforward fashion using the Fortran @samp{DO}. +be written in straightforward fashion using the Fortran @code{DO}. For example, on a system with the canonical 32-bit two's-complement -implementation of @samp{INTEGER}, the following loop will not work: +implementation of @code{INTEGER(KIND=1)}, the following loop will not work: @example DO I = -2000000000, 2000000000 @@ -5905,9 +9016,9 @@ DO I = -2000000000, 2000000000 @noindent Although the @var{start} and @var{end} values are well within -the range of @samp{INTEGER}, the @emph{trip count} is not. +the range of @code{INTEGER(KIND=1)}, the @emph{trip count} is not. The expected trip count is 40000000001, which is outside -the range of @samp{INTEGER} on many systems. +the range of @code{INTEGER(KIND=1)} on many systems. Instead, the above loop should be constructed this way: @@ -5921,14 +9032,14 @@ END DO @end example @noindent -The simple @samp{DO} construct and the @samp{EXIT} statement +The simple @code{DO} construct and the @code{EXIT} statement (used to leave the innermost loop) are F90 features that @code{g77} supports. -Some Fortran compilers have buggy implementations of @samp{DO}, +Some Fortran compilers have buggy implementations of @code{DO}, in that they don't follow the standard. -They implement @samp{DO} as a straightforward translation -to what, in C, would be a @samp{for} statement. +They implement @code{DO} as a straightforward translation +to what, in C, would be a @code{for} statement. Instead of creating a temporary variable to hold the trip count as calculated at run time, these compilers use the iteration variable @var{iter} to control @@ -5958,9 +9069,9 @@ can never be greater than 2147483647, since incrementing it beyond that value overflows @samp{i}, setting it to -2147483648. This is a large, negative number that still is less than 2147483647. -Another example of unexpected behavior of @samp{DO} involves -using a nonintegral iteration variable @var{iter}, such as -a @samp{REAL} or @samp{DOUBLE PRECISION} variable. +Another example of unexpected behavior of @code{DO} involves +using a nonintegral iteration variable @var{iter}, that is, +a @code{REAL} variable. Consider the following program: @smallexample @@ -5975,8 +9086,8 @@ Consider the following program: @end smallexample @noindent -A C-like view of @samp{DO} would hold that the two ``exclamatory'' -@samp{PRINT} are never executed. +A C-like view of @code{DO} would hold that the two ``exclamatory'' +@code{PRINT} statements are never executed. However, this is the output of running the above program as compiled by @code{g77} on a GNU/Linux ix86 system: @@ -6006,192 +9117,744 @@ of 31 might result, but, nevertheless, @code{g77} is faithfully following the Fortran standard, and the result is not what the author of the sample program above apparently expected. -(Such other systems might, for different values in the @samp{DATA} +(Such other systems might, for different values in the @code{DATA} statement, violate the other programmer's expectation, for example.) Due to this combination of imprecise representation of floating-point values and the often-misunderstood -interpretation of @samp{DO} by standard-conforming -compilers such as @code{g77}, use of @samp{DO} loops -with @samp{REAL} or @samp{DOUBLE PRECISION} iteration +interpretation of @code{DO} by standard-conforming +compilers such as @code{g77}, use of @code{DO} loops +with @code{REAL} iteration variables is not recommended. Such use can be caught by specifying @samp{-Wsurprising}. @xref{Warning Options}, for more information on this option. -@node Advantages Over f2c -@section Advantages Over f2c +@node Working Programs +@section Working Programs -Without @code{f2c}, @code{g77} would have taken much longer to -do and probably not been as good for quite a while. -Sometimes people who notice how much @code{g77} depends on, and -documents encouragement to use, @code{f2c} ask why @code{g77} -was created if @code{f2c} already existed. +Getting Fortran programs to work in the first place can be +quite a challenge---even when the programs already work on +other systems, or when using other compilers. -This section gives some basic answers to these questions, though it -is not intended to be comprehensive. +@code{g77} offers some facilities that might be useful for +tracking down bugs in such programs. @menu -* Language Extensions:: Features used by Fortran code. -* Compiler Options:: Features helpful during development. -* Compiler Speed:: Speed of the compilation process. -* Program Speed:: Speed of the generated, optimized code. -* Ease of Debugging:: Debugging ease-of-use at the source level. -* Character and Hollerith Constants:: A byte saved is a byte earned. +* Not My Type:: +* Variables Assumed To Be Zero:: +* Variables Assumed To Be Saved:: +* Unwanted Variables:: +* Unused Arguments:: +* Surprising Interpretations of Code:: +* Aliasing Assumed To Work:: +* Output Assumed To Flush:: +* Large File Unit Numbers:: @end menu -@node Language Extensions -@subsection Language Extensions +@node Not My Type +@subsection Not My Type +@cindex mistyped variables +@cindex variables, mistyped +@cindex mistyped functions +@cindex functions, mistyped +@cindex implicit typing + +A fruitful source of bugs in Fortran source code is use, or +mis-use, of Fortran's implicit-typing feature, whereby the +type of a variable, array, or function is determined by the +first character of its name. + +Simple cases of this include statements like @samp{LOGX=9.227}, +without a statement such as @samp{REAL LOGX}. +In this case, @samp{LOGX} is implicitly given @code{INTEGER(KIND=1)} +type, with the result of the assignment being that it is given +the value @samp{9}. + +More involved cases include a function that is defined starting +with a statement like @samp{DOUBLE PRECISION FUNCTION IPS(@dots{})}. +Any caller of this function that does not also declare @samp{IPS} +as type @code{DOUBLE PRECISION} (or, in GNU Fortran, @code{REAL(KIND=2)}) +is likely to assume it returns +@code{INTEGER}, or some other type, leading to invalid results +or even program crashes. + +The @samp{-Wimplicit} option might catch failures to +properly specify the types of +variables, arrays, and functions in the code. -@code{g77} offers several extensions to the Fortran language that @code{f2c} -doesn't. +However, in code that makes heavy use of Fortran's +implicit-typing facility, this option might produce so +many warnings about cases that are working, it would be +hard to find the one or two that represent bugs. +This is why so many experienced Fortran programmers strongly +recommend widespread use of the @code{IMPLICIT NONE} statement, +despite it not being standard FORTRAN 77, to completely turn +off implicit typing. +(@code{g77} supports @code{IMPLICIT NONE}, as do almost all +FORTRAN 77 compilers.) + +Note that @samp{-Wimplicit} catches only implicit typing of +@emph{names}. +It does not catch implicit typing of expressions such +as @samp{X**(2/3)}. +Such expressions can be buggy as well---in fact, @samp{X**(2/3)} +is equivalent to @samp{X**0}, due to the way Fortran expressions +are given types and then evaluated. +(In this particular case, the programmer probably wanted +@samp{X**(2./3.)}.) + +@node Variables Assumed To Be Zero +@subsection Variables Assumed To Be Zero +@cindex zero-initialized variables +@cindex variables assumed to be zero +@cindex uninitialized variables -However, @code{f2c} offers a few that @code{g77} doesn't, like -fairly complete support for @samp{INTEGER*2}. -It is expected that @code{g77} will offer some or all of these missing -features at some time in the future. -(Version 0.5.18 of @code{g77} offers some rudimentary support for some -of these features.) +Many Fortran programs were developed on systems that provided +automatic initialization of all, or some, variables and arrays +to zero. +As a result, many of these programs depend, sometimes +inadvertently, on this behavior, though to do so violates +the Fortran standards. + +You can ask @code{g77} for this behavior by specifying the +@samp{-finit-local-zero} option when compiling Fortran code. +(You might want to specify @samp{-fno-automatic} as well, +to avoid code-size inflation for non-optimized compilations.) + +Note that a program that works better when compiled with the +@samp{-finit-local-zero} option +is almost certainly depending on a particular system's, +or compiler's, tendency to initialize some variables to zero. +It might be worthwhile finding such cases and fixing them, +using techniques such as compiling with the @samp{-O -Wuninitialized} +options using @code{g77}. + +@node Variables Assumed To Be Saved +@subsection Variables Assumed To Be Saved +@cindex variables retaining values across calls +@cindex saved variables +@cindex static variables + +Many Fortran programs were developed on systems that +saved the values of all, or some, variables and arrays +across procedure calls. +As a result, many of these programs depend, sometimes +inadvertently, on being able to assign a value to a +variable, perform a @code{RETURN} to a calling procedure, +and, upon subsequent invocation, reference the previously +assigned variable to obtain the value. + +They expect this despite not using the @code{SAVE} statement +to specify that the value in a variable is expected to survive +procedure returns and calls. +Depending on variables and arrays to retain values across +procedure calls without using @code{SAVE} to require it violates +the Fortran standards. + +You can ask @code{g77} to assume @code{SAVE} is specified for all +relevant (local) variables and arrays by using the +@samp{-fno-automatic} option. + +Note that a program that works better when compiled with the +@samp{-fno-automatic} option +is almost certainly depending on not having to use +the @code{SAVE} statement as required by the Fortran standard. +It might be worthwhile finding such cases and fixing them, +using techniques such as compiling with the @samp{-O -Wuninitialized} +options using @code{g77}. + +@node Unwanted Variables +@subsection Unwanted Variables + +The @samp{-Wunused} option can find bugs involving +implicit typing, sometimes +more easily than using @samp{-Wimplicit} in code that makes +heavy use of implicit typing. +An unused variable or array might indicate that the +spelling for its declaration is different from that of +its intended uses. -@node Compiler Options -@subsection Compiler Options +Other than cases involving typos, unused variables rarely +indicate actual bugs in a program. +However, investigating such cases thoroughly has, on occasion, +led to the discovery of code that had not been completely +written---where the programmer wrote declarations as needed +for the whole algorithm, wrote some or even most of the code +for that algorithm, then got distracted and forgot that the +job was not complete. + +@node Unused Arguments +@subsection Unused Arguments +@cindex unused arguments +@cindex arguments, unused -@code{g77} offers a whole bunch of compiler options that @code{f2c} doesn't. +As with unused variables, It is possible that unused arguments +to a procedure might indicate a bug. +Compile with @samp{-W -Wunused} option to catch cases of +unused arguments. -However, @code{f2c} offers a few that @code{g77} doesn't, like an -option to generate code to check array subscripts at run time. -It is expected that @code{g77} will offer some or all of these -missing options at some time in the future. +Note that @samp{-W} also enables warnings regarding overflow +of floating-point constants under certain circumstances. -@node Compiler Speed -@subsection Compiler Speed +@node Surprising Interpretations of Code +@subsection Surprising Interpretations of Code -Saving the steps of writing and then rereading C code is a big reason -why @code{g77} should be able to compile code much faster than using -@code{f2c} in conjunction with the equivalent invocation of @code{gcc}. +The @samp{-Wsuprising} option can help find bugs involving +expression evaluation or in +the way @code{DO} loops with non-integral iteration variables +are handled. +Cases found by this option might indicate a difference of +interpretation between the author of the code involved, and +a standard-conforming compiler such as @code{g77}. +Such a difference might produce actual bugs. -However, due to @code{g77}'s youth, lots of self-checking is still being -performed. -As a result, this improvement is as yet unrealized -(though the potential seems to be there for quite a big speedup -in the future). -It is possible that, as of version 0.5.18, @code{g77} -is noticably faster compiling many Fortran source files than using -@code{f2c} in conjunction with @code{gcc}. +In any case, changing the code to explicitly do what the +programmer might have expected it to do, so @code{g77} and +other compilers are more likely to follow the programmer's +expectations, might be worthwhile, especially if such changes +make the program work better. -@node Program Speed -@subsection Program Speed +@node Aliasing Assumed To Work +@subsection Aliasing Assumed To Work +@cindex -falias-check option +@cindex options, -falias-check +@cindex -fargument-alias option +@cindex options, -fargument-alias +@cindex -fargument-noalias option +@cindex options, -fargument-noalias +@cindex -fno-argument-noalias-global option +@cindex options, -fno-argument-noalias-global +@cindex aliasing +@cindex anti-aliasing +@cindex overlapping arguments +@cindex overlays +@cindex association, storage +@cindex storage association +@cindex scheduling of reads and writes +@cindex reads and writes, scheduling + +The @samp{-falias-check}, @samp{-fargument-alias}, +@samp{-fargument-noalias}, +and @samp{-fno-argument-noalias-global} options, +introduced in version 0.5.20 and +@code{g77}'s version 2.7.2.2.f.2 of @code{gcc}, +control the assumptions regarding aliasing +(overlapping) +of writes and reads to main memory (core) made +by the @code{gcc} back end. + +They are effective only when compiling with @samp{-O} (specifying +any level other than @samp{-O0}) or with @samp{-falias-check}. + +The default for Fortran code is @samp{-fargument-noalias-global}. +(The default for C code and code written in other C-based languages +is @samp{-fargument-alias}. +These defaults apply regardless of whether you use @code{g77} or +@code{gcc} to compile your code.) + +Note that, on some systems, compiling with @samp{-fforce-addr} in +effect can produce more optimal code when the default aliasing +options are in effect (and when optimization is enabled). + +If your program is not working when compiled with optimization, +it is possible it is violating the Fortran standards (77 and 90) +by relying on the ability to ``safely'' modify variables and +arrays that are aliased, via procedure calls, to other variables +and arrays, without using @code{EQUIVALENCE} to explicitly +set up this kind of aliasing. + +(The FORTRAN 77 standard's prohibition of this sort of +overlap, generally referred to therein as ``storage +assocation'', appears in Sections 15.9.3.6. +This prohibition allows implementations, such as @code{g77}, +to, for example, implement the passing of procedures and +even values in @code{COMMON} via copy operations into local, +perhaps more efficiently accessed temporaries at entry to a +procedure, and, where appropriate, via copy operations back +out to their original locations in memory at exit from that +procedure, without having to take into consideration the +order in which the local copies are updated by the code, +among other things.) + +To test this hypothesis, try compiling your program with +the @samp{-fargument-alias} option, which causes the +compiler to revert to assumptions essentially the same as +made by versions of @code{g77} prior to 0.5.20. + +If the program works using this option, that strongly suggests +that the bug is in your program. +Finding and fixing the bug(s) should result in a program that +is more standard-conforming and that can be compiled by @code{g77} +in a way that results in a faster executable. + +(You might want to try compiling with @samp{-fargument-noalias}, +a kind of half-way point, to see if the problem is limited to +aliasing between dummy arguments and @code{COMMON} variables---this +option assumes that such aliasing is not done, while still allowing +aliasing among dummy arguments.) + +An example of aliasing that is invalid according to the standards +is shown in the following program, which might @emph{not} produce +the expected results when executed: -@code{g77} has the potential to better optimize code than @code{f2c}, -even when @code{gcc} is used to compile the output of @code{f2c}, -because @code{f2c} must necessarily -translate Fortran into a somewhat lower-level language (C) that cannot -preserve all the information that is potentially useful for optimization, -while @code{g77} can gather, preserve, and transmit that information directly -to the GBE. +@example +I = 1 +CALL FOO(I, I) +PRINT *, I +END -For example, @code{g77} implements @samp{ASSIGN} and assigned -@samp{GOTO} using direct assignment of pointers to labels and direct -jumps to labels, whereas @code{f2c} maps the assigned labels to -integer values and then uses a C @samp{switch} statement to encode -the assigned @samp{GOTO} statements. +SUBROUTINE FOO(J, K) +J = J + K +K = J * K +PRINT *, J, K +END +@end example -However, as is typical, theory and reality don't quite match, at least -not in all cases, so it is still the case that @code{f2c} plus @code{gcc} -can generate code that is faster than @code{g77}. +The above program attempts to use the temporary aliasing of the +@samp{J} and @samp{K} arguments in @samp{FOO} to effect a +pathological behavior---the simultaneous changing of the values +of @emph{both} @samp{J} and @samp{K} when either one of them +is written. -It is hoped that version 0.5.18 of @code{g77} will offer default -settings and options that allow for better program speed, though -it is not yet known whether these same options, when applied to -a @code{gcc} compilation of @code{f2c} output, will improve the -speed of programs compiled using that method as well. +The programmer likely expects the program to print these values: -@node Ease of Debugging -@subsection Ease of Debugging +@example +2 4 +4 +@end example -Because @code{g77} compiles directly to assembler code like @code{gcc}, -instead of translating to an intermediate language (C) as does @code{f2c}, -support for debugging can be better for @code{g77} than @code{f2c}. +However, since the program is not standard-conforming, an +implementation's behavior when running it is undefined, because +subroutine @samp{FOO} modifies at least one of the arguments, +and they are aliased with each other. +(Even if one of the assignment statements was deleted, the +program would still violate these rules. +This kind of on-the-fly aliasing is permitted by the standard +only when none of the aliased items are defined, or written, +while the aliasing is in effect.) + +As a practical example, an optimizing compiler might schedule +the @samp{J =} part of the second line of @samp{FOO} @emph{after} +the reading of @samp{J} and @samp{K} for the @samp{J * K} expression, +resulting in the following output: -However, although @code{g77} might be somewhat more ``native'' in terms of -debugging support than @code{f2c} plus @code{gcc}, there still are a lot -of things ``not quite right''. -Many of the important ones should be resolved in the near future. +@example +2 2 +2 +@end example -For example, @code{g77} doesn't have to worry about reserved names -like @code{f2c} does. -Given @samp{FOR = WHILE}, @code{f2c} must necessarily -translate this to something @emph{other} than -@samp{for = while;}, because C reserves those words. +Essentially, compilers are promised (by the standard and, therefore, +by programmers who write code they claim to be standard-conforming) +that if they cannot detect aliasing via static analysis of a single +program unit's @code{EQUIVALENCE} and @code{COMMON} statements, no +such aliasing exists. +In such cases, compilers are free to assume that an assignment to +one variable will not change the value of another variable, allowing +it to avoid generating code to re-read the value of the other +variable, to re-schedule reads and writes, and so on, to produce +a faster executable. + +The same promise holds true for arrays (as seen by the called +procedure)---an element of one dummy array cannot be aliased +with, or overlap, any element of another dummy array or be +in a @code{COMMON} area known to the procedure. + +(These restrictions apply only when the procedure defines, or +writes to, one of the aliased variables or arrays.) + +Unfortunately, there is no way to find @emph{all} possible cases of +violations of the prohibitions against aliasing in Fortran code. +Static analysis is certainly imperfect, as is run-time analysis, +since neither can catch all violations. +(Static analysis can catch all likely violations, and some that +might never actually happen, while run-time analysis can catch +only those violations that actually happen during a particular +run. +Neither approach can cope with programs mixing Fortran code with +routines written in other languages, however.) + +Currently, @code{g77} provides neither static nor run-time facilities +to detect any cases of this problem, although other products might. +Run-time facilities are more likely to be offered by future +versions of @code{g77}, though patches improving @code{g77} so that +it provides either form of detection are welcome. + +@node Output Assumed To Flush +@subsection Output Assumed To Flush +@cindex ALWAYS_FLUSH +@cindex synchronous write errors +@cindex disk full +@cindex flushing output +@cindex fflush() +@cindex I/O, flushing +@cindex output, flushing +@cindex writes, flushing +@cindex NFS +@cindex network file system + +For several versions prior to 0.5.20, @code{g77} configured its +version of the @code{libf2c} run-time library so that one of +its configuration macros, @samp{ALWAYS_FLUSH}, was defined. + +This was done as a result of a belief that many programs expected +output to be flushed to the operating system (under UNIX, via +the @code{fflush()} library call) with the result that errors, +such as disk full, would be immediately flagged via the +relevant @code{ERR=} and @code{IOSTAT=} mechanism. + +Because of the adverse effects this approach had on the performance +of many programs, @code{g77} no longer configures @code{libf2c} +to always flush output. + +If your program depends on this behavior, either insert the +appropriate @samp{CALL FLUSH} statements, or modify the sources +to the @code{libf2c}, rebuild and reinstall @code{g77}, and +relink your programs with the modified library. + +(Ideally, @code{libf2c} would offer the choice at run-time, so +that a compile-time option to @code{g77} or @code{f2c} could +result in generating the appropriate calls to flushing or +non-flushing library routines.) + +@xref{Always Flush Output}, for information on how to modify +the @code{g77} source tree so that a version of @code{libf2c} +can be built and installed with the @samp{ALWAYS_FLUSH} macro defined. + +@node Large File Unit Numbers +@subsection Large File Unit Numbers +@cindex MXUNIT +@cindex unit numbers +@cindex maximum unit number +@cindex illegal unit number +@cindex increasing maximum unit number + +If your program crashes at run time with a message including +the text @samp{illegal unit number}, that probably is +a message from the run-time library, @code{libf2c}, used, and +distributed with, @code{g77}. + +The message means that your program has attempted to use a +file unit number that is out of the range accepted by +@code{libf2c}. +Normally, this range is 0 through 99, and the high end +of the range is controlled by a @code{libf2c} source-file +macro named @samp{MXUNIT}. + +If you can easily change your program to use unit numbers +in the range 0 through 99, you should do so. + +Otherwise, see @ref{Larger File Unit Numbers}, for information on how +to change @samp{MXUNIT} in @code{libf2c} so you can build and +install a new version of @code{libf2c} that supports the larger +unit numbers you need. + +@emph{Note:} While @code{libf2c} places a limit on the range +of Fortran file-unit numbers, the underlying library and operating +system might impose different kinds of limits. +For example, some systems limit the number of files simultaneously +open by a running program. +Information on how to increase these limits should be found +in your system's documentation. -However, @code{g77} does still uses things like an extra level of indirection -for @samp{ENTRY}-laden procedures---in this case, because the back end doesn't -yet support multiple entry points. +@node Overly Convenient Options +@section Overly Convenient Command-line Options +@cindex overly convenient options +@cindex options, overly convenient -Another example is that, given +These options should be used only as a quick-and-dirty way to determine +how well your program will run under different compilation models +without having to change the source. +Some are more problematic +than others, depending on how portable and maintainable you want the +program to be (and, of course, whether you are allowed to change it +at all is crucial). -@example -COMMON A, B -EQUIVALENCE (B, C) -@end example +You should not continue to use these command-line options to compile +a given program, but rather should make changes to the source code: -@noindent -the @code{g77} user should be able to access the variables directly, by name, -without having to traverse C-like structures and unions, while @code{f2c} -is unlikely to ever offer this ability (due to limitations in the -C language). +@table @code +@cindex -finit-local-zero option +@cindex options, -finit-local-zero +@item -finit-local-zero +(This option specifies that any uninitialized local variables +and arrays have default initialization to binary zeros.) -However, due to apparent bugs in the back end, @code{g77} currently doesn't -take advantage of this facility at all---it doesn't emit any debugging -information for @samp{COMMON} and @samp{EQUIVALENCE} areas, -other than information -on the array of @samp{char} it creates (and, in the case -of local @samp{EQUIVALENCE}, names) for each such area. +Many other compilers do this automatically, which means lots of +Fortran code developed with those compilers depends on it. -Yet another example is arrays. -@code{g77} represents them to the debugger -using the same ``dimensionality'' as in the source code, while @code{f2c} -must necessarily convert them all to one-dimensional arrays to fit -into the confines of the C language. -However, the level of support -offered by debuggers for interactive Fortran-style access to arrays -as compiled by @code{g77} can vary widely. -In some cases, it can actually -be an advantage that @code{f2c} converts everything to widely supported -C semantics. +It is safer (and probably +would produce a faster program) to find the variables and arrays that +need such initialization and provide it explicitly via @code{DATA}, so that +@samp{-finit-local-zero} is not needed. -In fairness, @code{g77} could do many of the things @code{f2c} does -to get things working at least as well as @code{f2c}---for now, -the maintainers have tended to prefer making @code{g77} work the -way they think it is supposed to, and find help improving the -other products (the GBE of @code{gcc}; @code{gdb}; and so on) -to get things working properly. +Consider using @samp{-Wuninitialized} (which requires @samp{-O}) to +find likely candidates, but +do not specify @samp{-finit-local-zero} or @samp{-fno-automatic}, +or this technique won't work. -@node Character and Hollerith Constants -@subsection Character and Hollerith Constants -@cindex character constants -@cindex constants, character -@cindex Hollerith constants -@cindex constants, Hollerith -@cindex trailing null byte -@cindex null byte, trailing -@cindex zero byte, trailing +@cindex -fno-automatic option +@cindex options, -fno-automatic +@item -fno-automatic +(This option specifies that all local variables and arrays +are to be treated as if they were named in @code{SAVE} statements.) -To avoid the extensive hassle that would be needed to avoid this, -@code{f2c} uses C character constants to encode character and Hollerith -constants. -That means a constant like @samp{'HELLO'} is translated to -@samp{"hello"} in C, which further means that an extra null byte is -present at the end of the constant. -This null byte is superfluous. +Many other compilers do this automatically, which means lots of +Fortran code developed with those compilers depends on it. -@code{g77} does not generate such null bytes. -This represents significant -savings of resources, such as on systems where @file{/dev/null} or -@file{/dev/zero} represent bottlenecks in the systems' performance, -because @code{g77} simply asks for fewer zeros from the operating -system than @code{f2c}. +The effect of this is that all non-automatic variables and arrays +are made static, that is, not placed on the stack or in heap storage. +This might cause a buggy program to appear to work better. +If so, rather than relying on this command-line option (and hoping all +compilers provide the equivalent one), add @code{SAVE} +statements to some or all program unit sources, as appropriate. +Consider using @samp{-Wuninitialized} (which requires @samp{-O}) +to find likely candidates, but +do not specify @samp{-finit-local-zero} or @samp{-fno-automatic}, +or this technique won't work. + +The default is @samp{-fautomatic}, which tells @code{g77} to try +and put variables and arrays on the stack (or in fast registers) +where possible and reasonable. +This tends to make programs faster. + +@cindex automatic arrays +@cindex arrays, automatic +@emph{Note:} Automatic variables and arrays are not affected +by this option. +These are variables and arrays that are @emph{necessarily} automatic, +either due to explicit statements, or due to the way they are +declared. +Examples include local variables and arrays not given the +@code{SAVE} attribute in procedures declared @code{RECURSIVE}, +and local arrays declared with non-constant bounds (automatic +arrays). +Currently, @code{g77} supports only automatic arrays, not +@code{RECURSIVE} procedures or other means of explicitly +specifying that variables or arrays are automatic. + +@cindex -fugly option +@cindex options, -fugly +@item -fugly +Fix the source code so that @samp{-fno-ugly} will work. +Note that, for many programs, it is difficult to practically +avoid using the features enabled via @samp{-fugly-init}, and these +features pose the lowest risk of writing nonportable code, among the +various ``ugly'' features. + +@cindex -f@var{group}-intrinsics-hide option +@cindex options, -f@var{group}-intrinsics-hide +@item -f@var{group}-intrinsics-hide +Change the source code to use @code{EXTERNAL} for any external procedure +that might be the name of an intrinsic. +It is easy to find these using @samp{-f@var{group}-intrinsics-disable}. +@end table + +@node Faster Programs +@section Faster Programs +@cindex speeding up programs +@cindex programs, speeding up + +Aside from the usual @code{gcc} options, such as @samp{-O}, +@samp{-ffast-math}, and so on, consider trying some of the +following approaches to speed up your program (once you get +it working). + +@menu +* Aligned Data:: +* Prefer Automatic Uninitialized Variables:: +* Avoid f2c Compatibility:: +* Use Submodel Options:: +@end menu + +@node Aligned Data +@subsection Aligned Data +@cindex data, aligned +@cindex stack, aligned +@cindex aligned data +@cindex aligned stack +@cindex Pentium optimizations +@cindex optimizations, Pentium + +On some systems, such as those with Pentium Pro CPUs, programs +that make heavy use of @code{REAL(KIND=2)} (@code{DOUBLE PRECISION}) +might run much slower +than possible due to the compiler not aligning these 64-bit +values to 64-bit boundaries in memory. +(The effect also is present, though +to a lesser extent, on the 586 (Pentium) architecture.) + +The Intel x86 architecture generally ensures that these programs will +work on all its implementations, +but particular implementations (such as Pentium Pro) +perform better with more strict alignment. + +There are a variety of approaches to use to address this problem, +in any combination: + +@itemize @bullet +@item +Order your @code{COMMON} and @code{EQUIVALENCE} areas such +that the variables and arrays with the widest alignment +guidelines come first. + +For example, on most systems, this would mean placing +@code{COMPLEX(KIND=2)}, @code{REAL(KIND=2)}, and +@code{INTEGER(KIND=2)} entities first, followed by @code{REAL(KIND=1)}, +@code{INTEGER(KIND=1)}, and @code{LOGICAL(KIND=1)} entities, then +@code{INTEGER(KIND=6)} entities, and finally @code{CHARACTER} +and @code{INTEGER(KIND=3)} entities. + +The reason to use such placement is it makes it more likely +that your data will be aligned properly, without requiring +you to do detailed analysis of each aggregate (@code{COMMON} +and @code{EQUIVALENCE}) area. + +Specifically, on systems where the above guidelines are +appropriate, placing @code{CHARACTER} entities before +@code{REAL(KIND=2)} entities can work just as well, +but only if the number of bytes occupied by the @code{CHARACTER} +entities is divisible by the recommended alignment for +@code{REAL(KIND=2)}. + +By ordering the placement of entities in aggregate +areas according to the simple guidelines above, you +avoid having to carefully count the number of bytes +occupied by each entity to determine whether the +actual alignment of each subsequent entity meets the +alignment guidelines for the type of that entity. + +@item +Use the (x86-specific) @samp{-malign-double} option when compiling +programs. +This will align only static data (entities in @code{COMMON} or +local entities with the @code{SAVE} attribute), +but it should probably always be +used with Fortran code on the 586 and 686 architectures for best +performance. + +This feature of @samp{-malign-double} means it may actually be best to +use it with @samp{-fno-automatic} even though the latter usually +produces worse code; at least, doing so will tend to produce more +consistent run times. + +Using @samp{-malign-double} and @samp{-fno-automatic} together is +apparently the only way to ensure that all doubles are correctly aligned +on GNU x86 systems without having to change @code{g77} itself as +described in the next item. +(Note that the @code{gcc} C extension @samp{__attribute__ ((aligned (8))} +also won't double-align the datum to which it is applied if that is allocated +on the stack.) +It isn't clear whether this deficiency also applies to +non-GNU based x86 systems (Solaris, DGUX et al), but it probably does. + +@item +Change the definition of the @samp{STACK_BOUNDARY} macro in +@file{gcc/config/i386/i386.h} from @samp{32} to +@samp{(TARGET_ALIGN_DOUBLE ? 64 : 32)}, and rebuild +@code{g77}. +@xref{Installation,,Installing GNU Fortran}, for more information. + +@item +Ensure that @file{crt0.o} or @file{crt1.o} +on your system guarantees a 64-bit +aligned stack for @code{main()}. +Some experimentation might be needed to determine this, and +access to source code to fix this. +While arranging this may typically +get more data properly aligned, it won't, by itself, +ensure they all are. + +One approach to testing this is to write a @code{main()} program +in C or assembler that outputs the address of the stack pointer +(and/or frame pointer), and visually inspect the output to see +if the stack is 64-bit aligned. +If it is, try renaming the executable to longer and shorter names +and running the program again. +If the name of the executable is placed on the stack by @file{crt0.o} +or @file{crt1.o}, +the location of the stack should move, and this might help determine +whether it is kept on a 64-bit boundary. +@end itemize + +Yes, this is all more complicated than it should be. +The problems are best solved in @code{gcc} and the +libraries for the operating systems on such systems, +which need to be continuously updated to provide the +best alignment for newly released processors. +Managing this while remaining compatible with ABIs +on various systems can be challenging. + +@node Prefer Automatic Uninitialized Variables +@subsection Prefer Automatic Uninitialized Variables + +If you're using @samp{-fno-automatic} already, you probably +should change your code to allow compilation with @samp{-fautomatic} +(the default), to allow the program to run faster. + +Similarly, you should be able to use @samp{-fno-init-local-zero} +(the default) instead of @samp{-finit-local-zero}. +This is because it is rare that every variable affected by these +options in a given program actually needs to +be so affected. + +For example, @samp{-fno-automatic}, which effectively @code{SAVE}s +every local non-automatic variable and array, affects even things like +@code{DO} iteration +variables, which rarely need to be @code{SAVE}d, and this often reduces +run-time performances. +Similarly, @samp{-fno-init-local-zero} forces such +variables to be initialized to zero---when @code{SAVE}d (such as when +@samp{-fno-automatic}), this by itself generally affects only +startup time for a program, but when not @code{SAVE}d, +it can slow down the procedure every time it is called. + +@xref{Overly Convenient Options,,Overly Convenient Command-Line Options}, +for information on the @samp{-fno-automatic} and +@samp{-finit-local-zero} options and how to convert +their use into selective changes in your own code. + +@node Avoid f2c Compatibility +@subsection Avoid f2c Compatibility +@cindex -fno-f2c option +@cindex options, -fno-f2c +@cindex @code{f2c} compatibility +@cindex compatibility, @code{f2c} + +If you aren't linking with any code compiled using +@code{f2c}, try using the @samp{-fno-f2c} option when +compiling @emph{all} the code in your program. +(Note that @code{libf2c} is @emph{not} an example of code +that is compiled using @code{f2c}---it is compiled by a C +compiler, typically @code{gcc}.) + +@node Use Submodel Options +@subsection Use Submodel Options +@cindex Pentium optimizations +@cindex optimizations, Pentium +@cindex 586/686 CPUs +@cindex submodels + +Using an appropriate @samp{-m} option to generate specific code for your +CPU may be worthwhile, though it may mean the executable won't run on +other versions of the CPU that don't support the same instruction set. +@xref{Submodel Options,,Hardware Models and Configurations,gcc,Using and +Porting GNU CC}. + +For recent CPUs that don't have explicit support in +the released version of @code{gcc}, it may still be possible to get +improvements. +For instance, the flags recommended for 586/686 +(Pentium(Pro)) chips for building the Linux kernel are: + +@example +-m486 -malign-loops=2 -malign-jumps=2 -malign-functions=2 +-fomit-frame-pointer +@end example + +@noindent @samp{-fomit-frame-pointer} will, however, inhibit debugging +on x86 systems. @node Trouble @chapter Known Causes of Trouble with GNU Fortran @@ -6227,7 +9890,7 @@ gcc,Using and Porting GNU CC}.) * Disappointments:: Regrettable things we can't change. * Non-bugs:: Things we think are right, but some others disagree. * Warnings and Errors:: Which problems in your code get warnings, - and which get errors. + and which get errors. @end menu @node But-bugs @@ -6256,32 +9919,19 @@ users. of Fortran programs, and the programs that compile them, that might be @emph{thought} to indicate bugs. -@itemize @bullet -@item -@cindex common blocks, large -@cindex large common blocks -@cindex linker errors -@cindex ld errors -@cindex errors, linker -On some older GNU/Linux systems, programs with common blocks larger -than 16MB cannot be linked without some kind of error -message being produced. - -This is a bug in older versions of @code{ld}, fixed in -more recent versions of @code{binutils}, such as version 2.6. - -@cindex @code{gdb} support -@cindex support, @code{gdb} -@item -There are some known problems when using @code{gdb} on code -compiled by @code{g77}. -Inadequate investigation as of the release of 0.5.16 results in not -knowing which products are the culprit, but @file{gdb-4.14} definitely -crashes when, for example, an attempt is made to print the contents -of a @samp{COMPLEX*16} dummy array, on at least some GNU/Linux machines, plus -some others. +@menu +* Cannot Link Fortran Programs:: Unresolved references. +* Large Common Blocks:: Problems on older GNU/Linux systems. +* Debugger Problems:: When the debugger crashes. +* NeXTStep Problems:: Misbehaving executables. +* Stack Overflow:: More misbehaving executables. +* Strange Behavior at Run Time:: Executables misbehaving due to + bugs in your program. +* Floating-point Errors:: The results look wrong, but@dots{}. +@end menu -@item +@node Cannot Link Fortran Programs +@subsection Cannot Link Fortran Programs @cindex unresolved reference (various) @cindex linking error for user code @cindex code, user @@ -6301,13 +9951,12 @@ It is unclear at this point whether there are legitimately installed systems where @samp{-lf2c -lm} is insufficient to resolve code produced by @code{g77}. -@item @cindex undefined reference (_main) @cindex linking error for user code @cindex ld error for user code @cindex code, user @cindex ld can't find _main -If your program doesn't link, due to unresolved references to names +If your program doesn't link due to unresolved references to names like @samp{_main}, make sure you're using the @code{g77} command to do the link, since this command ensures that the necessary libraries are loaded by specifying @samp{-lf2c -lm} when it invokes the @code{gcc} @@ -6317,10 +9966,39 @@ more about what actually happens when you use the @code{g77} and @code{gcc} commands.) Also, try specifying @samp{-lc} as the last item on the @code{g77} -command line, because some systems need it and @code{g77} doesn't do it -automatically. +command line, in case that helps. -@item +@node Large Common Blocks +@subsection Large Common Blocks +@cindex common blocks, large +@cindex large common blocks +@cindex linker errors +@cindex ld errors +@cindex errors, linker +On some older GNU/Linux systems, programs with common blocks larger +than 16MB cannot be linked without some kind of error +message being produced. + +This is a bug in older versions of @code{ld}, fixed in +more recent versions of @code{binutils}, such as version 2.6. + +@node Debugger Problems +@subsection Debugger Problems +@cindex @code{gdb} support +@cindex support, @code{gdb} +There are some known problems when using @code{gdb} on code +compiled by @code{g77}. +Inadequate investigation as of the release of 0.5.16 results in not +knowing which products are the culprit, but @file{gdb-4.14} definitely +crashes when, for example, an attempt is made to print the contents +of a @code{COMPLEX(KIND=2)} dummy array, on at least some GNU/Linux machines, plus +some others. + +@node NeXTStep Problems +@subsection NeXTStep Problems +@cindex NeXTStep problems +@cindex bus error +@cindex segmentation violation Developers of Fortran code on NeXTStep (all architectures) have to watch out for the following problem when writing programs with large, statically allocated (i.e. non-stack based) data structures @@ -6368,21 +10046,12 @@ data structures. not enough.) (The above item was contributed by Toon Moene -(@code{toon@@moene.indiv.nluug.nl}).) - -@item -@code{g77} rejects some particularly nonportable, -silent data-type conversions such as @samp{LOGICAL} -to @samp{REAL} (as in @samp{A=.FALSE.}, where @samp{A} -is type @samp{REAL}), that other compilers might -quietly accept. - -Some of these conversions are accepted by @code{g77} -when the @samp{-fugly} option is specified. +(@email{toon@@moene.indiv.nluug.nl}).) +@node Stack Overflow +@subsection Stack Overflow @cindex stack overflow @cindex segmentation violation -@item @code{g77} code might fail at runtime (probably with a ``segmentation violation'') due to overflowing the stack. This happens most often on systems with an environment @@ -6411,7 +10080,7 @@ non-automatic variables and arrays on the stack. However, if your program uses large automatic arrays (for example, has declarations like @samp{REAL A(N)} where @samp{A} is a local array and @samp{N} is a dummy or -@samp{COMMON} variable that can have a large value), +@code{COMMON} variable that can have a large value), neither use of @samp{-fno-automatic}, nor changing the cut-off point for @code{g77} for using the stack, will solve the problem by changing the placement of these @@ -6430,11 +10099,12 @@ same memory area, such that they are effectively combined, then a stack overflow probably indicates a program that is either simply too large for the system, or buggy.) +@node Strange Behavior at Run Time +@subsection Strange Behavior at Run Time @cindex segmentation violation @cindex bus error @cindex overwritten data @cindex data, overwritten -@item @code{g77} code might fail at runtime with ``segmentation violation'', ``bus error'', or even something as subtle as a procedure call overwriting a variable or array element that it is not supposed @@ -6469,7 +10139,117 @@ calling and called procedures. In the meantime, finding and fixing the programming bugs that lead to these behaviors is, ultimately, the user's responsibility, as difficult as that task can sometimes be. -@end itemize + +@node Floating-point Errors +@subsection Floating-point Errors +@cindex floating-point errors +@cindex rounding errors +@cindex inconsistent floating-point results +@cindex results, inconsistent +Some programs appear to produce inconsistent floating-point +results compiled by @code{g77} versus by other compilers. + +Often the reason for this behavior is the fact that floating-point +values are represented on almost all Fortran systems by +@emph{approximations}, and these approximations are inexact +even for apparently simple values like 0.1, 0.2, 0.3, 0.4, 0.6, +0.7, 0.8, 0.9, 1.1, and so on. +Most Fortran systems, including all current ports of @code{g77}, +use binary arithmetic to represent these approximations. + +Therefore, the exact value of any floating-point approximation +as manipulated by @code{g77}-compiled code is representable by +adding some combination of the values 1.0, 0.5, 0.25, 0.125, and +so on (just keep dividing by two) through the precision of the +fraction (typically around 23 bits for @code{REAL(KIND=1)}, 52 for +@code{REAL(KIND=2)}), then multiplying the sum by a integral +power of two (in Fortran, by @samp{2**N}) that typically is between +-127 and +128 for @code{REAL(KIND=1)} and -1023 and +1024 for +@code{REAL(KIND=2)}, then multiplying by -1 if the number +is negative. + +So, a value like 0.2 is exactly represented in decimal---since +it is a fraction, @samp{2/10}, with a denomenator that is compatible +with the base of the number system (base 10). +However, @samp{2/10} cannot be represented by any finite number +of sums of any of 1.0, 0.5, 0.25, and so on, so 0.2 cannot +be exactly represented in binary notation. + +(On the other hand, decimal notation can represent any binary +number in a finite number of digits. +Decimal notation cannot do so with ternary, or base-3, +notation, which would represent floating-point numbers as +sums of any of @samp{1/1}, @samp{1/3}, @samp{1/9}, and so on. +After all, no finite number of decimal digits can exactly +represent @samp{1/3}. +Fortunately, few systems use ternary notation.) + +Moreover, differences in the way run-time I/O libraries convert +between these approximations and the decimal representation often +used by programmers and the programs they write can result in +apparent differences between results that do not actually exist, +or exist to such a small degree that they usually are not worth +worrying about. + +For example, consider the following program: + +@example +PRINT *, 0.2 +END +@end example + +When compiled by @code{g77}, the above program might output +@samp{0.20000003}, while another compiler might produce a +executable that outputs @samp{0.2}. + +This particular difference is due to the fact that, currently, +conversion of floating-point values by the @code{libf2c} library, +used by @code{g77}, handles only double-precision values. + +Since @samp{0.2} in the program is a single-precision value, it +is converted to double precision (still in binary notation) +before being converted back to decimal. +The conversion to binary appends _binary_ zero digits to the +original value---which, again, is an inexact approximation of +0.2---resulting in an approximation that is much less exact +than is connoted by the use of double precision. + +(The appending of binary zero digits has essentially the same +effect as taking a particular decimal approximation of +@samp{1/3}, such as @samp{0.3333333}, and appending decimal +zeros to it, producing @samp{0.33333330000000000}. +Treating the resulting decimal approximation as if it really +had 18 or so digits of valid precision would make it seem +a very poor approximation of @samp{1/3}.) + +As a result of converting the single-precision approximation +to double precision by appending binary zeros, the conversion +of the resulting double-precision +value to decimal produces what looks like an incorrect +result, when in fact the result is @emph{inexact}, and +is probably no less inaccurate or imprecise an approximation +of 0.2 than is produced by other compilers that happen to output +the converted value as ``exactly'' @samp{0.2}. +(Some compilers behave in a way that can make them appear +to retain more accuracy across a conversion of a single-precision +constant to double precision. +@xref{Context-Sensitive Constants}, to see why +this practice is illusory and even dangerous.) + +Note that a more exact approximation of the constant is +computed when the program is changed to specify a +double-precision constant: + +@example +PRINT *, 0.2D0 +END +@end example + +Future versions of @code{g77} and/or @code{libf2c} might convert +single-precision values directly to decimal, +instead of converting them to double precision first. +This would tend to result in output that is more consistent +with that produced by some other Fortran implementations. @include bugs.texi @@ -6480,15 +10260,111 @@ This section lists features we know are missing from @code{g77}, and which we want to add someday. (There is no priority implied in the ordering below.) -@itemize @bullet -@item +@menu +GNU Fortran language: +* Better Source Model:: +* Fortran 90 Support:: +* Intrinsics in PARAMETER Statements:: +* SELECT CASE on CHARACTER Type:: +* RECURSIVE Keyword:: +* Popular Non-standard Types:: +* Full Support for Compiler Types:: +* Array Bounds Expressions:: +* POINTER Statements:: +* Sensible Non-standard Constructs:: +* FLUSH Statement:: +* Expressions in FORMAT Statements:: +* Explicit Assembler Code:: + +GNU Fortran dialects: +* Old-style PARAMETER Statements:: +* TYPE and ACCEPT I/O Statements:: +* STRUCTURE UNION RECORD MAP:: +* OPEN CLOSE and INQUIRE Keywords:: +* ENCODE and DECODE:: +* Suppressing Space Padding:: +* Fortran Preprocessor:: +* Bit Operations on Floating-point Data:: + +New facilities: +* POSIX Standard:: +* Floating-point Exception Handling:: +* Nonportable Conversions:: +* Large Automatic Arrays:: +* Support for Threads:: +* Increasing Precision/Range:: + +Better diagnostics: +* Gracefully Handle Sensible Bad Code:: +* Non-standard Conversions:: +* Non-standard Intrinsics:: +* Modifying DO Variable:: +* Better Pedantic Compilation:: +* Warn About Implicit Conversions:: +* Invalid Use of Hollerith Constant:: +* Dummy Array Without Dimensioning Dummy:: +* Ambiguous Dialects:: +* Unused Labels:: +* Informational Messages:: + +Run-time facilities: +* Uninitialized Variables at Run Time:: +* Bounds Checking at Run Time:: + +Debugging: +* Labels Visible to Debugger:: +@end menu + +@node Better Source Model +@subsection Better Source Model + +@code{g77} needs to provide, as the default source-line model, +a ``pure visual'' mode, where +the interpretation of a source program in this mode can be accurately +determined by a user looking at a traditionally displayed rendition +of the program (assuming the user knows whether the program is fixed +or free form). + +The design should assume the user cannot tell tabs from spaces +and cannot see trailing spaces on lines, but has canonical tab stops +and, for fixed-form source, has the ability to always know exactly +where column 72 is (since the Fortran standard itself requires +this for fixed-form source). + +This would change the default treatment of fixed-form source +to not treat lines with tabs as if they were infinitely long---instead, +they would end at column 72 just as if the tabs were replaced +by spaces in the canonical way. + +As part of this, provide common alternate models (Digital, @code{f2c}, +and so on) via command-line options. +This includes allowing arbitrarily long +lines for free-form source as well as fixed-form source and providing +various limits and diagnostics as appropriate. + +@cindex sequence numbers +@cindex columns 73 through 80 +Also, @code{g77} should offer, perhaps even default to, warnings +when characters beyond the last valid column are anything other +than spaces. +This would mean code with ``sequence numbers'' in columns 73 through 80 +would be rejected, and there's a lot of that kind of code around, +but one of the most frequent bugs encountered by new users is +accidentally writing fixed-form source code into and beyond +column 73. +So, maybe the users of old code would be able to more easily handle +having to specify, say, a @code{-Wno-col73to80} option. + +@node Fortran 90 Support +@subsection Fortran 90 Support @cindex Fortran 90 support @cindex support, Fortran 90 + @code{g77} does not support many of the features that distinguish Fortran 90 (and, now, Fortran 95) from ANSI FORTRAN 77. -Some Fortran 90 features are listed here, because they +Some Fortran 90 features are supported, because they make sense to offer even to die-hard users of F77. For example, many of them codify various ways F77 has been extended to meet users' needs during its tenure, @@ -6497,7 +10373,7 @@ way to meet those same needs, even if it offers compatibility with one or more of the ways those needs were met by other F77 compilers in the industry. -Still, many important F90 features are not listed here, +Still, many important F90 features are not supported, because no attempt has been made to research each and every feature and assess its viability in @code{g77}. In the meantime, users who need those features must @@ -6505,26 +10381,151 @@ use Fortran 90 compilers anyway, and the best approach to adding some F90 features to GNU Fortran might well be to fund a comprehensive project to create GNU Fortran 95. -@item -@cindex AND intrinsic -@cindex intrinsics, AND -@cindex OR intrinsic -@cindex intrinsics, OR -@cindex SHIFT intrinsic -@cindex intrinsics, SHIFT -@code{g77} does not allow @samp{REAL} and other non-integral types for -arguments to intrinsics like @samp{AND}, @samp{OR}, and @samp{SHIFT}. +@node Intrinsics in PARAMETER Statements +@subsection Intrinsics in @code{PARAMETER} Statements +@cindex PARAMETER statement +@cindex statements, PARAMETER -@item +@code{g77} doesn't allow intrinsics in @code{PARAMETER} statements. +This feature is considered to be absolutely vital, even though it +is not standard-conforming, and is scheduled for version 0.6. + +Related to this, @code{g77} doesn't allow non-integral +exponentiation in @code{PARAMETER} statements, such as +@samp{PARAMETER (R=2**.25)}. +It is unlikely @code{g77} will ever support this feature, +as doing it properly requires complete emulation of +a target computer's floating-point facilities when +building @code{g77} as a cross-compiler. +But, if the @code{gcc} back end is enhanced to provide +such a facility, @code{g77} will likely use that facility +in implementing this feature soon afterwards. + +@node SELECT CASE on CHARACTER Type +@subsection @code{SELECT CASE} on @code{CHARACTER} Type + +Character-type selector/cases for @code{SELECT CASE} currently +are not supported. + +@node RECURSIVE Keyword +@subsection @code{RECURSIVE} Keyword +@cindex RECURSIVE keyword +@cindex keywords, RECURSIVE +@cindex recursion, lack of +@cindex lack of recursion + +@code{g77} doesn't support the @code{RECURSIVE} keyword that +F90 compilers do. +Nor does it provide any means for compiling procedures +designed to do recursion. + +All recursive code can be rewritten to not use recursion, +but the result is not pretty. + +@node Increasing Precision/Range +@subsection Increasing Precision/Range +@cindex -r8 +@cindex -i8 +@cindex f2c +@cindex increasing precision +@cindex precision, increasing +@cindex increasing range +@cindex range, increasing +@cindex Toolpack +@cindex Netlib + +Some compilers, such as @code{f2c}, have an option (@samp{-r8} or +similar) that provides automatic treatment of @code{REAL} +entities such that they have twice the storage size, and +a corresponding increase in the range and precision, of what +would normally be the @code{REAL(KIND=1)} (default @code{REAL}) type. +(This affects @code{COMPLEX} the same way.) + +They also typically offer another option (@samp{-i8}) to increase +@code{INTEGER} entities so they are twice as large +(with roughly twice as much range). + +(There are potential pitfalls in using these options.) + +@code{g77} does not yet offer any option that performs these +kinds of transformations. +Part of the problem is the lack of detailed specifications regarding +exactly how these options affect the interpretation of constants, +intrinsics, and so on. + +Until @code{g77} addresses this need, programmers could improve +the portability of their code by modifying it to not require +compile-time options to produce correct results. +Some free tools are available which may help, specifically +in Toolpack (which one would expect to be sound) and the @file{fortran} +section of the Netlib repository. + +Use of preprocessors can provide a fairly portable means +to work around the lack of widely portable methods in the Fortran +language itself (though increasing acceptance of Fortran 90 would +alleviate this problem). + +@node Popular Non-standard Types +@subsection Popular Non-standard Types @cindex INTEGER*2 support @cindex LOGICAL*1 support -@code{g77} doesn't support @samp{INTEGER*2}, @samp{LOGICAL*1}, and similar. -Version 0.6 will provide full support for this extremely -important set of features. + +@code{g77} doesn't fully support @code{INTEGER*2}, @code{LOGICAL*1}, +and similar. +Version 0.6 will provide full support for this very +popular set of features. In the meantime, version 0.5.18 provides rudimentary support for them. -@item +@node Full Support for Compiler Types +@subsection Full Support for Compiler Types + +@cindex REAL*16 support +@code{g77} doesn't support @code{INTEGER}, @code{REAL}, and @code{COMPLEX} equivalents +for @emph{all} applicable back-end-supported types (@code{char}, @code{short int}, +@code{int}, @code{long int}, @code{long long int}, and @code{long double}). +This means providing intrinsic support, and maybe constant +support (using F90 syntax) as well, and, for most +machines will result in automatic support of @code{INTEGER*1}, +@code{INTEGER*2}, @code{INTEGER*8}, maybe even @code{REAL*16}, +and so on. +This is scheduled for version 0.6. + +@node Array Bounds Expressions +@subsection Array Bounds Expressions +@cindex array elements, in adjustable array bounds +@cindex function references, in adjustable array bounds +@cindex array bounds, adjustable +@cindex DIMENSION statement +@cindex statements, DIMENSION + +@code{g77} doesn't support more general expressions to dimension +arrays, such as array element references, function +references, etc. + +For example, @code{g77} currently does not accept the following: + +@example +SUBROUTINE X(M, N) +INTEGER N(10), M(N(2), N(1)) +@end example + +@node POINTER Statements +@subsection POINTER Statements +@cindex POINTER statement +@cindex statements, POINTER +@cindex Cray pointers + +@code{g77} doesn't support pointers or allocatable objects +(other than automatic arrays). +This set of features is +probably considered just behind intrinsics +in @code{PARAMETER} statements on the list of large, +important things to add to @code{g77}. + +@node Sensible Non-standard Constructs +@subsection Sensible Non-standard Constructs + @code{g77} rejects things other compilers accept, like @samp{INTRINSIC SQRT,SQRT}. As time permits in the future, some of these things that are easy for @@ -6532,7 +10533,8 @@ humans to read and write and unlikely to be intended to mean something else will be accepted by @code{g77} (though @samp{-fpedantic} should trigger warnings about such non-standard constructs). -In the meantime, you might as well fix your code +Until @code{g77} no longer gratuitously rejects sensible code, +you might as well fix your code to be more standard-conforming and portable. The kind of case that is important to except from the @@ -6540,19 +10542,19 @@ recommendation to change your code is one where following good coding rules would force you to write non-standard code that nevertheless has a clear meaning. -For example, when writing an @samp{INCLUDE} file that +For example, when writing an @code{INCLUDE} file that defines a common block, it might be appropriate to -include a @samp{SAVE} statement for the common block +include a @code{SAVE} statement for the common block (such as @samp{SAVE /CBLOCK/}), so that variables defined in the common block retain their values even when all procedures declaring the common block become inactive (return to their callers). -However, putting @samp{SAVE} statements in an @samp{INCLUDE} +However, putting @code{SAVE} statements in an @code{INCLUDE} file would prevent otherwise standard-conforming code -from also specifying the @samp{SAVE} statement, by itself, +from also specifying the @code{SAVE} statement, by itself, to indicate that all local variables and arrays are to -have the @samp{SAVE} attribute. +have the @code{SAVE} attribute. For this reason, @code{g77} already has been changed to allow this combination, because although the general @@ -6575,42 +10577,100 @@ specification of an attribute), please submit a bug report with an explanation, so we can consider fixing @code{g77} just for cases like yours. -@item +@node FLUSH Statement +@subsection @code{FLUSH} Statement + +@code{g77} could perhaps use a @code{FLUSH} statement that +does what @samp{CALL FLUSH} does, +but that supports @samp{*} as the unit designator (same unit as for +@code{PRINT}) and accepts @code{ERR=} and/or @code{IOSTAT=} +specifiers. + +@node Expressions in FORMAT Statements +@subsection Expressions in @code{FORMAT} Statements +@cindex FORMAT statement +@cindex statements, FORMAT + +@code{g77} doesn't support @samp{FORMAT(I<J>)} and the like. +Supporting this requires a significant redesign or replacement +of @code{libf2c}. + +However, a future version of @code{g77} might support +this construct when the expression is constant. For +example: + +@example + PARAMETER (IWIDTH = 12) +10 FORMAT (I<IWIDTH>) +@end example + +In the meantime, at least for output (@code{PRINT} and +@code{WRITE}), Fortran code making use of this feature can +be rewritten to avoid it by constructing the @code{FORMAT} +string in a @code{CHARACTER} variable or array, then +using that variable or array in place of the @code{FORMAT} +statement label to do the original @code{PRINT} or @code{WRITE}. + +Many uses of this feature on input can be rewritten this way +as well, but not all can. +For example, this can be rewritten: + +@example + READ 20, I +20 FORMAT (I<J>) +@end example + +However, this cannot, in general, be rewritten, especially +when @code{ERR=} and @code{END=} constructs are employed: + +@example + READ 30, J, I +30 FORMAT (I<J>) +@end example + +@node Explicit Assembler Code +@subsection Explicit Assembler Code + +@code{g77} needs to provide some way, a la @code{gcc}, for @code{g77} +code to specify explicit assembler code. + +@node Old-style PARAMETER Statements +@subsection Old-style PARAMETER Statements @cindex PARAMETER statement @cindex statements, PARAMETER + @code{g77} doesn't accept @samp{PARAMETER I=1}. Supporting this obsolete form of -the @samp{PARAMETER} statement would not be particularly hard, as most of the +the @code{PARAMETER} statement would not be particularly hard, as most of the parsing code is already in place and working. Until time/money is spent implementing it, you might as well fix your code to use the standard form, @samp{PARAMETER (I=1)} (possibly needing -@samp{INTEGER I} preceding the @samp{PARAMETER} statement as well, -otherwise, in the obsolete form of @samp{PARAMETER}, the +@samp{INTEGER I} preceding the @code{PARAMETER} statement as well, +otherwise, in the obsolete form of @code{PARAMETER}, the type of the variable is set from the type of the constant being assigned to it). -@item -@cindex POINTER statement -@cindex statements, POINTER -@cindex Cray pointers -@code{g77} doesn't support pointers or allocatable objects. -This set of features is -probably considered just behind @samp{INTEGER*2} and intrinsics -in @samp{PARAMETER} statements on the list of large, -important things to add to @code{g77}. - +@node TYPE and ACCEPT I/O Statements +@subsection @code{TYPE} and @code{ACCEPT} I/O Statements @cindex TYPE statement @cindex statements, TYPE @cindex ACCEPT statement @cindex statements, ACCEPT -@item -@code{g77} doesn't support the I/O statements @samp{TYPE} and -@samp{ACCEPT}. + +@code{g77} doesn't support the I/O statements @code{TYPE} and +@code{ACCEPT}. These are common extensions that should be easy to support, but also are fairly easy to work around in user code. +Generally, any @samp{TYPE fmt,list} I/O statement can be replaced +by @samp{PRINT fmt,list}. +And, any @samp{ACCEPT fmt,list} statement can be +replaced by @samp{READ fmt,list}. + +@node STRUCTURE UNION RECORD MAP +@subsection @code{STRUCTURE}, @code{UNION}, @code{RECORD}, @code{MAP} @cindex STRUCTURE statement @cindex statements, STRUCTURE @cindex UNION statement @@ -6619,20 +10679,37 @@ but also are fairly easy to work around in user code. @cindex statements, RECORD @cindex MAP statement @cindex statements, MAP -@item -@code{g77} doesn't support @samp{STRUCTURE}, @samp{UNION}, @samp{RECORD}, -@samp{MAP}. + +@code{g77} doesn't support @code{STRUCTURE}, @code{UNION}, @code{RECORD}, +@code{MAP}. This set of extensions is quite a bit lower on the list of large, important things to add to @code{g77}, partly because it requires a great deal of work either upgrading or replacing @code{libf2c}. +@node OPEN CLOSE and INQUIRE Keywords +@subsection @code{OPEN}, @code{CLOSE}, and @code{INQUIRE} Keywords +@cindex disposition of files +@cindex OPEN statement +@cindex statements, OPEN +@cindex CLOSE statement +@cindex statements, CLOSE +@cindex INQUIRE statement +@cindex statements, INQUIRE + +@code{g77} doesn't have support for keywords such as @code{DISP='DELETE'} in +the @code{OPEN}, @code{CLOSE}, and @code{INQUIRE} statements. +These extensions are easy to add to @code{g77} itself, but +require much more work on @code{libf2c}. + +@node ENCODE and DECODE +@subsection @code{ENCODE} and @code{DECODE} @cindex ENCODE statement @cindex statements, ENCODE @cindex DECODE statement @cindex statements, DECODE -@item -@code{g77} doesn't support @samp{ENCODE} or @samp{DECODE}. + +@code{g77} doesn't support @code{ENCODE} or @code{DECODE}. These statements are best replaced by READ and WRITE statements involving internal files (CHARACTER variables and arrays). @@ -6647,6 +10724,7 @@ For example, replace a code fragment like 9000 FORMAT (1X, 3(F10.5)) @end example +@noindent with: @example @@ -6667,6 +10745,7 @@ Similarly, replace a code fragment like 9000 FORMAT (1X, 'OUTPUT IS ', 3(F10.5)) @end example +@noindent with: @example @@ -6677,222 +10756,222 @@ with: 9000 FORMAT (1X, 'OUTPUT IS ', 3(F10.5)) @end example -It is entirely possible that @samp{ENCODE} and @samp{DECODE} will +It is entirely possible that @code{ENCODE} and @code{DECODE} will be supported by a future version of @code{g77}. -@cindex disposition of files -@cindex OPEN statement -@cindex statements, OPEN -@cindex CLOSE statement -@cindex statements, CLOSE -@cindex INQUIRE statement -@cindex statements, INQUIRE -@item -There is no support for keywords such as @samp{DISP='DELETE'} in -the @samp{OPEN}, @samp{CLOSE}, and @samp{INQUIRE} statements. -These extensions are easy to add to @code{g77} itself, but -require much more work on @code{libf2c}. +@node Suppressing Space Padding +@subsection Suppressing Space Padding of Source Lines -@cindex PARAMETER statement -@cindex statements, PARAMETER -@item -@code{g77} doesn't allow intrinsics in @samp{PARAMETER} statements. -This feature is considered to be absolutely vital, even though it -is not standard-conforming, and is scheduled for version 0.6. +@code{g77} should offer VXT-Fortran-style suppression of virtual +spaces at the end of a source line +if an appropriate command-line option is specified. -Related to this, @code{g77} doesn't allow non-integral -exponentiation in @samp{PARAMETER} statements, such as -@samp{PARAMETER (R=2**.25)}. -It is unlikely @code{g77} will ever support this feature, -as doing it properly requires complete emulation of -a target computer's floating-point facilities when -building @code{g77} as a cross-compiler. -But, if the @code{gcc} back end is enhanced to provide -such a facility, @code{g77} will likely use that facility -in implementing this feature soon afterwards. +This affects cases where +a character constant is continued onto the next line in a fixed-form +source file, as in the following example: -@cindex FORMAT statement -@cindex statements, FORMAT -@item -@code{g77} doesn't support @samp{FORMAT(I<J>)} and the like. -Supporting this requires a significant redesign or replacement -of @code{libf2c}. +@example +10 PRINT *,'HOW MANY + 1 SPACES?' +@end example -@cindex RECURSIVE keyword -@cindex keywords, RECURSIVE -@cindex recursion, lack of -@cindex lack of recursion -@item -@code{g77} doesn't support the @samp{RECURSIVE} keyword that -F90 compilers do. -Nor does it provide any means for compiling procedures -designed to do recursion. +@noindent +@code{g77}, and many other compilers, virtually extend +the continued line through column 72 with spaces that become part +of the character constant, but Digital Fortran normally didn't, +leaving only one space between @samp{MANY} and @samp{SPACES?} +in the output of the above statement. + +Fairly recently, at least one version of Digital Fortran +was enhanced to provide the other behavior when a +command-line option is specified, apparently due to demand +from readers of the USENET group @file{comp.lang.fortran} +to offer conformance to this widespread practice in the +industry. +@code{g77} should return the favor by offering conformance +to Digital's approach to handling the above example. + +@node Fortran Preprocessor +@subsection Fortran Preprocessor + +@code{g77} should offer a preprocessor designed specifically +for Fortran to replace @samp{cpp -traditional}. +There are several out there worth evaluating, at least. + +Such a preprocessor would recognize Hollerith constants, +properly parse comments and character constants, and so on. + +@node Bit Operations on Floating-point Data +@subsection Bit Operations on Floating-point Data +@cindex AND intrinsic +@cindex intrinsics, AND +@cindex OR intrinsic +@cindex intrinsics, OR +@cindex SHIFT intrinsic +@cindex intrinsics, SHIFT + +@code{g77} does not allow @code{REAL} and other non-integral types for +arguments to intrinsics like @code{AND}, @code{OR}, and @code{SHIFT}. + +For example, this program is rejected by @code{g77}, because +the intrinsic @code{IAND} does not accept @code{REAL} arguments: + +@example +DATA A/7.54/, B/9.112/ +PRINT *, IAND(A, B) +END +@end example + +@node POSIX Standard +@subsection @code{POSIX} Standard + +@code{g77} should support the POSIX standard for Fortran. + +@node Floating-point Exception Handling +@subsection Floating-point Exception Handling +@cindex floating point exceptions +@cindex exceptions, floating point +@cindex FPE handling +@cindex NaN values + +The @code{gcc} backend and, consequently, @code{g77}, currently provides no +control over whether or not floating-point exceptions are trapped or +ignored. +(Ignoring them typically results in NaN values being +propagated in systems that conform to IEEE 754.)@ +The behaviour is inherited from the system-dependent startup code. + +Most systems provide some C-callable mechanism to change this; this can +be invoked at startup using @code{gcc}'s @code{constructor} attribute. +For example, just compiling and linking the following C code with your +program will turn on exception trapping for the ``common'' exceptions +on an x86-based GNU system: +@smallexample +#include <fpu_control.h> +void __attribute__ ((constructor)) +trapfpe () @{ + (void) __setfpucw (_FPU_DEFAULT & + ~(_FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM)); +@} +@end smallexample + +@node Nonportable Conversions +@subsection Nonportable Conversions +@cindex nonportable conversions +@cindex conversions, nonportable + +@code{g77} doesn't accept some particularly nonportable, +silent data-type conversions such as @code{LOGICAL} +to @code{REAL} (as in @samp{A=.FALSE.}, where @samp{A} +is type @code{REAL}), that other compilers might +quietly accept. + +Some of these conversions are accepted by @code{g77} +when the @samp{-fugly} option is specified. +Perhaps it should accept more or all of them. + +@node Large Automatic Arrays +@subsection Large Automatic Arrays @cindex automatic arrays @cindex arrays, automatic -@item -Automatic arrays are always allocated on the stack. + +Currently, automatic arrays always are allocated on the stack. For situations where the stack cannot be made large enough, @code{g77} should offer a compiler option that specifies allocation of automatic arrays in heap storage. +@node Support for Threads +@subsection Support for Threads @cindex threads @cindex parallel processing -@item + Neither the code produced by @code{g77} nor the @code{libf2c} library are thread-safe, nor does @code{g77} have support for parallel processing (other than the instruction-level parallelism available on some processors). A package such as PVM might help here. -@item -Need option to suppress information messages (notes). -@samp{-w} does this but also suppresses warnings. -The default should be to suppress info messages. - -@item -Provide some way, a la @code{gcc}, for @code{g77} code to specify assembler -code. - -@item -Support @samp{INTEGER}, @samp{REAL}, and @samp{COMPLEX} equivalents -for all applicable back-end-supported types (@samp{char}, @samp{short int}, -@samp{int}, @samp{long int}, @samp{long long int}, and @samp{long double}). -This means providing intrinsic support, and maybe constant -support (using F90 syntax) as well, and, for most -machines will result in automatic support of @samp{INTEGER*1}, -@samp{INTEGER*2}, @samp{INTEGER*8}, and so on. -This is scheduled for version 0.6. - -@item -Provide as the default source-line model a ``pure visual'' mode, where -the interpretation of a source program in this mode can be accurately -determined by a user looking at a traditionally displayed rendition -of the program (assuming the user knows whether the program is fixed -or free form). +@node Gracefully Handle Sensible Bad Code +@subsection Gracefully Handle Sensible Bad Code -That is, assume the user cannot tell tabs from spaces -and cannot see trailing spaces on lines, but has canonical tab stops -and, for fixed-form source, has the ability to always know exactly -where column 72 is. +@code{g77} generally should continue processing for +warnings and recoverable (user) errors whenever possible---that +is, it shouldn't gratuitously make bad or useless code. -This would change the default treatment of fixed-form source -to not treat lines with tabs as if they were infinitely long---instead, -they would end at column 72 just as if the tabs were replaced -by spaces in the canonical way. - -As part of this, provide common alternate models (Digital, @code{f2c}, -and so on) via command-line options. -This includes allowing arbitrarily long -lines for free-form source as well as fixed-form source and providing -various limits and diagnostics as appropriate. +For example: -@cindex array elements, in adjustable array bounds -@cindex function references, in adjustable array bounds -@cindex array bounds, adjustable -@cindex DIMENSION statement -@cindex statements, DIMENSION -@item -Support more general expressions to dimension -arrays, such as array element references, function -references, etc. +@example +INTRINSIC ZABS +CALL FOO(ZABS) +END +@end example -@item -A @samp{FLUSH} statement that does what many systems provide via -@samp{CALL FLUSH}, -but that supports @samp{*} as the unit designator (same unit as for -@samp{PRINT}). +@noindent +When compiling the above with @samp{-ff2c-intrinsics-disable}, +@code{g77} should indeed complain about passing @code{ZABS}, +but it still should compile, instead of rejecting +the entire @code{CALL} statement. +(Some of this is related to improving +the compiler internals to improve how statements are analyzed.) -@item -Character-type selector/cases for @samp{SELECT CASE}. +@node Non-standard Conversions +@subsection Non-standard Conversions -@item -Option to initialize everything not explicitly initialized to ``weird'' -(machine-dependent) values, e.g. NANs, bad (non-@samp{NULL}) pointers, and -largest-magnitude integers. +@samp{-Wconversion} and related should flag places where non-standard +conversions are found. +Perhaps much of this would be part of @samp{-Wugly*}. -@item -Add run-time bounds-checking of array/subscript references a la @code{f2c}. +@node Non-standard Intrinsics +@subsection Non-standard Intrinsics -@item -Output labels for use by debuggers that know how to support them. -Same with weirder things like construct names. -It is not yet known if any debug formats or debuggers support these. +@code{g77} needs a new option, like @samp{-Wintrinsics}, to warn about use of +non-standard intrinsics without explicit @code{INTRINSIC} statements for them. +This would help find code that might fail silently when ported to another +compiler. -@item -Support the POSIX standard for Fortran. +@node Modifying DO Variable +@subsection Modifying @code{DO} Variable -@item -Support Digital-style lossage of virtual blanks at end of source line -if some command-line option specified. +@code{g77} should warn about modifying @code{DO} variables +via @code{EQUIVALENCE}. +(The internal information gathered to produce this warning +might also be useful in setting the +internal ``doiter'' flag for a variable or even array +reference within a loop, since that might produce faster code someday.) -This affects cases where -a character constant is continued onto the next line in a fixed-form -source file, as in the following example: +For example, this code is invalid, so @code{g77} should warn about +the invalid assignment to @samp{NOTHER}: @example -10 PRINT *,'HOW MANY - 1 SPACES?' +EQUIVALENCE (I, NOTHER) +DO I = 1, 100 + IF (I.EQ. 10) NOTHER = 20 +END DO @end example -@code{g77}, and many other compilers, virtually extend -the continued line through column 72 with blanks that become part -of the character constant, but Digital Fortran normally didn't, -leaving only one space between @samp{MANY} and @samp{SPACES?} -in the output of the above statement. - -Fairly recently, at least one version of Digital Fortran -was enhanced to provide the other behavior when a -command-line option is specified, apparently due to demand -from readers of the USENET group @file{comp.lang.fortran} -to offer conformance to this widespread practice in the -industry. -@code{g77} should return the favor by offering conformance -to Digital's approach to handling the above example. - -@item -Consider a preprocessor designed specifically for Fortran to replace -@samp{cpp -traditional}. -There are several out there worth evaluating, at least. - -@item -Have @samp{-Wunused} warn about unused labels. - -@item -Warn about assigned @samp{GOTO}/@samp{FORMAT} usage without any -@samp{ASSIGN} to variable. -(Actually, use of @samp{-O -Wuninitialized} should -take care of most of these.) - -@item -Add @samp{-Wintrinsics} to warn about use of -non-standard intrinsics without explicit @samp{INTRINSIC} statements for them -(to help find code that might fail silently when ported to another -compiler). +@node Better Pedantic Compilation +@subsection Better Pedantic Compilation -@item -Support @samp{-fpedantic} more thoroughly, and use it only to generate +@code{g77} needs to support @samp{-fpedantic} more thoroughly, +and use it only to generate warnings instead of rejecting constructs outright. Have it warn: if a variable that dimensions an array is not a dummy or placed -explicitly in @samp{COMMON} (F77 does not allow it to be -placed in @samp{COMMON} via @samp{EQUIVALENCE}); if specification statements +explicitly in @code{COMMON} (F77 does not allow it to be +placed in @code{COMMON} via @code{EQUIVALENCE}); if specification statements follow statement-function-definition statements; about all sorts of syntactic extensions. -@item -Warn about modifying @samp{DO} variables via @samp{EQUIVALENCE}. -(This test might be useful in setting the -internal ``doiter'' flag for a variable or even array -reference within a loop, since that might produce faster code someday.) +@node Warn About Implicit Conversions +@subsection Warn About Implicit Conversions -@item -Add @samp{-Wpromotions} to warn if source code appears +@code{g77} needs a @samp{-Wpromotions} option to warn if source code appears to expect automatic, silent, and -somewhat dangerous compiler-assisted conversion of @samp{REAL} -constants to @samp{DOUBLE PRECISION} based on context. +somewhat dangerous compiler-assisted conversion of @code{REAL(KIND=1)} +constants to @code{REAL(KIND=2)} based on context. -For example, warn about cases like this: +For example, it would warn about cases like this: @example DOUBLE PRECISION FOO @@ -6900,99 +10979,91 @@ PARAMETER (TZPHI = 9.435784839284958) FOO = TZPHI * 3D0 @end example -@item -Generally continue processing for warnings and recoverable (user) -errors whenever possible---don't gratuitously make bad code. +@node Invalid Use of Hollerith Constant +@subsection Invalid Use of Hollerith Constant -For example: +@code{g77} should disallow statements like @samp{RETURN 2HAB}, +which are invalid in both source forms +(unlike @samp{RETURN (2HAB)}, +which probably still makes no sense but at least can +be reliably parsed). +Fixed-form processing rejects it, but not free-form, except +in a way that is a bit difficult to understand. + +@node Dummy Array Without Dimensioning Dummy +@subsection Dummy Array Without Dimensioning Dummy + +@code{g77} should complain when a list of dummy arguments containing an +adjustable dummy array does +not also contain every variable listed in the dimension list of the +adjustable array. + +Currently, @code{g77} does complain about a variable that +dimensions an array but doesn't appear in any dummy list or @code{COMMON} +area, but this needs to be extended to catch cases where it doesn't appear in +every dummy list that also lists any arrays it dimensions. + +For example, @code{g77} should warn about the entry point @samp{ALT} +below, since it includes @samp{ARRAY} but not @samp{ISIZE} in its +list of arguments: @example -INTRINSIC ZABS -CALL FOO(ZABS) -END +SUBROUTINE PRIMARY(ARRAY, ISIZE) +REAL ARRAY(ISIZE) +ENTRY ALT(ARRAY) @end example -When compiling the above with @samp{-ff2c-intrinsics-disable}, -@code{g77} should indeed complain about passing @samp{ZABS}, -but it still should compile, instead of rejecting -the entire @samp{CALL} statement. -(Some of this is related to improving -the compiler internals to improve how statements are analyzed.) - -@item -If @samp{-fno-ugly}, reject badly designed trailing-radix quoted (typeless) -numbers, such as @samp{'123'O}. +@node Ambiguous Dialects +@subsection Ambiguous Dialects -@item -Add @samp{-Wugly*}, @samp{-Wautomatic}, @samp{-Wvxt-not-f90}, @samp{-Wf90}, -and so on. +@code{g77} needs a set of options such as @samp{-Wugly*}, @samp{-Wautomatic}, +@samp{-Wvxt}, @samp{-Wf90}, and so on. These would warn about places in the user's source where ambiguities -are found. +are found, helpful in resolving ambiguities in the program's +dialect or dialects. -One especially interesting case that @samp{-Wf90} would catch -is use of @samp{REAL(Z)}, where @samp{Z} is @samp{DOUBLE COMPLEX}. -Apparently, traditional extended F77 compilers treat this as -what all compilers should agree is @samp{REAL(REAL(Z))}, while -F90 compilers are required to treat @samp{REAL(Z)} as the same -as @samp{DBLE(Z)}, returning a @samp{DOUBLE PRECISION} result -rather than a @samp{REAL} result. +@node Unused Labels +@subsection Unused Labels -@item -@samp{-Wconversion} and related should flag places where non-standard -conversions are found. -Perhaps much of this would be part of @samp{-Wugly*}. +@code{g77} should warn about unused labels when @samp{-Wunused} is in effect. -@item -Complain when list of dummies containing an adjustable dummy array does -not also contain every variable listed in the dimension list of the -adjustable array. +@node Informational Messages +@subsection Informational Messages -Currently, @code{g77} does complain about a variable that -dimensions an array but doesn't appear in any dummy list or @samp{COMMON} -area, but this needs to be extended to catch cases where it doesn't appear in -every dummy list that also lists any arrays it dimensions. +@code{g77} needs an option to suppress information messages (notes). +@samp{-w} does this but also suppresses warnings. +The default should be to suppress info messages. -@item -Make sure things like @samp{RETURN 2HAB} are invalid in both source forms -(must be @samp{RETURN (2HAB)}, -which probably still makes no sense but at least can -be reliably parsed). -Fixed form rejects it, but not free form, except -in a way that is a bit difficult to understand. +Perhaps info messages should simply be eliminated. -@item -The sort of routines usually found in the BSD-ish @code{libU77} should be -provided in addition to the few utility routines in @code{libf2c}. -Much of this work has already been done, and is awaiting -integration into @code{g77}. +@node Uninitialized Variables at Run Time +@subsection Uninitialized Variables at Run Time -@cindex floating point exceptions -@cindex exceptions, floating point -@cindex FPE handling -@cindex NaN values -@item -The GCC backend and, consequently, @code{g77} currently provides no -control over whether or not floating point exceptions are trapped or -ignored. -(Ignoring them typically results in NaN values being -propagated in systems that conform to IEEE 754). -The behaviour is inherited from the system-dependent startup code. +@code{g77} needs an option to initialize everything (not otherwise +explicitly initialized) to ``weird'' +(machine-dependent) values, e.g. NaNs, bad (non-@code{NULL}) pointers, and +largest-magnitude integers, would help track down references to +some kinds of uninitialized variables at run time. -Most systems provide some C-callable mechanism to change this; this can -be invoked at startup using GCC's @samp{constructor} attribute. -For example, just compiling and linking the following C with your -program will turn on exception trapping for the ``common'' exceptions -on an x86-based GNU system: +Note that use of the options @samp{-O -Wuninitialized} can catch +many such bugs at compile time. -@smallexample -#include <fpu_control.h> -void __attribute__ ((constructor)) -trapfpe () @{ - (void) __setfpucw (_FPU_DEFAULT & - ~(_FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM)); -@} -@end smallexample -@end itemize +@node Bounds Checking at Run Time +@subsection Bounds Checking at Run Time + +@code{g77} should offer run-time bounds-checking of array/subscript references +in a fashion similar to @code{f2c}. + +Note that @code{g77} already warns about references to out-of-bounds +elements of arrays when it detects these at compile time. + +@node Labels Visible to Debugger +@subsection Labels Visible to Debugger + +@code{g77} should output debugging information for statements labels, +for use by debuggers that know how to support them. +Same with weirder things like construct names. +It is not yet known if any debug formats or debuggers support these. @node Disappointments @section Disappointments and Misunderstandings @@ -7001,37 +11072,50 @@ These problems are perhaps regrettable, but we don't know any practical way around them for now. @menu -* Limitation on Implicit Declarations:: No @samp{IMPLICIT CHARACTER*(*)}. -* Multiple Definitions of External Names:: No doing both @samp{COMMON /FOO/} - and @samp{SUBROUTINE FOO}. * Mangling of Names:: @samp{SUBROUTINE FOO} is given external name @samp{foo_}. +* Multiple Definitions of External Names:: No doing both @samp{COMMON /FOO/} + and @samp{SUBROUTINE FOO}. +* Limitation on Implicit Declarations:: No @samp{IMPLICIT CHARACTER*(*)}. @end menu -@cindex IMPLICIT CHARACTER*(*) statement -@cindex statements, IMPLICIT CHARACTER*(*) -@node Limitation on Implicit Declarations -@subsection Limitation on Implicit Declarations +@node Mangling of Names +@subsection Mangling of Names in Source Code +@cindex naming issues +@cindex external names +@cindex common blocks +@cindex name space +@cindex underscores -@code{g77} disallows @samp{IMPLICIT CHARACTER*(*)}. -This is not standard-conforming. +The current external-interface design, which includes naming of +external procedures, COMMON blocks, and the library interface, +has various usability problems, including things like adding +underscores where not really necessary (and preventing easier +inter-language operability) and yet not providing complete +namespace freedom for user C code linked with Fortran apps (due +to the naming of functions in the library, among other things). +Project GNU should at least get all this ``right'' for systems +it fully controls, such as the Hurd, and provide defaults and +options for compatibility with existing systems and interoperability +with popular existing compilers. + +@node Multiple Definitions of External Names +@subsection Multiple Definitions of External Names @cindex block data @cindex BLOCK DATA statement @cindex statements, BLOCK DATA @cindex COMMON statement @cindex statements, COMMON @cindex naming conflicts -@node Multiple Definitions of External Names -@subsection Multiple Definitions of External Names @code{g77} doesn't allow a common block and an external procedure or -@samp{BLOCK DATA} to have the same name. +@code{BLOCK DATA} to have the same name. Some systems allow this, but @code{g77} does not, to be compatible with @code{f2c}. @code{g77} could special-case the way it handles -@samp{BLOCK DATA}, since it is not compatible with @code{f2c} in this +@code{BLOCK DATA}, since it is not compatible with @code{f2c} in this particular area (necessarily, since @code{g77} offers an important feature here), but it is likely that such special-casing would be very annoying to people @@ -7041,37 +11125,24 @@ the result would be that @code{g77} would treat these references as requests to force-load BLOCK DATA program units. In that case, if @code{g77} modified -names of @samp{BLOCK DATA} so they could have the same names as -@samp{COMMON}, users +names of @code{BLOCK DATA} so they could have the same names as +@code{COMMON}, users would find that their programs wouldn't link because the @samp{FOO} procedure didn't have its name translated the same way. (Strictly speaking, @code{g77} could emit a null-but-externally-satisfying definition of @samp{FOO} with its name transformed as if it had been a -@samp{BLOCK DATA}, but that probably invites more trouble than it's +@code{BLOCK DATA}, but that probably invites more trouble than it's worth.) -@cindex naming issues -@cindex external names -@cindex COMMON block names -@cindex name space -@cindex underscores -@node Mangling of Names -@subsection Mangling of Names in Source Code - -The current external-interface design, which includes naming of -external procedures, COMMON blocks, and the library interface, -has various usability problems, including things like adding -underscores where not really necessary (and preventing easier -inter-language operability) and yet not providing complete -namespace freedom for user C code linked with Fortran apps (due -to the naming of functions in the library, among other things). +@node Limitation on Implicit Declarations +@subsection Limitation on Implicit Declarations +@cindex IMPLICIT CHARACTER*(*) statement +@cindex statements, IMPLICIT CHARACTER*(*) -Project GNU should at least get all this ``right'' for systems -it fully controls, such as the Hurd, and provide defaults and -options for compatibility with existing systems and interoperability -with popular existing compilers. +@code{g77} disallows @code{IMPLICIT CHARACTER*(*)}. +This is not standard-conforming. @node Non-bugs @section Certain Changes We Don't Want to Make @@ -7082,23 +11153,23 @@ we do not make because we think GNU Fortran is better without them. @menu * Backslash in Constants:: Why @samp{'\\'} is a constant that is one, not two, characters long. +* Initializing Before Specifying:: Why @samp{DATA VAR/1/} can't precede + @samp{COMMON VAR}. +* Context-Sensitive Intrinsicness:: Why @samp{CALL SQRT} won't work. * Context-Sensitive Constants:: Why @samp{9.435784839284958} is a - single-precision (@samp{REAL}) constant, + single-precision constant, and might be interpreted as @samp{9.435785} or similar. * Equivalence Versus Equality:: Why @samp{.TRUE. .EQ. .TRUE.} won't work. -* Context-Sensitive Intrinsicness:: Why @samp{CALL SQRT} won't work. -* Initializing Before Specifying:: Why @samp{DATA VAR/1/} can't precede - @samp{COMMON VAR}. * Order of Side Effects:: Why @samp{J = IFUNC() - IFUNC()} might not behave as expected. @end menu +@node Backslash in Constants +@subsection Backslash in Constants @cindex backslash @cindex f77 support @cindex support, f77 -@node Backslash in Constants -@subsection Backslash in Constants In the opinion of many experienced Fortran users, @samp{-fno-backslash} should be the default, not @samp{-fbackslash}, @@ -7190,6 +11261,9 @@ not widely agreed-upon, goals for GNU compilers in general.) This is why GNU Fortran does and will treat backslashes in the same fashion on all types of machines (by default). +@xref{Direction of Language Development}, for more information on +this overall philosophy guiding the development of the GNU Fortran +language. Of course, users strongly concerned about portability should indicate explicitly in their build procedures which options are expected @@ -7205,23 +11279,100 @@ CHARACTER BACKSL PARAMETER (BACKSL = '\\') @end example +@noindent Then, use concatenation of @samp{BACKSL} anyplace a backslash is desired. +In this way, users can write programs which have the same meaning +in many Fortran dialects. + (However, this technique does not work for Hollerith constants---which -is good, since the only generally portable uses for Hollerith +is just as well, since the only generally portable uses for Hollerith constants are in places where character constants can and should be used instead, for readability.) -In this way, users can write programs which have the same meaning -in many Fortran dialects. +@node Initializing Before Specifying +@subsection Initializing Before Specifying +@cindex initialization, statement placement +@cindex placing initialization statements + +@code{g77} does not allow @samp{DATA VAR/1/} to appear in the +source code before @samp{COMMON VAR}, +@samp{DIMENSION VAR(10)}, @samp{INTEGER VAR}, and so on. +In general, @code{g77} requires initialization of a variable +or array to be specified @emph{after} all other specifications +of attributes (type, size, placement, and so on) of that variable +or array are specified (though @emph{confirmation} of data type is +permitted). + +It is @emph{possible} @code{g77} will someday allow all of this, +even though it is not allowed by the FORTRAN 77 standard. + +Then again, maybe it is better to have +@code{g77} always require placement of @code{DATA} +so that it can possibly immediately write constants +to the output file, thus saving time and space. + +That is, @samp{DATA A/1000000*1/} should perhaps always +be immediately writable to canonical assembler, unless it's already known +to be in a @code{COMMON} area following as-yet-uninitialized stuff, +and to do this it cannot be followed by @samp{COMMON A}. + +@node Context-Sensitive Intrinsicness +@subsection Context-Sensitive Intrinsicness +@cindex intrinsics, context-sensitive +@cindex context-sensitive intrinsics + +@code{g77} treats procedure references to @emph{possible} intrinsic +names as always enabling their intrinsic nature, regardless of +whether the @emph{form} of the reference is valid for that +intrinsic. + +For example, @samp{CALL SQRT} is interpreted by @code{g77} as +an invalid reference to the @code{SQRT} intrinsic function, +because the reference is a subroutine invocation. + +First, @code{g77} recognizes the statement @samp{CALL SQRT} +as a reference to a @emph{procedure} named @samp{SQRT}, not +to a @emph{variable} with that name (as it would for a statement +such as @samp{V = SQRT}). + +Next, @code{g77} establishes that, in the program unit being compiled, +@code{SQRT} is an intrinsic---not a subroutine that +happens to have the same name as an intrinsic (as would be +the case if, for example, @samp{EXTERNAL SQRT} was present). + +Finally, @code{g77} recognizes that the @emph{form} of the +reference is invalid for that particular intrinsic. +That is, it recognizes that it is invalid for an intrinsic +@emph{function}, such as @code{SQRT}, to be invoked as +a @emph{subroutine}. + +At that point, @code{g77} issues a diagnostic. + +Some users claim that it is ``obvious'' that @samp{CALL SQRT} +references an external subroutine of their own, not an +intrinsic function. + +However, @code{g77} knows about intrinsic +subroutines, not just functions, and is able to support both having +the same names, for example. + +As a result of this, @code{g77} rejects calls +to intrinsics that are not subroutines, and function invocations +of intrinsics that are not functions, just as it (and most compilers) +rejects invocations of intrinsics with the wrong number (or types) +of arguments. + +So, use the @samp{EXTERNAL SQRT} statement in a program unit that calls +a user-written subroutine named @samp{SQRT}. -@cindex constants, context-sensitive -@cindex context-sensitive constants @node Context-Sensitive Constants @subsection Context-Sensitive Constants +@cindex constants, context-sensitive +@cindex context-sensitive constants @code{g77} does not use context to determine the types of -constants or named constants (@samp{PARAMETER}), except +constants or named constants (@code{PARAMETER}), except for (non-standard) typeless constants such as @samp{'123'O}. For example, consider the following statement: @@ -7230,9 +11381,10 @@ For example, consider the following statement: PRINT *, 9.435784839284958 * 2D0 @end example +@noindent @code{g77} will interpret the (truncated) constant -@samp{9.435784839284958} as a @samp{REAL}, not @samp{DOUBLE PRECISION}, -constant, because the suffix @samp{D0} is not specified. +@samp{9.435784839284958} as a @code{REAL(KIND=1)}, not @code{REAL(KIND=2)}, +constant, because the suffix @code{D0} is not specified. As a result, the output of the above statement when compiled by @code{g77} will appear to have ``less precision'' @@ -7263,6 +11415,7 @@ PRINT *, CLOSE - FIVE END @end example +@noindent Running the above program should result in the same value being printed three times. @@ -7285,7 +11438,7 @@ in some compilers, to named constants. Since programmers often are encouraged to replace manifest constants or permanently-assigned variables with named -constants (@samp{PARAMETER} in Fortran), and might need +constants (@code{PARAMETER} in Fortran), and might need to replace some constants with variables having the same values for pertinent portions of code, it is important that compilers treat code so modified in the @@ -7300,23 +11453,23 @@ interpret constants' types based on context, so anything @code{g77} can do to help flag cases of this in such code could be very helpful. +@node Equivalence Versus Equality +@subsection Equivalence Versus Equality @cindex .EQV., with integer operands @cindex comparing logical expressions @cindex logical expressions, comparing -@node Equivalence Versus Equality -@subsection Equivalence Versus Equality -Use of @samp{.EQ.} and @samp{.NE.} on @samp{LOGICAL} operands +Use of @code{.EQ.} and @code{.NE.} on @code{LOGICAL} operands is not supported, except via @samp{-fugly}, which is not recommended except for legacy code (where the behavior expected by the @emph{code} is assumed). -Legacy code should be changed, as resources permit, to use @samp{.EQV.} -and @samp{.NEQV.} instead, as these are permitted by the various +Legacy code should be changed, as resources permit, to use @code{.EQV.} +and @code{.NEQV.} instead, as these are permitted by the various Fortran standards. -New code should never be written expecting @samp{.EQ.} or @samp{.NE.} -to work if either of its operands is @samp{LOGICAL}. +New code should never be written expecting @code{.EQ.} or @code{.NE.} +to work if either of its operands is @code{LOGICAL}. The problem with supporting this ``feature'' is that there is unlikely to be consensus on how it works, as illustrated by the @@ -7329,23 +11482,23 @@ IF (L.AND.M.EQ.N) PRINT *,'L.AND.M.EQ.N' END @end example -The issue raised by the above sample program is, what is the -precedence of @samp{.EQ.} (and @samp{.NE.}) when applied to -@samp{LOGICAL} operands? +The issue raised by the above sample program is: what is the +precedence of @code{.EQ.} (and @code{.NE.}) when applied to +@code{LOGICAL} operands? Some programmers will argue that it is the same as the precedence -for @samp{.EQ.} when applied to numeric (such as @samp{INTEGER}) +for @code{.EQ.} when applied to numeric (such as @code{INTEGER}) operands. By this interpretation, the subexpression @samp{M.EQ.N} must be evaluated first in the above program, resulting in a program that, -when run, does not execute the @samp{PRINT} statement. +when run, does not execute the @code{PRINT} statement. Other programmers will argue that the precedence is the same as -the precedence for @samp{.EQV.}, which is restricted by the standards -to @samp{LOGICAL} operands. +the precedence for @code{.EQV.}, which is restricted by the standards +to @code{LOGICAL} operands. By this interpretation, the subexpression @samp{L.AND.M} must be evaluated first, resulting in a program that @emph{does} execute -the @samp{PRINT} statement. +the @code{PRINT} statement. Assigning arbitrary semantic interpretations to syntactic expressions that might legitimately have more than one ``obvious'' interpretation @@ -7353,7 +11506,7 @@ is generally unwise. The creators of the various Fortran standards have done a good job in this case, requiring a distinct set of operators (which have their -own distinct precedence) to compare @samp{LOGICAL} operands. +own distinct precedence) to compare @code{LOGICAL} operands. This requirement results in expression syntax with more certain precedence (without requiring substantial context), making it easier for programmers to read existing code. @@ -7365,86 +11518,10 @@ that were well-designed in the first place. you, without knowing more context, whether the @samp{&} and @samp{-} operators are infix (binary) or unary!) -@cindex intrinsics, context-sensitive -@cindex context-sensitive intrinsics -@node Context-Sensitive Intrinsicness -@subsection Context-Sensitive Intrinsicness - -@code{g77} treats procedure references to @emph{possible} intrinsic -names as always enabling their intrinsic nature, regardless of -whether the @emph{form} of the reference is valid for that -intrinsic. - -For example, @samp{CALL SQRT} is interpreted by @code{g77} as -an invalid reference to the @samp{SQRT} intrinsic function, -because the reference is a subroutine invocation. - -First, @code{g77} recognizes the statement @samp{CALL SQRT} -as a reference to a @emph{procedure} named @samp{SQRT}, not -to a @emph{variable} with that name (as it would for a statement -such as @samp{V = SQRT}). - -Next, @code{g77} establishes that, in the program unit being compiled, -@samp{SQRT} is an intrinsic---not a subroutine that -happens to have the same name as an intrinsic (as would be -the case if, for example, @samp{EXTERNAL SQRT} was present). - -Finally, @code{g77} recognizes that the @emph{form} of the -reference is invalid for that particular intrinsic. -That is, it recognizes that it is invalid for an intrinsic -@emph{function}, such as @samp{SQRT}, to be invoked as -a @emph{subroutine}. - -At that point, @code{g77} issues a diagnostic. - -Some users claim that it is ``obvious'' that @samp{CALL SQRT} -references an external subroutine of their own, not an -intrinsic function. - -However, @code{g77} knows about intrinsic -subroutines, not just functions, and is able to support both having -the same names, for example. - -As a result of this, @code{g77} rejects calls -to intrinsics that are not subroutines, and function invocations -of intrinsics that are not functions, just as it (and most compilers) -rejects invocations of intrinsics with the wrong number (or types) -of arguments. - -So, use the @samp{EXTERNAL SQRT} statement in a program unit that calls -a user-written subroutine named @samp{SQRT}. - -@cindex initialization, statement placement -@cindex placing initialization statements -@node Initializing Before Specifying -@subsection Initializing Before Specifying - -@code{g77} does not allow @samp{DATA VAR/1/} to appear in the -source code before @samp{COMMON VAR}, -@samp{DIMENSION VAR(10)}, @samp{INTEGER VAR}, and so on. -In general, @code{g77} requires initialization of a variable -or array to be specified @emph{after} all other specifications -of attributes (type, size, placement, and so on) of that variable -or array are specified (though @emph{confirmation} of data type is -permitted). - -It is @emph{possible} @code{g77} will someday allow all of this, -even though it is not allowed by the FORTRAN 77 standard. - -Then again, maybe it is better to have -@code{g77} always require placement of @samp{DATA} -so that it can possibly immediately write constants -to the output file, thus saving time and space. - -That is, @samp{DATA A/1000000*1/} should perhaps always -be immediately writable to canonical assembler, unless it's already known -to be in a @samp{COMMON} area following as-yet-uninitialized stuff, -and to do this it cannot be followed by @samp{COMMON A}. - -@cindex side effects, order of evaluation -@cindex order of evaluation, side effects @node Order of Side Effects @subsection Order of Side Effects +@cindex side effects, order of evaluation +@cindex order of evaluation, side effects @code{g77} does not necessarily produce code that, when run, performs side effects (such as those performed by function invocations) @@ -7460,6 +11537,7 @@ from one compiler to another: J = IFUNC() - IFUNC() @end example +@noindent There is no guarantee that @samp{IFUNC} will be evaluated in any particular order. Either invocation might happen first. @@ -7559,7 +11637,23 @@ Please consider offering useful answers to these questions! @itemize @bullet @item -@samp{LOC()} and other intrinsics are probably somewhat misclassified. +How do system administrators and users manage multiple incompatible +Fortran compilers on their systems? +How can @code{g77} contribute to this, or at least avoiding +intefering with it? + +Currently, @code{g77} provides rudimentary ways to choose whether to +overwrite portions of other Fortran compilation systems +(such as the @code{f77} command and the @code{libf2c} library). +Is this sufficient? +What happens when users choose not to overwrite these---does +@code{g77} work properly in all such installations, picking +up its own versions, or does it pick up the existing ``alien'' +versions it didn't overwrite with its own, possibly leading +to subtle bugs? + +@item +@code{LOC()} and other intrinsics are probably somewhat misclassified. Is the a need for more precise classification of intrinsics, and if so, what are the appropriate groupings? Is there a need to individually @@ -7581,7 +11675,7 @@ If it isn't known, then you should report the problem. Reporting a bug might help you by bringing a solution to your problem, or it might not. (If it does not, look in the service directory; see -@ref{Service}.) +@ref{Service}.)@ In any case, the principal function of a bug report is to help the entire community by making the next version of GNU Fortran work better. @@ -7596,14 +11690,18 @@ In order for a bug report to serve its purpose, you must include the information that makes for fixing the bug. @menu -* Criteria: Bug Criteria. Have you really found a bug? -* Where: Bug Lists. Where to send your bug report. +* Criteria: Bug Criteria. Have you really found a bug? +* Where: Bug Lists. Where to send your bug report. * Reporting: Bug Reporting. How to report a bug effectively. * Patches: Sending Patches. How to send a patch for GNU Fortran. -* Known: Trouble. Known problems. -* Help: Service. Where to ask for help. @end menu +@xref{Trouble,,Known Causes of Trouble with GNU Fortran}, +for information on problems we already know about. + +@xref{Service,,How To Get Help with GNU Fortran}, +for information on where to ask for help. + @node Bug Criteria @section Have You Found a Bug? @cindex bug criteria @@ -7675,7 +11773,7 @@ for improvement of GNU Fortran are welcome in any case. @section Where to Report Bugs @cindex bug report mailing lists @kindex fortran@@gnu.ai.mit.edu -Send bug reports for GNU Fortran to @samp{fortran@@gnu.ai.mit.edu}. +Send bug reports for GNU Fortran to @email{fortran@@gnu.ai.mit.edu}. Often people think of posting bug reports to a newsgroup instead of mailing them. @@ -7802,14 +11900,17 @@ frequently depend on every little detail of the function they happen in. @item @cindex included files -@cindex INCLUDE statement -@cindex statements, INCLUDE +@cindex INCLUDE directive +@cindex directive, INCLUDE +@cindex #include directive +@cindex directive, #include Note that you should include with your bug report any files -included by the source file (via the @samp{INCLUDE} statement) -that you send, and any files they @samp{INCLUDE}, -and so on. +included by the source file +(via the @code{#include} or @code{INCLUDE} directive) +that you send, and any files they include, and so on. -It is not necessary to replace the @samp{INCLUDE} statements +It is not necessary to replace +the @code{#include} and @code{INCLUDE} directives with the actual files in the version of the source file that you send, but it might make submitting the bug report easier in the end. @@ -8002,13 +12103,13 @@ unless we have an identical system---and if we do have one, we should be able to reproduce the crash ourselves. @end itemize -@node Sending Patches,, Bug Reporting, Bugs +@node Sending Patches @section Sending Patches for GNU Fortran If you would like to write bug fixes or improvements for the GNU Fortran compiler, that is very helpful. Send suggested fixes to the bug report -mailing list, @code{fortran@@gnu.ai.mit.edu}. +mailing list, @email{fortran@@gnu.ai.mit.edu}. Please follow these guidelines so we can study your patches efficiently. If you don't follow these guidelines, your information might still be @@ -8072,7 +12173,7 @@ study the diffs to decide whether we want to install them. Unidiff format is better than contextless diffs, but not as easy to read as @samp{-c} format. -If you have GNU diff, use @samp{diff -cp}, which shows the name of the +If you have GNU @code{diff}, use @samp{diff -cp}, which shows the name of the function that each change occurs in. (The maintainer of GNU Fortran currently uses @samp{diff -rcp2N}.) @@ -8133,7 +12234,7 @@ The service directory is found in the file named @file{SERVICE} in the GNU CC distribution. @item -Send a message to @code{fortran@@gnu.ai.mit.edu}. +Send a message to @email{fortran@@gnu.ai.mit.edu}. @end itemize @end ifset @@ -8286,7 +12387,7 @@ memory pools and, where feasible, use obstacks to implement them. @item Skip over uninitialized portions of aggregate areas (arrays, -@samp{COMMON} areas, @samp{EQUIVALENCE} areas) so zeros need not be output. +@code{COMMON} areas, @code{EQUIVALENCE} areas) so zeros need not be output. This would reduce memory usage for large initialized aggregate areas, even ones with only one initialized element. @@ -8302,7 +12403,7 @@ This would allow ripping out of the statement-confirmation, symbol retraction/confirmation, and diagnostic inhibition mechanisms. Plus, it would result in much-improved diagnostics. -For example, @samp{CALL some-intrinsic(...)}, where the intrinsic +For example, @samp{CALL some-intrinsic(@dots{})}, where the intrinsic is not a subroutine intrinsic, would result actual error instead of the unimplemented-statement catch-all. @@ -8332,7 +12433,7 @@ Maybe type-conversion, where necessary, can be speeded up as well in cases like the one shown (converting the @samp{2} into @samp{2.}). @item -If analysis shows it to be worthwhile, optimize @samp{lex.c}. +If analysis shows it to be worthwhile, optimize @file{lex.c}. @item Consider redesigning @file{lex.c} to not need any feedback @@ -8353,17 +12454,6 @@ the feature-adding work. @itemize @bullet @item -Get the back end to produce at least as good code involving array -references as does @code{f2c} plus @code{gcc}. -(@emph{Note:} 0.5.18, with its improvements to the GBE for -versions 2.7.1 and 2.7.2 of @code{gcc}, should succeed at -doing this. -Please submit any cases where @code{g77} cannot be made to -generate as optimal code as @code{f2c} in combination with -the same version of @code{gcc}, but only for versions 2.7.1 and -greater of @code{gcc}.) - -@item Do the equivalent of the trick of putting @samp{extern inline} in front of every function definition in @code{libf2c} and #include'ing the resulting file in @code{f2c}+@code{gcc}---that is, inline all run-time-library functions @@ -8376,7 +12466,7 @@ and it's clear that types line up and @samp{CHAR_VAR} is addressable or not a @samp{VAR_DECL}, make @samp{CHAR_VAR}, not a temporary, be the receiver for @samp{CHAR_FUNC}. -(This is now done for @samp{COMPLEX} variables.) +(This is now done for @code{COMPLEX} variables.) @item Design and implement Fortran-specific optimizations that don't @@ -8394,8 +12484,7 @@ and so on) to general computing (array/section implementations of various intrinsics, implementation of commonly performed loops that aren't likely to be optimally compiled otherwise, etc.). -Among -the important things the library would do are: +Among the important things the library would do are: @itemize @bullet @item @@ -8403,7 +12492,7 @@ Be a one-stop-shop-type library, hence shareable and usable by all, in that what are now library-build-time options in @code{libf2c} would be moved at least to the @code{g77} compile phase, if not to finer grains (such as choosing how -list-directed I/O formatting is done by default at @samp{OPEN} time, for +list-directed I/O formatting is done by default at @code{OPEN} time, for preconnected units via options or even statements in the main program unit, maybe even on a per-I/O basis with appropriate pragma-like devices). @@ -8411,20 +12500,20 @@ devices). @item Probably requiring the new library design, change interface to -normally have @samp{COMPLEX} functions return their values in the way -@code{gcc} would if they were declared @samp{__complex__ float}, +normally have @code{COMPLEX} functions return their values in the way +@code{gcc} would if they were declared @code{__complex__ float}, rather than using -the mechanism currently used by @samp{CHARACTER} functions (whereby the +the mechanism currently used by @code{CHARACTER} functions (whereby the functions are compiled as returning void and their first arg is a pointer to where to store the result). (Don't append underscores to -external names for @samp{COMPLEX} functions in some cases once @code{g77} uses +external names for @code{COMPLEX} functions in some cases once @code{g77} uses @code{gcc} rather than @code{f2c} calling conventions.) @item Do something useful with @samp{doiter} references where possible. For example, @samp{CALL FOO(I)} cannot modify @samp{I} if within -a @samp{DO} loop that uses @samp{I} as the +a @code{DO} loop that uses @samp{I} as the iteration variable, and the back end might find that info useful in determining whether it needs to read @samp{I} back into a register after the call. @@ -8453,7 +12542,7 @@ conflicts, while making debugger more straightforward. Also, it should make multi-language applications more feasible, such as by providing -Fortran intrinsics that get Fortran unit numbers given C @samp{FILE *} +Fortran intrinsics that get Fortran unit numbers given C @code{FILE *} descriptors. @item @@ -8461,7 +12550,7 @@ Possibly related to a new library, @code{g77} should produce the equivalent of a @code{gcc} @samp{main(argc, argv)} function when it compiles a main program unit, instead of compiling something that must be called by a library -implementation of @samp{main()}. +implementation of @code{main()}. This would do many useful things such as provide more flexibility in terms of setting up exception handling, @@ -8490,25 +12579,37 @@ so that some popular extensions can be more easily supported. @itemize @bullet @item -Consider adding a @samp{NUMERIC} type to designate typeless numeric constants, +Look through all the documentation on the GNU Fortran language, +dialects, compiler, missing features, bugs, and so on. +Many mentions of incomplete or missing features are +sprinkled throughout. +It is not worth repeating them here. + +@item +Consider adding a @code{NUMERIC} type to designate typeless numeric constants, named and unnamed. The idea is to provide a forward-looking, effective -replacement for things like the old-style @samp{PARAMETER} statement +replacement for things like the old-style @code{PARAMETER} statement when people really need typelessness in a maintainable, portable, clearly documented way. -Maybe @samp{TYPELESS} would include @samp{CHARACTER}, @samp{POINTER}, +Maybe @code{TYPELESS} would include @code{CHARACTER}, @code{POINTER}, and whatever else might come along. (This is not really a call for polymorphism per se, just an ability to express limited, syntactic polymorphism.) @item -Support @samp{OPEN(...,KEY=(...),...)}. +Support @samp{OPEN(@dots{},KEY=(@dots{}),@dots{})}. + +@item +Support arbitrary file unit numbers, instead of limiting them +to 0 through @samp{MXUNIT-1}. +(This is a @code{libf2c} issue.) @item @samp{OPEN(NOSPANBLOCKS,@dots{})} is treated as @samp{OPEN(UNIT=NOSPANBLOCKS,@dots{})}, so a -later @samp{UNIT=} in the first example is invalid. +later @code{UNIT=} in the first example is invalid. Make sure this is what users of this feature would expect. @item @@ -8520,10 +12621,10 @@ as whether general expressions separated by an apostrophe are supported, or maybe the record number can be a general expression, and so on. @item -Support @samp{STRUCTURE}, @samp{UNION}, @samp{MAP}, and @samp{RECORD} +Support @code{STRUCTURE}, @code{UNION}, @code{MAP}, and @code{RECORD} fully. Currently there is no support at all -for @samp{%FILL} in @samp{STRUCTURE} and related syntax, +for @code{%FILL} in @code{STRUCTURE} and related syntax, whereas the rest of the stuff has at least some parsing support. This requires either major @@ -8531,11 +12632,11 @@ changes to @code{libf2c} or its replacement. @item F90 and @code{g77} probably disagree about label scoping relative to -@samp{INTERFACE} and @samp{END INTERFACE}, and their contained +@code{INTERFACE} and @code{END INTERFACE}, and their contained procedure interface bodies (blocks?). @item -@samp{ENTRY} doesn't support F90 @samp{RESULT()} yet, +@code{ENTRY} doesn't support F90 @code{RESULT()} yet, since that was added after S8.112. @item @@ -8544,11 +12645,11 @@ with the final form of the standard (it was vague at S8.112). @item It seems to be an ``open'' question whether a file, immediately after being -@samp{OPEN}ed,is positioned at the beginning, the end, or wherever---it +@code{OPEN}ed,is positioned at the beginning, the end, or wherever---it might be nice to offer an option of opening to ``undefined'' status, requiring an explicit absolute-positioning operation to be performed before any -other (besides @samp{CLOSE}) to assist in making applications port to systems -(some IBM?) that @samp{OPEN} to the end of a file or some such thing. +other (besides @code{CLOSE}) to assist in making applications port to systems +(some IBM?) that @code{OPEN} to the end of a file or some such thing. @end itemize @node Machine Model @@ -8564,9 +12665,9 @@ Switch to using @samp{REAL_VALUE_TYPE} to represent floating-point constants exclusively so the target float format need not be required. This means changing the way @code{g77} handles initialization of aggregate areas -having more than one type, such as @samp{REAL} and @samp{INTEGER}, +having more than one type, such as @code{REAL} and @code{INTEGER}, because currently -it initializes them as if they were arrays of @samp{char} and uses the +it initializes them as if they were arrays of @code{char} and uses the bit patterns of the constants of the various types in them to determine what to stuff in elements of the arrays. @@ -8586,6 +12687,8 @@ libraries are installed) after building. @section Internals Documentation Better info on how @code{g77} works and how to port it is needed. +Much of this should be done only after the redesign planned for +0.6 is complete. @node Internals Improvements @section Internals Improvements @@ -8601,7 +12704,7 @@ For example, anything a caller can check, semantically, let it do so, rather than having @file{expr.c} do it. (Exceptions might include things like -diagnosing @samp{FOO(I--K:)=BAR} where @samp{FOO} is a @samp{PARAMETER}---if +diagnosing @samp{FOO(I--K:)=BAR} where @samp{FOO} is a @code{PARAMETER}---if it seems important to preserve the left-to-right-in-source order of production of diagnostics.) @@ -8632,7 +12735,7 @@ available instead (a good argument for wishing this could have written all this stuff in C++, perhaps). On the other hand, it's questionable whether this sort of improvement is really necessary, given the availability of -tools such as Emacs and perl, which making finding any +tools such as Emacs and Perl, which make finding any address-taking of structure members easy enough? @item @@ -8649,14 +12752,14 @@ of access macros in @samp{.h} files) so they can be tailored to catch code writing into a @samp{RETURNS()} or reading from a @samp{SETS()}. @item -Decorate throughout with @samp{const} and other such stuff. +Decorate throughout with @code{const} and other such stuff. @item All F90 notational derivations in the source code are still based on the S8.112 version of the draft standard. Probably should update to the official standard, or put documentation of the rules as used -in the code...uh...in the code. +in the code@dots{}uh@dots{}in the code. @item Some @samp{ffebld_new} calls (those outside of @file{ffeexpr.c} or @@ -8671,7 +12774,7 @@ Some @samp{ffebld_list_new} (or whatever) calls might not be matched by (It definitely is not a problem just yet.) @item -Probably not doing clean things when we fail to @samp{EQUIVALENCE} something +Probably not doing clean things when we fail to @code{EQUIVALENCE} something due to alignment/mismatch or other problems---they end up without @samp{ffestorag} objects, so maybe the backend (and other parts of the front end) can notice that and handle like an @samp{opANY} (do what it wants, just @@ -8690,14 +12793,9 @@ clutter. @itemize @bullet @item -Implement non-F90 messages (especially avoid mentioning F90 things @code{g77} -doesn't yet support). -Much of this has been done as of 0.5.14. - -@item -When @samp{FUNCTION} and @samp{ENTRY} point types disagree (@samp{CHARACTER} +When @code{FUNCTION} and @code{ENTRY} point types disagree (@code{CHARACTER} lengths, type classes, and so on), -@samp{ANY}-ize the offending @samp{ENTRY} point and any @emph{new} dummies +@samp{ANY}-ize the offending @code{ENTRY} point and any @emph{new} dummies it specifies. @item @@ -8713,12 +12811,255 @@ DATA (X(I), J= 1, 20) /20*5/ END @end example -(The @samp{CONTINUE} statement ensures the @samp{DATA} statement +@noindent +(The @code{CONTINUE} statement ensures the @code{DATA} statement is processed in the context of executable, not specification, statements.) @end itemize @end ifset +@ifset USING +@node Diagnostics +@chapter Diagnostics +@cindex diagnostics + +Some diagnostics produced by @code{g77} require sufficient explanation +that the explanations are given below, and the diagnostics themselves +identify the appropriate explanation. + +Identification uses the GNU Info format---specifically, the @code{info} +command that displays the explanation is given in within square +brackets in the diagnostic. +For example: + +@example +foo.f:5: Invalid statement [info -f g77 M FOOEY] +@end example + +More details about the above diagnostic is found in the @code{g77} Info +documentation, menu item @samp{M}, submenu item @samp{FOOEY}, +which is displayed by typing the UNIX command +@samp{info -f g77 M FOOEY}. + +Other Info readers, such as EMACS, may be just as easily used to display +the pertinent node. +In the above example, @samp{g77} is the Info document name, +@samp{M} is the top-level menu item to select, +and, in that node (named @samp{Diagnostics}, the name of +this chapter, which is the very text you're reading now), +@samp{FOOEY} is the menu item to select. + +@iftex +In this printed version of the @code{g77} manual, the above example +points to a section, below, entitled @samp{FOOEY}---though, of course, +as the above is just a sample, no such section exists. +@end iftex + +@menu +* CMPAMBIG:: Ambiguous use of intrinsic. +@end menu + +@node CMPAMBIG +@section @code{CMPAMBIG} + +@noindent +@example +Ambiguous use of intrinsic @var{intrinsic} @dots{} +@end example + +The type of the argument to the invocation of the @var{intrinsic} +intrinsic is a @code{COMPLEX} type other than @code{COMPLEX(KIND=1)}. +Typically, it is @code{COMPLEX(KIND=2)}, also known as +@code{DOUBLE COMPLEX}. + +The interpretation of this invocation depends on the particular +dialect of Fortran for which the code was written. +Some dialects convert the real part of the argument to +@code{REAL(KIND=1)}, thus losing precision; other dialects, +and Fortran 90, do no such conversion. + +So, GNU Fortran rejects such invocations except under certain +circumstances, to avoid making an incorrect assumption that results +in generating the wrong code. + +To determine the dialect of the program unit, perhaps even whether +that particular invocation is properly coded, determine how the +result of the intrinsic is used. + +The result of @var{intrinsic} is expected (by the original programmer) +to be @code{REAL(KIND=1)} (the non-Fortran-90 interpretation) if: + +@itemize @bullet +@item +It is passed as an argument to a procedure that explicitly or +implicitly declares that argument @code{REAL(KIND=1)}. + +For example, +a procedure with no @code{DOUBLE PRECISION} or @code{IMPLICIT DOUBLE PRECISION} +statement specifying the dummy argument corresponding to an +actual argument of @samp{REAL(Z)}, where @samp{Z} is declared +@code{DOUBLE COMPLEX}, strongly suggests that the programmer +expected @samp{REAL(Z)} to return @code{REAL(KIND=1)} instead +of @code{REAL(KIND=2)}. + +@item +It is used in a context that would otherwise not include +any @code{REAL(KIND=2)} but where treating the @var{intrinsic} +invocation as @code{REAL(KIND=2)} would result in unnecessary +promotions and (typically) more expensive operations on the +wider type. + +For example: + +@example +DOUBLE COMPLEX Z +@dots{} +R(1) = T * REAL(Z) +@end example + +The above example suggests the programmer expected the real part +of @samp{Z} to be converted to @code{REAL(KIND=1)} before being +multiplied by @samp{T} (presumed, along with @samp{R} above, to +be type @code{REAL(KIND=1)}). + +Otherwise, the conversion would have to be delayed until after +the multiplication, requiring not only an extra conversion +(of @samp{T} to @code{REAL(KIND=2)}), but a (typically) more +expensive multiplication (a double-precision multiplication instead +of a single-precision one). +@end itemize + +The result of @var{intrinsic} is expected (by the original programmer) +to be @code{REAL(KIND=2)} (the Fortran 90 interpretation) if: + +@itemize @bullet +@item +It is passed as an argument to a procedure that explicitly or +implicitly declares that argument @code{REAL(KIND=2)}. + +For example, a procedure specifying a @code{DOUBLE PRECISION} +dummy argument corresponding to an +actual argument of @samp{REAL(Z)}, where @samp{Z} is declared +@code{DOUBLE COMPLEX}, strongly suggests that the programmer +expected @samp{REAL(Z)} to return @code{REAL(KIND=2)} instead +of @code{REAL(KIND=1)}. + +@item +It is used in an expression context that includes +other @code{REAL(KIND=2)} operands, +or is assigned to a @code{REAL(KIND=2)} variable or array element. + +For example: + +@example +DOUBLE COMPLEX Z +DOUBLE PRECISION R, T +@dots{} +R(1) = T * REAL(Z) +@end example + +The above example suggests the programmer expected the real part +of @samp{Z} to @emph{not} be converted to @code{REAL(KIND=1)} +by the @code{REAL()} intrinsic. + +Otherwise, the conversion would have to be immediately followed +by a conversion back to @code{REAL(KIND=2)}, losing +the original, full precision of the real part of @code{Z}, +before being multiplied by @samp{T}. +@end itemize + +Once you have determined whether a particular invocation of @var{intrinsic} +expects the Fortran 90 interpretation, you can: + +@itemize @bullet +@item +Change it to @samp{DBLE(@var{intrinsic}(@var{expr}))}, +if it expected the Fortran 90 interpretation. + +This assumes @var{expr} is @code{COMPLEX(KIND=2)}---if it is +some other type, such as @code{COMPLEX*32}, you should use the +appropriate intrinsic, such as the one to convert to @code{REAL*16} +(perhaps @code{DBLEQ()}), in place of @code{DBLE()}. + +@item +Change it to @samp{REAL(@var{intrinsic}(@var{expr}))}, +otherwise. +This converts to @code{REAL(KIND=1)} in all working +Fortran compilers. +@end itemize + +If you don't want to change the code, and you are certain that all +ambiguous invocations of @var{intrinsic} in the source file have +the same expectation regarding interpretation, you can: + +@itemize @bullet +@item +Compile with the @code{g77} option @samp{-ff90}, to enable the +Fortran 90 interpretation. + +@item +Compile with the @code{g77} options @samp{-fno-f90 -fugly-complex}, +to enable the non-Fortran-90 interpretations. +@end itemize + +@xref{REAL() and AIMAG() of Complex}, for more information on this +issue. + +Note: If the above suggestions don't produce enough evidence +as to whether a particular program expects the Fortran 90 +interpretation of this ambiguous invocation of @var{intrinsic}, +there is one more thing you can try. + +If you have access to most or all the compilers used on the +program to create successfully tested and deployed executables, +read the documentation for, and @emph{also} test out, each compiler +to determine how it treats the @var{intrinsic} intrinsic in +this case. +(If all the compilers don't agree on an interpretation, there +might be lurking bugs in the deployed versions of the program.) + +The following sample program might help: + +@cindex JCB003 program +@smallexample + PROGRAM JCB003 +C +C Written by James Craig Burley 1997-02-23. +C Contact via Internet email: burley@@gnu.ai.mit.edu +C +C Determine how compilers handle non-standard REAL +C and AIMAG on DOUBLE COMPLEX operands. +C + DOUBLE COMPLEX Z + REAL R + Z = (3.3D0, 4.4D0) + R = Z + CALL DUMDUM(Z, R) + R = REAL(Z) - R + IF (R .NE. 0.) PRINT *, 'REAL() is Fortran 90' + IF (R .EQ. 0.) PRINT *, 'REAL() is not Fortran 90' + R = 4.4D0 + CALL DUMDUM(Z, R) + R = AIMAG(Z) - R + IF (R .NE. 0.) PRINT *, 'AIMAG() is Fortran 90' + IF (R .EQ. 0.) PRINT *, 'AIMAG() is not Fortran 90' + END +C +C Just to make sure compiler doesn't use naive flow +C analysis to optimize away careful work above, +C which might invalidate results.... +C + SUBROUTINE DUMDUM(Z, R) + DOUBLE COMPLEX Z + REAL R + END +@end smallexample + +If the above program prints contradictory results on a +particular compiler, run away! + +@end ifset + @node Index @unnumbered Index diff --git a/gnu/usr.bin/gcc/f/gbe/2.6.3.diff b/gnu/usr.bin/gcc/f/gbe/2.6.3.diff deleted file mode 100644 index 8ceee52de91..00000000000 --- a/gnu/usr.bin/gcc/f/gbe/2.6.3.diff +++ /dev/null @@ -1,186 +0,0 @@ -*** gcc-2.6.3/Makefile.in Fri Dec 2 16:03:09 1994 ---- g77-2.6.3-0.5.16/Makefile.in Thu Aug 10 04:01:02 1995 -*************** ENQUIRE_CFLAGS = -DNO_MEM -DNO_LONG_DOUB -*** 118,121 **** ---- 118,126 ---- - ENQUIRE_LDFLAGS = $(LDFLAGS) - -+ # NEXT FOUR LINES ADDED BY g77 PATCH ONLY TO ENABLE COMPATIBILITY WITH 2.7.x. -+ # Sed command to transform gcc to installed name. Overwritten by configure. -+ program_transform_name = -e s,x,x, -+ program_transform_cross_name = -e s,^,$(target)-, -+ - # Tools to use when building a cross-compiler. - # These are used because `configure' appends `cross-make' -*************** infodir = $(prefix)/info -*** 176,179 **** ---- 181,188 ---- - # Extension (if any) to put in installed man-page filename. - manext = .1 -+ # NEXT THREE LINES ADDED BY g77 PATCH ONLY TO ENABLE COMPATIBILITY WITH 2.7.x. -+ objext = .o -+ exeext = -+ - # Directory in which to put man pages. - mandir = $(prefix)/man/man1 -*************** c-common.o : c-common.c $(CONFIG_H) $(TR -*** 1010,1014 **** - # Language-independent files. - -! gcc.o: gcc.c $(CONFIG_H) multilib.h config.status - $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ - -DSTANDARD_STARTFILE_PREFIX=\"$(libdir)/\" \ ---- 1019,1023 ---- - # Language-independent files. - -! gcc.o: gcc.c $(CONFIG_H) multilib.h config.status f/lang-specs.h - $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ - -DSTANDARD_STARTFILE_PREFIX=\"$(libdir)/\" \ -*************** stor-layout.o : stor-layout.c $(CONFIG_H -*** 1032,1036 **** - fold-const.o : fold-const.c $(CONFIG_H) $(TREE_H) flags.h - toplev.o : toplev.c $(CONFIG_H) $(TREE_H) $(RTL_H) flags.h input.h \ -! insn-attr.h xcoffout.h defaults.h - $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ - $(MAYBE_TARGET_DEFAULT) $(MAYBE_USE_COLLECT2) \ ---- 1041,1045 ---- - fold-const.o : fold-const.c $(CONFIG_H) $(TREE_H) flags.h - toplev.o : toplev.c $(CONFIG_H) $(TREE_H) $(RTL_H) flags.h input.h \ -! insn-attr.h xcoffout.h defaults.h f/lang-options.h - $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ - $(MAYBE_TARGET_DEFAULT) $(MAYBE_USE_COLLECT2) \ -*** gcc-2.6.3/fold-const.c Fri Dec 2 16:03:43 1994 ---- g77-2.6.3-0.5.16/fold-const.c Thu Aug 10 04:01:03 1995 -*************** eval_subst (arg, old0, new0, old1, new1) -*** 1938,1943 **** ---- 1938,1948 ---- - switch (code) - { -+ /* ??? Disable this since the SAVE_EXPR might already be in use outside -+ the expression. There may be no way to make this work, but it needs -+ to be looked at again for 2.6. */ -+ #if 0 - case SAVE_EXPR: - return eval_subst (TREE_OPERAND (arg, 0), old0, new0, old1, new1); -+ #endif - - case COMPOUND_EXPR: -*************** fold (expr) -*** 3953,3958 **** ---- 3958,3968 ---- - tree xarg0 = arg0; - -+ /* ??? Disable this since the SAVE_EXPR might already be in use outside -+ the expression. There may be no way to make this work, but it needs -+ to be looked at again for 2.6. */ -+ #if 0 - if (TREE_CODE (xarg0) == SAVE_EXPR) - have_save_expr = 1, xarg0 = TREE_OPERAND (xarg0, 0); -+ #endif - - STRIP_NOPS (xarg0); -*************** fold (expr) -*** 3971,3976 **** ---- 3981,3991 ---- - } - -+ /* ??? Disable this since the SAVE_EXPR might already be in use outside -+ the expression. There may be no way to make this work, but it needs -+ to be looked at again for 2.6. */ -+ #if 0 - if (TREE_CODE (xarg0) == SAVE_EXPR) - have_save_expr = 1, xarg0 = TREE_OPERAND (xarg0, 0); -+ #endif - - STRIP_NOPS (xarg0); -*** gcc-2.6.3/gcc.c Mon Nov 7 11:01:43 1994 ---- g77-2.6.3-0.5.16/gcc.c Thu Aug 10 04:01:03 1995 -*************** static struct compiler default_compilers -*** 712,715 **** ---- 712,716 ---- - %{c:%W{o*}%{!o*:-o %w%b.o}}\ - %{!c:-o %d%w%u.o} %{!pipe:%g.s} %A\n}}}}}} "}, -+ #include "f/lang-specs.h" - /* Mark end of table */ - {0, 0} -*** gcc-2.6.3/obstack.c Sat Nov 12 06:40:02 1994 ---- g77-2.6.3-0.5.16/obstack.c Thu Aug 10 04:01:04 1995 -*************** Foundation, 675 Mass Ave, Cambridge, MA -*** 27,33 **** - (especially if it is a shared library). Rather than having every GNU - program understand `configure --with-gnu-libc' and omit the object files, -! it is simpler to just do this in the source for each such file. */ - -! #if defined (_LIBC) || !defined (__GNU_LIBRARY__) - - ---- 27,40 ---- - (especially if it is a shared library). Rather than having every GNU - program understand `configure --with-gnu-libc' and omit the object files, -! it is simpler to just do this in the source for each such file. - -! Actually, don't comment this code out after all. Else, unless the -! inlining set up by obstack.h also is commented out (and replaced by -! including the system's <obstack.h>), bugs will result on a system -! with an older obstack (with older and different inlining) installed. -! And for now it doesn't seem worth having obstack.h #include <stdio.h>, -! as above, just to get __GNU_LIBRARY__ defined, for example. */ -! -! #if defined (_LIBC) || !defined (__GNU_LIBRARY__) || 1 - - -*** gcc-2.6.3/stor-layout.c Thu Oct 20 09:41:02 1994 ---- g77-2.6.3-0.5.16/stor-layout.c Thu Aug 10 04:01:04 1995 -*************** get_pending_sizes () -*** 80,83 **** ---- 80,93 ---- - } - -+ void -+ put_pending_sizes (chain) -+ tree chain; -+ { -+ if (pending_sizes) -+ abort (); -+ -+ pending_sizes = chain; -+ } -+ - /* Given a size SIZE that isn't constant, return a SAVE_EXPR - to serve as the actual size-expression for a type or decl. */ -*** gcc-2.6.3/toplev.c Tue Oct 25 16:09:12 1994 ---- g77-2.6.3-0.5.16/toplev.c Thu Aug 10 04:01:05 1995 -*************** char *lang_options[] = -*** 725,728 **** ---- 725,730 ---- - "-Wno-protocol", - -+ #include "f/lang-options.h" -+ - /* This is for GNAT and is temporary. */ - "-gnat", -*** gcc-2.6.3/tree.c Fri Dec 2 16:03:49 1994 ---- g77-2.6.3-0.5.16/tree.c Thu Aug 10 04:01:05 1995 -*************** save_expr (expr) -*** 1984,1988 **** - - if (TREE_CONSTANT (t) || (TREE_READONLY (t) && ! TREE_SIDE_EFFECTS (t)) -! || TREE_CODE (t) == SAVE_EXPR) - return t; - ---- 1984,1988 ---- - - if (TREE_CONSTANT (t) || (TREE_READONLY (t) && ! TREE_SIDE_EFFECTS (t)) -! || TREE_CODE (t) == SAVE_EXPR || TREE_CODE (t) == ERROR_MARK) - return t; - -*** gcc-2.6.3/tree.h Thu Sep 8 14:25:41 1994 ---- g77-2.6.3-0.5.16/tree.h Thu Aug 10 04:01:06 1995 -*************** extern tree size_int PROTO((unsigned)) -*** 1245,1248 **** ---- 1245,1249 ---- - extern tree round_up PROTO((tree, int)); - extern tree get_pending_sizes PROTO((void)); -+ extern void put_pending_sizes PROTO((tree)); - - /* Type for sizes of data-type. */ diff --git a/gnu/usr.bin/gcc/f/gbe/2.7.0.diff b/gnu/usr.bin/gcc/f/gbe/2.7.0.diff deleted file mode 100644 index e69de29bb2d..00000000000 --- a/gnu/usr.bin/gcc/f/gbe/2.7.0.diff +++ /dev/null diff --git a/gnu/usr.bin/gcc/f/gbe/2.7.1.diff b/gnu/usr.bin/gcc/f/gbe/2.7.1.diff deleted file mode 100644 index e69de29bb2d..00000000000 --- a/gnu/usr.bin/gcc/f/gbe/2.7.1.diff +++ /dev/null diff --git a/gnu/usr.bin/gcc/f/gbe/2.7.2.1.diff b/gnu/usr.bin/gcc/f/gbe/2.7.2.1.diff deleted file mode 100644 index 95b84789fd6..00000000000 --- a/gnu/usr.bin/gcc/f/gbe/2.7.2.1.diff +++ /dev/null @@ -1,246 +0,0 @@ -IMPORTANT: After applying this patch, you must rebuild the -Info documentation derived from the Texinfo files in the -gcc distribution, as this patch does not include patches -to any derived files (due to differences in the way gcc -version 2.7.2.1 is obtained by users). Use the following -command sequence after applying this patch: - - cd gcc-2.7.2.1; make -f Makefile.in gcc.info - -If that fails due to `makeinfo' not being installed, obtain -texinfo-3.9.tar.gz from a GNU distribution site, unpack, -build, and install it, and try the above command sequence -again. - - -diff -rcp2N gcc-2.7.2.1/flags.h gcc-2.7.2.1.f.1/flags.h -*** gcc-2.7.2.1/flags.h Thu Jun 15 07:34:11 1995 ---- gcc-2.7.2.1.f.1/flags.h Mon Nov 11 15:02:26 1996 -*************** extern int flag_unroll_loops; -*** 204,207 **** ---- 204,221 ---- - extern int flag_unroll_all_loops; - -+ /* Nonzero forces all invariant computations in loops to be moved -+ outside the loop. */ -+ -+ extern int flag_move_all_movables; -+ -+ /* Nonzero forces all general induction variables in loops to be -+ strength reduced. */ -+ -+ extern int flag_reduce_all_givs; -+ -+ /* Nonzero gets another run of loop_optimize performed. */ -+ -+ extern int flag_rerun_loop_opt; -+ - /* Nonzero for -fcse-follow-jumps: - have cse follow jumps to do a more extensive job. */ -diff -rcp2N gcc-2.7.2.1/gcc.texi gcc-2.7.2.1.f.1/gcc.texi -*** gcc-2.7.2.1/gcc.texi Mon Nov 11 14:54:07 1996 ---- gcc-2.7.2.1.f.1/gcc.texi Mon Nov 11 15:04:26 1996 -*************** original English. -*** 149,152 **** ---- 149,153 ---- - @sp 3 - @center Last updated 29 June 1996 -+ @center (Revised for GNU Fortran 1996-03-06) - @sp 1 - @c The version number appears twice more in this file. -diff -rcp2N gcc-2.7.2.1/invoke.texi gcc-2.7.2.1.f.1/invoke.texi -*** gcc-2.7.2.1/invoke.texi Tue Oct 3 11:40:43 1995 ---- gcc-2.7.2.1.f.1/invoke.texi Mon Nov 11 15:02:33 1996 -*************** in the following sections. -*** 149,152 **** ---- 149,153 ---- - -fschedule-insns2 -fstrength-reduce -fthread-jumps - -funroll-all-loops -funroll-loops -+ -fmove-all-movables -freduce-all-givs -frerun-loop-opt - -O -O0 -O1 -O2 -O3 - @end smallexample -*************** Perform the optimization of loop unrolli -*** 1940,1943 **** ---- 1941,1985 ---- - and usually makes programs run more slowly. @samp{-funroll-all-loops} - implies @samp{-fstrength-reduce} as well as @samp{-frerun-cse-after-loop}. -+ -+ @item -fmove-all-movables -+ Forces all invariant computations in loops to be moved -+ outside the loop. -+ This option is provided primarily to improve performance -+ for some Fortran code, though it might improve code written -+ in other languages. -+ -+ @emph{Note:} When compiling programs written in Fortran, -+ this option is enabled by default. -+ -+ Analysis of Fortran code optimization and the resulting -+ optimizations triggered by this option, and the -+ @samp{-freduce-all-givs} and @samp{-frerun-loop-opt} -+ options as well, were -+ contributed by Toon Moene (@code{toon@@moene.indiv.nluug.nl}). -+ -+ Please let us (@code{fortran@@gnu.ai.mit.edu}) -+ know how use of these options affects -+ the performance of your production code. -+ We're very interested in code that runs @emph{slower} -+ when these options are @emph{enabled}. -+ -+ @item -freduce-all-givs -+ Forces all general-induction variables in loops to be -+ strength-reduced. -+ This option is provided primarily to improve performance -+ for some Fortran code, though it might improve code written -+ in other languages. -+ -+ @emph{Note:} When compiling programs written in Fortran, -+ this option is enabled by default. -+ -+ @item -frerun-loop-opt -+ Runs loop optimizations a second time. -+ This option is provided primarily to improve performance -+ for some Fortran code, though it might improve code written -+ in other languages. -+ -+ @emph{Note:} When compiling programs written in Fortran, -+ this option is enabled by default. - - @item -fno-peephole -diff -rcp2N gcc-2.7.2.1/loop.c gcc-2.7.2.1.f.1/loop.c -*** gcc-2.7.2.1/loop.c Mon Nov 11 14:54:08 1996 ---- gcc-2.7.2.1.f.1/loop.c Mon Nov 11 15:02:33 1996 -*************** move_movables (movables, threshold, insn -*** 1629,1632 **** ---- 1629,1633 ---- - - if (already_moved[regno] -+ || flag_move_all_movables - || (threshold * savings * m->lifetime) >= insn_count - || (m->forces && m->forces->done -*************** strength_reduce (scan_start, end, loop_t -*** 3821,3826 **** - exit. */ - -! if (v->lifetime * threshold * benefit < insn_count -! && ! bl->reversed) - { - if (loop_dump_stream) ---- 3822,3827 ---- - exit. */ - -! if ( ! flag_reduce_all_givs && v->lifetime * threshold * benefit < insn_count -! && ! bl->reversed ) - { - if (loop_dump_stream) -diff -rcp2N gcc-2.7.2.1/toplev.c gcc-2.7.2.1.f.1/toplev.c -*** gcc-2.7.2.1/toplev.c Fri Oct 20 17:56:35 1995 ---- gcc-2.7.2.1.f.1/toplev.c Mon Nov 11 15:02:33 1996 -*************** int flag_unroll_loops; -*** 388,391 **** ---- 388,405 ---- - int flag_unroll_all_loops; - -+ /* Nonzero forces all invariant computations in loops to be moved -+ outside the loop. */ -+ -+ int flag_move_all_movables = 0; -+ -+ /* Nonzero forces all general induction variables in loops to be -+ strength reduced. */ -+ -+ int flag_reduce_all_givs = 0; -+ -+ /* Nonzero gets another run of loop_optimize performed. */ -+ -+ int flag_rerun_loop_opt = 0; -+ - /* Nonzero for -fwritable-strings: - store string constants in data segment and don't uniquize them. */ -*************** struct { char *string; int *variable; in -*** 542,545 **** ---- 556,562 ---- - {"unroll-loops", &flag_unroll_loops, 1}, - {"unroll-all-loops", &flag_unroll_all_loops, 1}, -+ {"move-all-movables", &flag_move_all_movables, 1}, -+ {"reduce-all-givs", &flag_reduce_all_givs, 1}, -+ {"rerun-loop-opt", &flag_rerun_loop_opt, 1}, - {"writable-strings", &flag_writable_strings, 1}, - {"peephole", &flag_no_peephole, 0}, -*************** rest_of_compilation (decl) -*** 2894,2897 **** ---- 2911,2916 ---- - { - loop_optimize (insns, loop_dump_file); -+ if (flag_rerun_loop_opt) -+ loop_optimize (insns, loop_dump_file); - }); - } -diff -rcp2N gcc-2.7.2.1/tree.c gcc-2.7.2.1.f.1/tree.c -*** gcc-2.7.2.1/tree.c Sun Oct 1 21:26:56 1995 ---- gcc-2.7.2.1.f.1/tree.c Mon Nov 11 15:02:33 1996 -*************** saveable_tree_cons (purpose, value, chai -*** 1965,1968 **** ---- 1965,1992 ---- - } - -+ /* Try to find out whether the type for which the size is to be determined -+ is an ARRAY(of ARRAY(of ARRAY ... of something with a constant size -+ which is an integral multiple of BITS_PER_UNIT)). -+ In that case, the size in bytes can be determined using an EXACT_DIV_EXPR. -+ */ -+ enum tree_code -+ which_div_expr(type) -+ tree type; -+ { -+ tree t; -+ -+ if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != ARRAY_TYPE) -+ return CEIL_DIV_EXPR; -+ -+ for (t = TREE_TYPE (type); TREE_CODE (t) == ARRAY_TYPE; t = TREE_TYPE (t)) -+ ; -+ -+ if (TYPE_SIZE (t) != 0 && TREE_CODE (TYPE_SIZE (t)) == INTEGER_CST && -+ TREE_INT_CST_LOW (TYPE_SIZE (t)) % BITS_PER_UNIT == 0) -+ return EXACT_DIV_EXPR; -+ else -+ return CEIL_DIV_EXPR; -+ } -+ - /* Return the size nominally occupied by an object of type TYPE - when it resides in memory. The value is measured in units of bytes, -*************** size_in_bytes (type) -*** 1985,1989 **** - return integer_zero_node; - } -! t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), - size_int (BITS_PER_UNIT)); - if (TREE_CODE (t) == INTEGER_CST) ---- 2009,2013 ---- - return integer_zero_node; - } -! t = size_binop (which_div_expr (type), TYPE_SIZE (type), - size_int (BITS_PER_UNIT)); - if (TREE_CODE (t) == INTEGER_CST) -*************** int_size_in_bytes (type) -*** 2009,2013 **** - if (TREE_INT_CST_HIGH (TYPE_SIZE (type)) != 0) - { -! tree t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), - size_int (BITS_PER_UNIT)); - return TREE_INT_CST_LOW (t); ---- 2033,2037 ---- - if (TREE_INT_CST_HIGH (TYPE_SIZE (type)) != 0) - { -! tree t = size_binop (which_div_expr (type), TYPE_SIZE (type), - size_int (BITS_PER_UNIT)); - return TREE_INT_CST_LOW (t); -diff -rcp2N gcc-2.7.2.1/version.c gcc-2.7.2.1.f.1/version.c -*** gcc-2.7.2.1/version.c Mon Nov 11 14:54:09 1996 ---- gcc-2.7.2.1.f.1/version.c Mon Nov 11 15:02:34 1996 -*************** -*** 1 **** -! char *version_string = "2.7.2.1"; ---- 1 ---- -! char *version_string = "2.7.2.1.f.1"; diff --git a/gnu/usr.bin/gcc/f/gbe/2.7.2.2.diff b/gnu/usr.bin/gcc/f/gbe/2.7.2.2.diff new file mode 100644 index 00000000000..80903bed46f --- /dev/null +++ b/gnu/usr.bin/gcc/f/gbe/2.7.2.2.diff @@ -0,0 +1,4100 @@ +IMPORTANT: After applying this patch, you must rebuild the +Info documentation derived from the Texinfo files in the +gcc distribution, as this patch does not include patches +to any derived files (due to differences in the way gcc +version 2.7.2.2 is obtained by users). Use the following +command sequence after applying this patch: + + cd gcc-2.7.2.2; make -f Makefile.in gcc.info + +If that fails due to `makeinfo' not being installed, obtain +texinfo-3.9.tar.gz from a GNU distribution site, unpack, +build, and install it, and try the above command sequence +again. + + +diff -rcp2N gcc-2.7.2.2/ChangeLog gcc-2.7.2.2.f.2/ChangeLog +*** gcc-2.7.2.2/ChangeLog Thu Feb 20 19:24:10 1997 +--- gcc-2.7.2.2.f.2/ChangeLog Thu Feb 27 23:04:00 1997 +*************** +*** 1,2 **** +--- 1,69 ---- ++ Wed Feb 26 13:09:33 1997 Michael Meissner <meissner@cygnus.com> ++ ++ * reload.c (debug_reload): Fix format string to print ++ reload_nocombine[r]. ++ ++ Sun Feb 23 15:26:53 1997 Craig Burley <burley@gnu.ai.mit.edu> ++ ++ * fold-const.c (multiple_of_p): Clean up and improve. ++ (fold): Clean up invocation of multiple_of_p. ++ ++ Sat Feb 8 04:53:27 1997 Craig Burley <burley@gnu.ai.mit.edu> ++ ++ From <jfc@jfc.tiac.net> Fri, 07 Feb 1997 22:02:21 -0500: ++ * alias.c (init_alias_analysis): Reduce amount of time ++ needed to simplify the reg_base_value array in the ++ typical case (especially involving function inlining). ++ ++ Fri Jan 10 17:22:17 1997 Craig Burley <burley@gnu.ai.mit.edu> ++ ++ Minor improvements/fixes to better alias handling: ++ * Makefile.in (alias.o): Fix typo in rule (was RLT_H). ++ * cse.c, sched.c: Fix up some indenting. ++ * toplev.c: Add -fargument-alias flag, so Fortran users ++ can turn C-style aliasing on once g77 defaults to ++ -fargument-noalias-global. ++ ++ Integrate patch for better alias handling from ++ John Carr <jfc@mit.edu>: ++ * Makefile.in (OBJS, alias.o): New module and rule. ++ * alias.c: New source module. ++ * calls.c (expand_call): Recognize alias status of calls ++ to malloc(). ++ * combine.c (distribute_notes): New REG_NOALIAS note. ++ * rtl.h (REG_NOALIAS): Ditto. ++ Many other changes for new alias.c module. ++ * cse.c: Many changes, and much code moved into alias.c. ++ * flags.h (flag_alias_check, flag_argument_noalias): ++ New flags. ++ * toplev.c: New flags and related options. ++ * local-alloc.c (validate_equiv_mem_from_store): ++ Caller of true_dependence changed. ++ * loop.c (NUM_STORES): Increase to 50 from 20. ++ (prescan_loop): "const" functions don't alter unknown addresses. ++ (invariant_p): Caller of true_dependence changed. ++ (record_giv): Zero new unrolled and shared flags. ++ (emit_iv_add_mult): Record base value for register. ++ * sched.c: Many changes, mostly moving code to alias.c. ++ (sched_note_set): SCHED_SORT macro def form, but not function, ++ inexplicably changed. ++ * unroll.c: Record base values for registers, etc. ++ ++ Fri Jan 3 04:01:00 1997 Craig Burley <burley@gnu.ai.mit.edu> ++ ++ * loop.c (check_final_value): Handle insns with no luid's ++ appropriately, instead of crashing on INSN_LUID macro ++ invocations. ++ ++ Mon Dec 23 00:49:19 1996 Craig Burley <burley@gnu.ai.mit.edu> ++ ++ * config/alpha/alpha.md: Fix pattern that matches if_then_else ++ involving DF target, DF comparison, SF source. ++ ++ Fri Dec 20 15:42:52 1996 Craig Burley <burley@gnu.ai.mit.edu> ++ ++ * fold-const.c (multiple_of_p): New function. ++ (fold): Use new function to turn *_DIV_EXPR into EXACT_DIV_EXPR. ++ + Sat Jun 29 12:33:39 1996 Richard Kenner <kenner@vlsi1.ultra.nyu.edu> + +diff -rcp2N gcc-2.7.2.2/Makefile.in gcc-2.7.2.2.f.2/Makefile.in +*** gcc-2.7.2.2/Makefile.in Sun Nov 26 14:44:25 1995 +--- gcc-2.7.2.2.f.2/Makefile.in Sun Feb 23 16:36:34 1997 +*************** OBJS = toplev.o version.o tree.o print-t +*** 519,523 **** + integrate.o jump.o cse.o loop.o unroll.o flow.o stupid.o combine.o \ + regclass.o local-alloc.o global.o reload.o reload1.o caller-save.o \ +! insn-peep.o reorg.o sched.o final.o recog.o reg-stack.o \ + insn-opinit.o insn-recog.o insn-extract.o insn-output.o insn-emit.o \ + insn-attrtab.o $(out_object_file) getpwd.o convert.o $(EXTRA_OBJS) +--- 519,523 ---- + integrate.o jump.o cse.o loop.o unroll.o flow.o stupid.o combine.o \ + regclass.o local-alloc.o global.o reload.o reload1.o caller-save.o \ +! insn-peep.o reorg.o alias.o sched.o final.o recog.o reg-stack.o \ + insn-opinit.o insn-recog.o insn-extract.o insn-output.o insn-emit.o \ + insn-attrtab.o $(out_object_file) getpwd.o convert.o $(EXTRA_OBJS) +*************** reorg.o : reorg.c $(CONFIG_H) $(RTL_H) c +*** 1238,1241 **** +--- 1238,1242 ---- + basic-block.h regs.h insn-config.h insn-attr.h insn-flags.h recog.h \ + flags.h output.h ++ alias.o : $(CONFIG_H) $(RTL_H) flags.h hard-reg-set.h regs.h + sched.o : sched.c $(CONFIG_H) $(RTL_H) basic-block.h regs.h hard-reg-set.h \ + flags.h insn-config.h insn-attr.h +diff -rcp2N gcc-2.7.2.2/alias.c gcc-2.7.2.2.f.2/alias.c +*** gcc-2.7.2.2/alias.c Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.2.f.2/alias.c Sat Feb 8 04:53:07 1997 +*************** +*** 0 **** +--- 1,989 ---- ++ /* Alias analysis for GNU C, by John Carr (jfc@mit.edu). ++ Derived in part from sched.c */ ++ #include "config.h" ++ #include "rtl.h" ++ #include "expr.h" ++ #include "regs.h" ++ #include "hard-reg-set.h" ++ #include "flags.h" ++ ++ static rtx canon_rtx PROTO((rtx)); ++ static int rtx_equal_for_memref_p PROTO((rtx, rtx)); ++ static rtx find_symbolic_term PROTO((rtx)); ++ static int memrefs_conflict_p PROTO((int, rtx, int, rtx, ++ HOST_WIDE_INT)); ++ ++ /* Set up all info needed to perform alias analysis on memory references. */ ++ ++ #define SIZE_FOR_MODE(X) (GET_MODE_SIZE (GET_MODE (X))) ++ ++ /* reg_base_value[N] gives an address to which register N is related. ++ If all sets after the first add or subtract to the current value ++ or otherwise modify it so it does not point to a different top level ++ object, reg_base_value[N] is equal to the address part of the source ++ of the first set. The value will be a SYMBOL_REF, a LABEL_REF, or ++ (address (reg)) to indicate that the address is derived from an ++ argument or fixed register. */ ++ rtx *reg_base_value; ++ unsigned int reg_base_value_size; /* size of reg_base_value array */ ++ #define REG_BASE_VALUE(X) \ ++ (REGNO (X) < reg_base_value_size ? reg_base_value[REGNO (X)] : 0) ++ ++ /* Vector indexed by N giving the initial (unchanging) value known ++ for pseudo-register N. */ ++ rtx *reg_known_value; ++ ++ /* Indicates number of valid entries in reg_known_value. */ ++ static int reg_known_value_size; ++ ++ /* Vector recording for each reg_known_value whether it is due to a ++ REG_EQUIV note. Future passes (viz., reload) may replace the ++ pseudo with the equivalent expression and so we account for the ++ dependences that would be introduced if that happens. */ ++ /* ??? This is a problem only on the Convex. The REG_EQUIV notes created in ++ assign_parms mention the arg pointer, and there are explicit insns in the ++ RTL that modify the arg pointer. Thus we must ensure that such insns don't ++ get scheduled across each other because that would invalidate the REG_EQUIV ++ notes. One could argue that the REG_EQUIV notes are wrong, but solving ++ the problem in the scheduler will likely give better code, so we do it ++ here. */ ++ char *reg_known_equiv_p; ++ ++ /* Inside SRC, the source of a SET, find a base address. */ ++ ++ /* When copying arguments into pseudo-registers, record the (ADDRESS) ++ expression for the argument directly so that even if the argument ++ register is changed later (e.g. for a function call) the original ++ value is noted. */ ++ static int copying_arguments; ++ ++ static rtx ++ find_base_value (src) ++ register rtx src; ++ { ++ switch (GET_CODE (src)) ++ { ++ case SYMBOL_REF: ++ case LABEL_REF: ++ return src; ++ ++ case REG: ++ if (copying_arguments && REGNO (src) < FIRST_PSEUDO_REGISTER) ++ return reg_base_value[REGNO (src)]; ++ return src; ++ ++ case MEM: ++ /* Check for an argument passed in memory. Only record in the ++ copying-arguments block; it is too hard to track changes ++ otherwise. */ ++ if (copying_arguments ++ && (XEXP (src, 0) == arg_pointer_rtx ++ || (GET_CODE (XEXP (src, 0)) == PLUS ++ && XEXP (XEXP (src, 0), 0) == arg_pointer_rtx))) ++ return gen_rtx (ADDRESS, VOIDmode, src); ++ return 0; ++ ++ case CONST: ++ src = XEXP (src, 0); ++ if (GET_CODE (src) != PLUS && GET_CODE (src) != MINUS) ++ break; ++ /* fall through */ ++ case PLUS: ++ case MINUS: ++ /* Guess which operand to set the register equivalent to. */ ++ /* If the first operand is a symbol or the second operand is ++ an integer, the first operand is the base address. */ ++ if (GET_CODE (XEXP (src, 0)) == SYMBOL_REF ++ || GET_CODE (XEXP (src, 0)) == LABEL_REF ++ || GET_CODE (XEXP (src, 1)) == CONST_INT) ++ return XEXP (src, 0); ++ /* If an operand is a register marked as a pointer, it is the base. */ ++ if (GET_CODE (XEXP (src, 0)) == REG ++ && REGNO_POINTER_FLAG (REGNO (XEXP (src, 0)))) ++ src = XEXP (src, 0); ++ else if (GET_CODE (XEXP (src, 1)) == REG ++ && REGNO_POINTER_FLAG (REGNO (XEXP (src, 1)))) ++ src = XEXP (src, 1); ++ else ++ return 0; ++ if (copying_arguments && REGNO (src) < FIRST_PSEUDO_REGISTER) ++ return reg_base_value[REGNO (src)]; ++ return src; ++ ++ case AND: ++ /* If the second operand is constant set the base ++ address to the first operand. */ ++ if (GET_CODE (XEXP (src, 1)) == CONST_INT ++ && GET_CODE (XEXP (src, 0)) == REG) ++ { ++ src = XEXP (src, 0); ++ if (copying_arguments && REGNO (src) < FIRST_PSEUDO_REGISTER) ++ return reg_base_value[REGNO (src)]; ++ return src; ++ } ++ return 0; ++ ++ case HIGH: ++ return XEXP (src, 0); ++ } ++ ++ return 0; ++ } ++ ++ /* Called from init_alias_analysis indirectly through note_stores. */ ++ ++ /* while scanning insns to find base values, reg_seen[N] is nonzero if ++ register N has been set in this function. */ ++ static char *reg_seen; ++ ++ static ++ void record_set (dest, set) ++ rtx dest, set; ++ { ++ register int regno; ++ rtx src; ++ ++ if (GET_CODE (dest) != REG) ++ return; ++ ++ regno = REGNO (dest); ++ ++ if (set) ++ { ++ /* A CLOBBER wipes out any old value but does not prevent a previously ++ unset register from acquiring a base address (i.e. reg_seen is not ++ set). */ ++ if (GET_CODE (set) == CLOBBER) ++ { ++ reg_base_value[regno] = 0; ++ return; ++ } ++ src = SET_SRC (set); ++ } ++ else ++ { ++ static int unique_id; ++ if (reg_seen[regno]) ++ { ++ reg_base_value[regno] = 0; ++ return; ++ } ++ reg_seen[regno] = 1; ++ reg_base_value[regno] = gen_rtx (ADDRESS, Pmode, ++ GEN_INT (unique_id++)); ++ return; ++ } ++ ++ /* This is not the first set. If the new value is not related to the ++ old value, forget the base value. Note that the following code is ++ not detected: ++ extern int x, y; int *p = &x; p += (&y-&x); ++ ANSI C does not allow computing the difference of addresses ++ of distinct top level objects. */ ++ if (reg_base_value[regno]) ++ switch (GET_CODE (src)) ++ { ++ case PLUS: ++ case MINUS: ++ if (XEXP (src, 0) != dest && XEXP (src, 1) != dest) ++ reg_base_value[regno] = 0; ++ break; ++ case AND: ++ if (XEXP (src, 0) != dest || GET_CODE (XEXP (src, 1)) != CONST_INT) ++ reg_base_value[regno] = 0; ++ break; ++ case LO_SUM: ++ if (XEXP (src, 0) != dest) ++ reg_base_value[regno] = 0; ++ break; ++ default: ++ reg_base_value[regno] = 0; ++ break; ++ } ++ /* If this is the first set of a register, record the value. */ ++ else if ((regno >= FIRST_PSEUDO_REGISTER || ! fixed_regs[regno]) ++ && ! reg_seen[regno] && reg_base_value[regno] == 0) ++ reg_base_value[regno] = find_base_value (src); ++ ++ reg_seen[regno] = 1; ++ } ++ ++ /* Called from loop optimization when a new pseudo-register is created. */ ++ void ++ record_base_value (regno, val) ++ int regno; ++ rtx val; ++ { ++ if (!flag_alias_check || regno >= reg_base_value_size) ++ return; ++ if (GET_CODE (val) == REG) ++ { ++ if (REGNO (val) < reg_base_value_size) ++ reg_base_value[regno] = reg_base_value[REGNO (val)]; ++ return; ++ } ++ reg_base_value[regno] = find_base_value (val); ++ } ++ ++ static rtx ++ canon_rtx (x) ++ rtx x; ++ { ++ /* Recursively look for equivalences. */ ++ if (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER ++ && REGNO (x) < reg_known_value_size) ++ return reg_known_value[REGNO (x)] == x ++ ? x : canon_rtx (reg_known_value[REGNO (x)]); ++ else if (GET_CODE (x) == PLUS) ++ { ++ rtx x0 = canon_rtx (XEXP (x, 0)); ++ rtx x1 = canon_rtx (XEXP (x, 1)); ++ ++ if (x0 != XEXP (x, 0) || x1 != XEXP (x, 1)) ++ { ++ /* We can tolerate LO_SUMs being offset here; these ++ rtl are used for nothing other than comparisons. */ ++ if (GET_CODE (x0) == CONST_INT) ++ return plus_constant_for_output (x1, INTVAL (x0)); ++ else if (GET_CODE (x1) == CONST_INT) ++ return plus_constant_for_output (x0, INTVAL (x1)); ++ return gen_rtx (PLUS, GET_MODE (x), x0, x1); ++ } ++ } ++ /* This gives us much better alias analysis when called from ++ the loop optimizer. Note we want to leave the original ++ MEM alone, but need to return the canonicalized MEM with ++ all the flags with their original values. */ ++ else if (GET_CODE (x) == MEM) ++ { ++ rtx addr = canon_rtx (XEXP (x, 0)); ++ if (addr != XEXP (x, 0)) ++ { ++ rtx new = gen_rtx (MEM, GET_MODE (x), addr); ++ MEM_VOLATILE_P (new) = MEM_VOLATILE_P (x); ++ RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (x); ++ MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (x); ++ x = new; ++ } ++ } ++ return x; ++ } ++ ++ /* Return 1 if X and Y are identical-looking rtx's. ++ ++ We use the data in reg_known_value above to see if two registers with ++ different numbers are, in fact, equivalent. */ ++ ++ static int ++ rtx_equal_for_memref_p (x, y) ++ rtx x, y; ++ { ++ register int i; ++ register int j; ++ register enum rtx_code code; ++ register char *fmt; ++ ++ if (x == 0 && y == 0) ++ return 1; ++ if (x == 0 || y == 0) ++ return 0; ++ x = canon_rtx (x); ++ y = canon_rtx (y); ++ ++ if (x == y) ++ return 1; ++ ++ code = GET_CODE (x); ++ /* Rtx's of different codes cannot be equal. */ ++ if (code != GET_CODE (y)) ++ return 0; ++ ++ /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent. ++ (REG:SI x) and (REG:HI x) are NOT equivalent. */ ++ ++ if (GET_MODE (x) != GET_MODE (y)) ++ return 0; ++ ++ /* REG, LABEL_REF, and SYMBOL_REF can be compared nonrecursively. */ ++ ++ if (code == REG) ++ return REGNO (x) == REGNO (y); ++ if (code == LABEL_REF) ++ return XEXP (x, 0) == XEXP (y, 0); ++ if (code == SYMBOL_REF) ++ return XSTR (x, 0) == XSTR (y, 0); ++ ++ /* For commutative operations, the RTX match if the operand match in any ++ order. Also handle the simple binary and unary cases without a loop. */ ++ if (code == EQ || code == NE || GET_RTX_CLASS (code) == 'c') ++ return ((rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 0)) ++ && rtx_equal_for_memref_p (XEXP (x, 1), XEXP (y, 1))) ++ || (rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 1)) ++ && rtx_equal_for_memref_p (XEXP (x, 1), XEXP (y, 0)))); ++ else if (GET_RTX_CLASS (code) == '<' || GET_RTX_CLASS (code) == '2') ++ return (rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 0)) ++ && rtx_equal_for_memref_p (XEXP (x, 1), XEXP (y, 1))); ++ else if (GET_RTX_CLASS (code) == '1') ++ return rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 0)); ++ ++ /* Compare the elements. If any pair of corresponding elements ++ fail to match, return 0 for the whole things. */ ++ ++ fmt = GET_RTX_FORMAT (code); ++ for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) ++ { ++ switch (fmt[i]) ++ { ++ case 'w': ++ if (XWINT (x, i) != XWINT (y, i)) ++ return 0; ++ break; ++ ++ case 'n': ++ case 'i': ++ if (XINT (x, i) != XINT (y, i)) ++ return 0; ++ break; ++ ++ case 'V': ++ case 'E': ++ /* Two vectors must have the same length. */ ++ if (XVECLEN (x, i) != XVECLEN (y, i)) ++ return 0; ++ ++ /* And the corresponding elements must match. */ ++ for (j = 0; j < XVECLEN (x, i); j++) ++ if (rtx_equal_for_memref_p (XVECEXP (x, i, j), XVECEXP (y, i, j)) == 0) ++ return 0; ++ break; ++ ++ case 'e': ++ if (rtx_equal_for_memref_p (XEXP (x, i), XEXP (y, i)) == 0) ++ return 0; ++ break; ++ ++ case 'S': ++ case 's': ++ if (strcmp (XSTR (x, i), XSTR (y, i))) ++ return 0; ++ break; ++ ++ case 'u': ++ /* These are just backpointers, so they don't matter. */ ++ break; ++ ++ case '0': ++ break; ++ ++ /* It is believed that rtx's at this level will never ++ contain anything but integers and other rtx's, ++ except for within LABEL_REFs and SYMBOL_REFs. */ ++ default: ++ abort (); ++ } ++ } ++ return 1; ++ } ++ ++ /* Given an rtx X, find a SYMBOL_REF or LABEL_REF within ++ X and return it, or return 0 if none found. */ ++ ++ static rtx ++ find_symbolic_term (x) ++ rtx x; ++ { ++ register int i; ++ register enum rtx_code code; ++ register char *fmt; ++ ++ code = GET_CODE (x); ++ if (code == SYMBOL_REF || code == LABEL_REF) ++ return x; ++ if (GET_RTX_CLASS (code) == 'o') ++ return 0; ++ ++ fmt = GET_RTX_FORMAT (code); ++ for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) ++ { ++ rtx t; ++ ++ if (fmt[i] == 'e') ++ { ++ t = find_symbolic_term (XEXP (x, i)); ++ if (t != 0) ++ return t; ++ } ++ else if (fmt[i] == 'E') ++ break; ++ } ++ return 0; ++ } ++ ++ static rtx ++ find_base_term (x) ++ rtx x; ++ { ++ switch (GET_CODE (x)) ++ { ++ case REG: ++ return REG_BASE_VALUE (x); ++ ++ case HIGH: ++ return find_base_value (XEXP (x, 0)); ++ ++ case CONST: ++ x = XEXP (x, 0); ++ if (GET_CODE (x) != PLUS && GET_CODE (x) != MINUS) ++ return 0; ++ /* fall through */ ++ case LO_SUM: ++ case PLUS: ++ case MINUS: ++ { ++ rtx tmp = find_base_term (XEXP (x, 0)); ++ if (tmp) ++ return tmp; ++ return find_base_term (XEXP (x, 1)); ++ } ++ ++ case AND: ++ if (GET_CODE (XEXP (x, 0)) == REG && GET_CODE (XEXP (x, 1)) == CONST_INT) ++ return REG_BASE_VALUE (XEXP (x, 0)); ++ return 0; ++ ++ case SYMBOL_REF: ++ case LABEL_REF: ++ return x; ++ ++ default: ++ return 0; ++ } ++ } ++ ++ /* Return 0 if the addresses X and Y are known to point to different ++ objects, 1 if they might be pointers to the same object. */ ++ ++ static int ++ base_alias_check (x, y) ++ rtx x, y; ++ { ++ rtx x_base = find_base_term (x); ++ rtx y_base = find_base_term (y); ++ ++ /* If either base address is unknown or the base addresses are equal, ++ nothing is known about aliasing. */ ++ if (x_base == 0 || y_base == 0 || rtx_equal_p (x_base, y_base)) ++ return 1; ++ ++ /* The base addresses of the read and write are different ++ expressions. If they are both symbols there is no ++ conflict. */ ++ if (GET_CODE (x_base) != ADDRESS && GET_CODE (y_base) != ADDRESS) ++ return 0; ++ ++ /* If one address is a stack reference there can be no alias: ++ stack references using different base registers do not alias, ++ a stack reference can not alias a parameter, and a stack reference ++ can not alias a global. */ ++ if ((GET_CODE (x_base) == ADDRESS && GET_MODE (x_base) == Pmode) ++ || (GET_CODE (y_base) == ADDRESS && GET_MODE (y_base) == Pmode)) ++ return 0; ++ ++ if (! flag_argument_noalias) ++ return 1; ++ ++ if (flag_argument_noalias > 1) ++ return 0; ++ ++ /* Weak noalias assertion (arguments are distinct, but may match globals). */ ++ return ! (GET_MODE (x_base) == VOIDmode && GET_MODE (y_base) == VOIDmode); ++ } ++ ++ /* Return nonzero if X and Y (memory addresses) could reference the ++ same location in memory. C is an offset accumulator. When ++ C is nonzero, we are testing aliases between X and Y + C. ++ XSIZE is the size in bytes of the X reference, ++ similarly YSIZE is the size in bytes for Y. ++ ++ If XSIZE or YSIZE is zero, we do not know the amount of memory being ++ referenced (the reference was BLKmode), so make the most pessimistic ++ assumptions. ++ ++ We recognize the following cases of non-conflicting memory: ++ ++ (1) addresses involving the frame pointer cannot conflict ++ with addresses involving static variables. ++ (2) static variables with different addresses cannot conflict. ++ ++ Nice to notice that varying addresses cannot conflict with fp if no ++ local variables had their addresses taken, but that's too hard now. */ ++ ++ ++ static int ++ memrefs_conflict_p (xsize, x, ysize, y, c) ++ register rtx x, y; ++ int xsize, ysize; ++ HOST_WIDE_INT c; ++ { ++ if (GET_CODE (x) == HIGH) ++ x = XEXP (x, 0); ++ else if (GET_CODE (x) == LO_SUM) ++ x = XEXP (x, 1); ++ else ++ x = canon_rtx (x); ++ if (GET_CODE (y) == HIGH) ++ y = XEXP (y, 0); ++ else if (GET_CODE (y) == LO_SUM) ++ y = XEXP (y, 1); ++ else ++ y = canon_rtx (y); ++ ++ if (rtx_equal_for_memref_p (x, y)) ++ { ++ if (xsize == 0 || ysize == 0) ++ return 1; ++ if (c >= 0 && xsize > c) ++ return 1; ++ if (c < 0 && ysize+c > 0) ++ return 1; ++ return 0; ++ } ++ ++ if (y == frame_pointer_rtx || y == hard_frame_pointer_rtx ++ || y == stack_pointer_rtx) ++ { ++ rtx t = y; ++ int tsize = ysize; ++ y = x; ysize = xsize; ++ x = t; xsize = tsize; ++ } ++ ++ if (x == frame_pointer_rtx || x == hard_frame_pointer_rtx ++ || x == stack_pointer_rtx) ++ { ++ rtx y1; ++ ++ if (CONSTANT_P (y)) ++ return 0; ++ ++ if (GET_CODE (y) == PLUS ++ && canon_rtx (XEXP (y, 0)) == x ++ && (y1 = canon_rtx (XEXP (y, 1))) ++ && GET_CODE (y1) == CONST_INT) ++ { ++ c += INTVAL (y1); ++ return (xsize == 0 || ysize == 0 ++ || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0)); ++ } ++ ++ if (GET_CODE (y) == PLUS ++ && (y1 = canon_rtx (XEXP (y, 0))) ++ && CONSTANT_P (y1)) ++ return 0; ++ ++ return 1; ++ } ++ ++ if (GET_CODE (x) == PLUS) ++ { ++ /* The fact that X is canonicalized means that this ++ PLUS rtx is canonicalized. */ ++ rtx x0 = XEXP (x, 0); ++ rtx x1 = XEXP (x, 1); ++ ++ if (GET_CODE (y) == PLUS) ++ { ++ /* The fact that Y is canonicalized means that this ++ PLUS rtx is canonicalized. */ ++ rtx y0 = XEXP (y, 0); ++ rtx y1 = XEXP (y, 1); ++ ++ if (rtx_equal_for_memref_p (x1, y1)) ++ return memrefs_conflict_p (xsize, x0, ysize, y0, c); ++ if (rtx_equal_for_memref_p (x0, y0)) ++ return memrefs_conflict_p (xsize, x1, ysize, y1, c); ++ if (GET_CODE (x1) == CONST_INT) ++ if (GET_CODE (y1) == CONST_INT) ++ return memrefs_conflict_p (xsize, x0, ysize, y0, ++ c - INTVAL (x1) + INTVAL (y1)); ++ else ++ return memrefs_conflict_p (xsize, x0, ysize, y, c - INTVAL (x1)); ++ else if (GET_CODE (y1) == CONST_INT) ++ return memrefs_conflict_p (xsize, x, ysize, y0, c + INTVAL (y1)); ++ ++ /* Handle case where we cannot understand iteration operators, ++ but we notice that the base addresses are distinct objects. */ ++ /* ??? Is this still necessary? */ ++ x = find_symbolic_term (x); ++ if (x == 0) ++ return 1; ++ y = find_symbolic_term (y); ++ if (y == 0) ++ return 1; ++ return rtx_equal_for_memref_p (x, y); ++ } ++ else if (GET_CODE (x1) == CONST_INT) ++ return memrefs_conflict_p (xsize, x0, ysize, y, c - INTVAL (x1)); ++ } ++ else if (GET_CODE (y) == PLUS) ++ { ++ /* The fact that Y is canonicalized means that this ++ PLUS rtx is canonicalized. */ ++ rtx y0 = XEXP (y, 0); ++ rtx y1 = XEXP (y, 1); ++ ++ if (GET_CODE (y1) == CONST_INT) ++ return memrefs_conflict_p (xsize, x, ysize, y0, c + INTVAL (y1)); ++ else ++ return 1; ++ } ++ ++ if (GET_CODE (x) == GET_CODE (y)) ++ switch (GET_CODE (x)) ++ { ++ case MULT: ++ { ++ /* Handle cases where we expect the second operands to be the ++ same, and check only whether the first operand would conflict ++ or not. */ ++ rtx x0, y0; ++ rtx x1 = canon_rtx (XEXP (x, 1)); ++ rtx y1 = canon_rtx (XEXP (y, 1)); ++ if (! rtx_equal_for_memref_p (x1, y1)) ++ return 1; ++ x0 = canon_rtx (XEXP (x, 0)); ++ y0 = canon_rtx (XEXP (y, 0)); ++ if (rtx_equal_for_memref_p (x0, y0)) ++ return (xsize == 0 || ysize == 0 ++ || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0)); ++ ++ /* Can't properly adjust our sizes. */ ++ if (GET_CODE (x1) != CONST_INT) ++ return 1; ++ xsize /= INTVAL (x1); ++ ysize /= INTVAL (x1); ++ c /= INTVAL (x1); ++ return memrefs_conflict_p (xsize, x0, ysize, y0, c); ++ } ++ } ++ ++ /* Treat an access through an AND (e.g. a subword access on an Alpha) ++ as an access with indeterminate size. */ ++ if (GET_CODE (x) == AND && GET_CODE (XEXP (x, 1)) == CONST_INT) ++ return memrefs_conflict_p (0, XEXP (x, 0), ysize, y, c); ++ if (GET_CODE (y) == AND && GET_CODE (XEXP (y, 1)) == CONST_INT) ++ return memrefs_conflict_p (xsize, x, 0, XEXP (y, 0), c); ++ ++ if (CONSTANT_P (x)) ++ { ++ if (GET_CODE (x) == CONST_INT && GET_CODE (y) == CONST_INT) ++ { ++ c += (INTVAL (y) - INTVAL (x)); ++ return (xsize == 0 || ysize == 0 ++ || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0)); ++ } ++ ++ if (GET_CODE (x) == CONST) ++ { ++ if (GET_CODE (y) == CONST) ++ return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)), ++ ysize, canon_rtx (XEXP (y, 0)), c); ++ else ++ return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)), ++ ysize, y, c); ++ } ++ if (GET_CODE (y) == CONST) ++ return memrefs_conflict_p (xsize, x, ysize, ++ canon_rtx (XEXP (y, 0)), c); ++ ++ if (CONSTANT_P (y)) ++ return (rtx_equal_for_memref_p (x, y) ++ && (xsize == 0 || ysize == 0 ++ || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0))); ++ ++ return 1; ++ } ++ return 1; ++ } ++ ++ /* Functions to compute memory dependencies. ++ ++ Since we process the insns in execution order, we can build tables ++ to keep track of what registers are fixed (and not aliased), what registers ++ are varying in known ways, and what registers are varying in unknown ++ ways. ++ ++ If both memory references are volatile, then there must always be a ++ dependence between the two references, since their order can not be ++ changed. A volatile and non-volatile reference can be interchanged ++ though. ++ ++ A MEM_IN_STRUCT reference at a non-QImode varying address can never ++ conflict with a non-MEM_IN_STRUCT reference at a fixed address. We must ++ allow QImode aliasing because the ANSI C standard allows character ++ pointers to alias anything. We are assuming that characters are ++ always QImode here. */ ++ ++ /* Read dependence: X is read after read in MEM takes place. There can ++ only be a dependence here if both reads are volatile. */ ++ ++ int ++ read_dependence (mem, x) ++ rtx mem; ++ rtx x; ++ { ++ return MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem); ++ } ++ ++ /* True dependence: X is read after store in MEM takes place. */ ++ ++ int ++ true_dependence (mem, mem_mode, x, varies) ++ rtx mem; ++ enum machine_mode mem_mode; ++ rtx x; ++ int (*varies)(); ++ { ++ rtx x_addr, mem_addr; ++ ++ if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem)) ++ return 1; ++ ++ x_addr = XEXP (x, 0); ++ mem_addr = XEXP (mem, 0); ++ ++ if (flag_alias_check && ! base_alias_check (x_addr, mem_addr)) ++ return 0; ++ ++ /* If X is an unchanging read, then it can't possibly conflict with any ++ non-unchanging store. It may conflict with an unchanging write though, ++ because there may be a single store to this address to initialize it. ++ Just fall through to the code below to resolve the case where we have ++ both an unchanging read and an unchanging write. This won't handle all ++ cases optimally, but the possible performance loss should be ++ negligible. */ ++ if (RTX_UNCHANGING_P (x) && ! RTX_UNCHANGING_P (mem)) ++ return 0; ++ ++ x_addr = canon_rtx (x_addr); ++ mem_addr = canon_rtx (mem_addr); ++ if (mem_mode == VOIDmode) ++ mem_mode = GET_MODE (mem); ++ ++ if (! memrefs_conflict_p (mem_mode, mem_addr, SIZE_FOR_MODE (x), x_addr, 0)) ++ return 0; ++ ++ /* If both references are struct references, or both are not, nothing ++ is known about aliasing. ++ ++ If either reference is QImode or BLKmode, ANSI C permits aliasing. ++ ++ If both addresses are constant, or both are not, nothing is known ++ about aliasing. */ ++ if (MEM_IN_STRUCT_P (x) == MEM_IN_STRUCT_P (mem) ++ || mem_mode == QImode || mem_mode == BLKmode ++ || GET_MODE (x) == QImode || GET_MODE (mem) == BLKmode ++ || varies (x_addr) == varies (mem_addr)) ++ return 1; ++ ++ /* One memory reference is to a constant address, one is not. ++ One is to a structure, the other is not. ++ ++ If either memory reference is a variable structure the other is a ++ fixed scalar and there is no aliasing. */ ++ if ((MEM_IN_STRUCT_P (mem) && varies (mem_addr)) ++ || (MEM_IN_STRUCT_P (x) && varies (x))) ++ return 0; ++ ++ return 1; ++ } ++ ++ /* Anti dependence: X is written after read in MEM takes place. */ ++ ++ int ++ anti_dependence (mem, x) ++ rtx mem; ++ rtx x; ++ { ++ if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem)) ++ return 1; ++ ++ if (flag_alias_check && ! base_alias_check (XEXP (x, 0), XEXP (mem, 0))) ++ return 0; ++ ++ /* If MEM is an unchanging read, then it can't possibly conflict with ++ the store to X, because there is at most one store to MEM, and it must ++ have occurred somewhere before MEM. */ ++ x = canon_rtx (x); ++ mem = canon_rtx (mem); ++ if (RTX_UNCHANGING_P (mem)) ++ return 0; ++ ++ return (memrefs_conflict_p (SIZE_FOR_MODE (mem), XEXP (mem, 0), ++ SIZE_FOR_MODE (x), XEXP (x, 0), 0) ++ && ! (MEM_IN_STRUCT_P (mem) && rtx_addr_varies_p (mem) ++ && GET_MODE (mem) != QImode ++ && ! MEM_IN_STRUCT_P (x) && ! rtx_addr_varies_p (x)) ++ && ! (MEM_IN_STRUCT_P (x) && rtx_addr_varies_p (x) ++ && GET_MODE (x) != QImode ++ && ! MEM_IN_STRUCT_P (mem) && ! rtx_addr_varies_p (mem))); ++ } ++ ++ /* Output dependence: X is written after store in MEM takes place. */ ++ ++ int ++ output_dependence (mem, x) ++ register rtx mem; ++ register rtx x; ++ { ++ if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem)) ++ return 1; ++ ++ if (flag_alias_check && !base_alias_check (XEXP (x, 0), XEXP (mem, 0))) ++ return 0; ++ ++ x = canon_rtx (x); ++ mem = canon_rtx (mem); ++ return (memrefs_conflict_p (SIZE_FOR_MODE (mem), XEXP (mem, 0), ++ SIZE_FOR_MODE (x), XEXP (x, 0), 0) ++ && ! (MEM_IN_STRUCT_P (mem) && rtx_addr_varies_p (mem) ++ && GET_MODE (mem) != QImode ++ && ! MEM_IN_STRUCT_P (x) && ! rtx_addr_varies_p (x)) ++ && ! (MEM_IN_STRUCT_P (x) && rtx_addr_varies_p (x) ++ && GET_MODE (x) != QImode ++ && ! MEM_IN_STRUCT_P (mem) && ! rtx_addr_varies_p (mem))); ++ } ++ ++ void ++ init_alias_analysis () ++ { ++ int maxreg = max_reg_num (); ++ register int i; ++ register rtx insn; ++ rtx note; ++ rtx set; ++ int changed; ++ ++ reg_known_value_size = maxreg; ++ ++ reg_known_value ++ = (rtx *) oballoc ((maxreg - FIRST_PSEUDO_REGISTER) * sizeof (rtx)) ++ - FIRST_PSEUDO_REGISTER; ++ reg_known_equiv_p = ++ oballoc (maxreg - FIRST_PSEUDO_REGISTER) - FIRST_PSEUDO_REGISTER; ++ bzero ((char *) (reg_known_value + FIRST_PSEUDO_REGISTER), ++ (maxreg-FIRST_PSEUDO_REGISTER) * sizeof (rtx)); ++ bzero (reg_known_equiv_p + FIRST_PSEUDO_REGISTER, ++ (maxreg - FIRST_PSEUDO_REGISTER) * sizeof (char)); ++ ++ if (flag_alias_check) ++ { ++ /* Overallocate reg_base_value to allow some growth during loop ++ optimization. Loop unrolling can create a large number of ++ registers. */ ++ reg_base_value_size = maxreg * 2; ++ reg_base_value = (rtx *)oballoc (reg_base_value_size * sizeof (rtx)); ++ reg_seen = (char *)alloca (reg_base_value_size); ++ bzero (reg_base_value, reg_base_value_size * sizeof (rtx)); ++ bzero (reg_seen, reg_base_value_size); ++ ++ /* Mark all hard registers which may contain an address. ++ The stack, frame and argument pointers may contain an address. ++ An argument register which can hold a Pmode value may contain ++ an address even if it is not in BASE_REGS. ++ ++ The address expression is VOIDmode for an argument and ++ Pmode for other registers. */ ++ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) ++ if (FUNCTION_ARG_REGNO_P (i) && HARD_REGNO_MODE_OK (i, Pmode)) ++ reg_base_value[i] = gen_rtx (ADDRESS, VOIDmode, ++ gen_rtx (REG, Pmode, i)); ++ ++ reg_base_value[STACK_POINTER_REGNUM] ++ = gen_rtx (ADDRESS, Pmode, stack_pointer_rtx); ++ reg_base_value[ARG_POINTER_REGNUM] ++ = gen_rtx (ADDRESS, Pmode, arg_pointer_rtx); ++ reg_base_value[FRAME_POINTER_REGNUM] ++ = gen_rtx (ADDRESS, Pmode, frame_pointer_rtx); ++ reg_base_value[HARD_FRAME_POINTER_REGNUM] ++ = gen_rtx (ADDRESS, Pmode, hard_frame_pointer_rtx); ++ } ++ ++ copying_arguments = 1; ++ /* Fill in the entries with known constant values. */ ++ for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) ++ { ++ if (flag_alias_check && GET_RTX_CLASS (GET_CODE (insn)) == 'i') ++ { ++ /* If this insn has a noalias note, process it, Otherwise, ++ scan for sets. A simple set will have no side effects ++ which could change the base value of any other register. */ ++ rtx noalias_note; ++ if (GET_CODE (PATTERN (insn)) == SET ++ && (noalias_note = find_reg_note (insn, REG_NOALIAS, NULL_RTX))) ++ record_set(SET_DEST (PATTERN (insn)), 0); ++ else ++ note_stores (PATTERN (insn), record_set); ++ } ++ else if (GET_CODE (insn) == NOTE ++ && NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_BEG) ++ copying_arguments = 0; ++ ++ if ((set = single_set (insn)) != 0 ++ && GET_CODE (SET_DEST (set)) == REG ++ && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER ++ && (((note = find_reg_note (insn, REG_EQUAL, 0)) != 0 ++ && reg_n_sets[REGNO (SET_DEST (set))] == 1) ++ || (note = find_reg_note (insn, REG_EQUIV, NULL_RTX)) != 0) ++ && GET_CODE (XEXP (note, 0)) != EXPR_LIST) ++ { ++ int regno = REGNO (SET_DEST (set)); ++ reg_known_value[regno] = XEXP (note, 0); ++ reg_known_equiv_p[regno] = REG_NOTE_KIND (note) == REG_EQUIV; ++ } ++ } ++ ++ /* Fill in the remaining entries. */ ++ for (i = FIRST_PSEUDO_REGISTER; i < maxreg; i++) ++ if (reg_known_value[i] == 0) ++ reg_known_value[i] = regno_reg_rtx[i]; ++ ++ if (! flag_alias_check) ++ return; ++ ++ /* Simplify the reg_base_value array so that no register refers to ++ another register, except to special registers indirectly through ++ ADDRESS expressions. ++ ++ In theory this loop can take as long as O(registers^2), but unless ++ there are very long dependency chains it will run in close to linear ++ time. */ ++ do ++ { ++ changed = 0; ++ for (i = FIRST_PSEUDO_REGISTER; i < reg_base_value_size; i++) ++ { ++ rtx base = reg_base_value[i]; ++ if (base && GET_CODE (base) == REG) ++ { ++ int base_regno = REGNO (base); ++ if (base_regno == i) /* register set from itself */ ++ reg_base_value[i] = 0; ++ else ++ reg_base_value[i] = reg_base_value[base_regno]; ++ changed = 1; ++ } ++ } ++ } ++ while (changed); ++ ++ reg_seen = 0; ++ } ++ ++ void ++ end_alias_analysis () ++ { ++ reg_known_value = 0; ++ reg_base_value = 0; ++ reg_base_value_size = 0; ++ } +diff -rcp2N gcc-2.7.2.2/calls.c gcc-2.7.2.2.f.2/calls.c +*** gcc-2.7.2.2/calls.c Thu Oct 26 21:53:43 1995 +--- gcc-2.7.2.2.f.2/calls.c Fri Jan 10 23:18:21 1997 +*************** expand_call (exp, target, ignore) +*** 564,567 **** +--- 564,569 ---- + /* Nonzero if it is plausible that this is a call to alloca. */ + int may_be_alloca; ++ /* Nonzero if this is a call to malloc or a related function. */ ++ int is_malloc; + /* Nonzero if this is a call to setjmp or a related function. */ + int returns_twice; +*************** expand_call (exp, target, ignore) +*** 852,855 **** +--- 854,858 ---- + returns_twice = 0; + is_longjmp = 0; ++ is_malloc = 0; + + if (name != 0 && IDENTIFIER_LENGTH (DECL_NAME (fndecl)) <= 15) +*************** expand_call (exp, target, ignore) +*** 891,894 **** +--- 894,901 ---- + && ! strcmp (tname, "longjmp")) + is_longjmp = 1; ++ /* Only recognize malloc when alias analysis is enabled. */ ++ else if (tname[0] == 'm' && flag_alias_check ++ && ! strcmp(tname, "malloc")) ++ is_malloc = 1; + } + +*************** expand_call (exp, target, ignore) +*** 1363,1367 **** + /* Now we are about to start emitting insns that can be deleted + if a libcall is deleted. */ +! if (is_const) + start_sequence (); + +--- 1370,1374 ---- + /* Now we are about to start emitting insns that can be deleted + if a libcall is deleted. */ +! if (is_const || is_malloc) + start_sequence (); + +*************** expand_call (exp, target, ignore) +*** 1951,1954 **** +--- 1958,1975 ---- + end_sequence (); + emit_insns (insns); ++ } ++ else if (is_malloc) ++ { ++ rtx temp = gen_reg_rtx (GET_MODE (valreg)); ++ rtx last, insns; ++ ++ emit_move_insn (temp, valreg); ++ last = get_last_insn (); ++ REG_NOTES (last) = ++ gen_rtx (EXPR_LIST, REG_NOALIAS, temp, REG_NOTES (last)); ++ insns = get_insns (); ++ end_sequence (); ++ emit_insns (insns); ++ valreg = temp; + } + +diff -rcp2N gcc-2.7.2.2/combine.c gcc-2.7.2.2.f.2/combine.c +*** gcc-2.7.2.2/combine.c Sun Nov 26 14:32:07 1995 +--- gcc-2.7.2.2.f.2/combine.c Fri Jan 10 23:18:21 1997 +*************** distribute_notes (notes, from_insn, i3, +*** 10648,10651 **** +--- 10648,10652 ---- + case REG_EQUIV: + case REG_NONNEG: ++ case REG_NOALIAS: + /* These notes say something about results of an insn. We can + only support them if they used to be on I3 in which case they +diff -rcp2N gcc-2.7.2.2/config/alpha/alpha.c gcc-2.7.2.2.f.2/config/alpha/alpha.c +*** gcc-2.7.2.2/config/alpha/alpha.c Thu Feb 20 19:24:11 1997 +--- gcc-2.7.2.2.f.2/config/alpha/alpha.c Sun Feb 23 15:35:33 1997 +*************** output_prolog (file, size) +*** 1370,1373 **** +--- 1370,1378 ---- + + alpha_function_needs_gp = 0; ++ #ifdef __linux__ ++ if(profile_flag) { ++ alpha_function_needs_gp = 1; ++ } ++ #endif + for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) + if ((GET_CODE (insn) == CALL_INSN) +diff -rcp2N gcc-2.7.2.2/config/alpha/alpha.h gcc-2.7.2.2.f.2/config/alpha/alpha.h +*** gcc-2.7.2.2/config/alpha/alpha.h Thu Feb 20 19:24:12 1997 +--- gcc-2.7.2.2.f.2/config/alpha/alpha.h Sun Feb 23 15:35:34 1997 +*************** extern int target_flags; +*** 112,116 **** +--- 112,118 ---- + {"", TARGET_DEFAULT | TARGET_CPU_DEFAULT} } + ++ #ifndef TARGET_DEFAULT + #define TARGET_DEFAULT 3 ++ #endif + + #ifndef TARGET_CPU_DEFAULT +diff -rcp2N gcc-2.7.2.2/config/alpha/alpha.md gcc-2.7.2.2.f.2/config/alpha/alpha.md +*** gcc-2.7.2.2/config/alpha/alpha.md Fri Oct 27 06:49:59 1995 +--- gcc-2.7.2.2.f.2/config/alpha/alpha.md Mon Dec 23 00:43:55 1996 +*************** +*** 1746,1752 **** + (if_then_else:DF + (match_operator 3 "signed_comparison_operator" +! [(match_operand:DF 1 "reg_or_fp0_operand" "fG,fG") + (match_operand:DF 2 "fp0_operand" "G,G")]) +! (float_extend:DF (match_operand:SF 4 "reg_or_fp0_operand" "fG,0")) + (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))] + "TARGET_FP" +--- 1746,1752 ---- + (if_then_else:DF + (match_operator 3 "signed_comparison_operator" +! [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG") + (match_operand:DF 2 "fp0_operand" "G,G")]) +! (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG,0")) + (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))] + "TARGET_FP" +diff -rcp2N gcc-2.7.2.2/config/alpha/linux.h gcc-2.7.2.2.f.2/config/alpha/linux.h +*** gcc-2.7.2.2/config/alpha/linux.h Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.2.f.2/config/alpha/linux.h Thu Dec 19 12:31:08 1996 +*************** +*** 0 **** +--- 1,72 ---- ++ /* Definitions of target machine for GNU compiler, for Alpha Linux, ++ using ECOFF. ++ Copyright (C) 1995 Free Software Foundation, Inc. ++ Contributed by Bob Manson. ++ Derived from work contributed by Cygnus Support, ++ (c) 1993 Free Software Foundation. ++ ++ This file is part of GNU CC. ++ ++ GNU CC is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2, or (at your option) ++ any later version. ++ ++ GNU CC is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with GNU CC; see the file COPYING. If not, write to ++ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ++ ++ #define TARGET_DEFAULT (3 | MASK_GAS) ++ ++ #include "alpha/alpha.h" ++ ++ #undef TARGET_VERSION ++ #define TARGET_VERSION fprintf (stderr, " (Linux/Alpha)"); ++ ++ #undef CPP_PREDEFINES ++ #define CPP_PREDEFINES "\ ++ -D__alpha -D__alpha__ -D__linux__ -D__linux -D_LONGLONG -Dlinux -Dunix \ ++ -Asystem(linux) -Acpu(alpha) -Amachine(alpha)" ++ ++ /* We don't actually need any of these; the MD_ vars are ignored ++ anyway for cross-compilers, and the other specs won't get picked up ++ 'coz the user is supposed to do ld -r (hmm, perhaps that should be ++ the default). In any case, setting them thus will catch some ++ common user errors. */ ++ ++ #undef MD_EXEC_PREFIX ++ #undef MD_STARTFILE_PREFIX ++ ++ #undef LIB_SPEC ++ #define LIB_SPEC "%{pg:-lgmon} %{pg:-lc_p} %{!pg:-lc}" ++ ++ #undef LINK_SPEC ++ #define LINK_SPEC \ ++ "-G 8 %{O*:-O3} %{!O*:-O1}" ++ ++ #undef ASM_SPEC ++ #define ASM_SPEC "-nocpp" ++ ++ /* Can't do stabs */ ++ #undef SDB_DEBUGGING_INFO ++ ++ /* Prefer dbx. */ ++ #undef PREFERRED_DEBUGGING_TYPE ++ #define PREFERRED_DEBUGGING_TYPE DBX_DEBUG ++ ++ #undef FUNCTION_PROFILER ++ ++ #define FUNCTION_PROFILER(FILE, LABELNO) \ ++ do { \ ++ fputs ("\tlda $27,_mcount\n", (FILE)); \ ++ fputs ("\tjsr $26,($27),_mcount\n", (FILE)); \ ++ fputs ("\tldgp $29,0($26)\n", (FILE)); \ ++ } while (0); ++ ++ /* Generate calls to memcpy, etc., not bcopy, etc. */ ++ #define TARGET_MEM_FUNCTIONS +diff -rcp2N gcc-2.7.2.2/config/alpha/t-linux gcc-2.7.2.2.f.2/config/alpha/t-linux +*** gcc-2.7.2.2/config/alpha/t-linux Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.2.f.2/config/alpha/t-linux Thu Dec 19 12:31:08 1996 +*************** +*** 0 **** +--- 1,3 ---- ++ # Our header files are supposed to be correct, nein? ++ FIXINCLUDES = ++ STMP_FIXPROTO = +diff -rcp2N gcc-2.7.2.2/config/alpha/x-linux gcc-2.7.2.2.f.2/config/alpha/x-linux +*** gcc-2.7.2.2/config/alpha/x-linux Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.2.f.2/config/alpha/x-linux Thu Dec 19 12:31:08 1996 +*************** +*** 0 **** +--- 1 ---- ++ CLIB=-lbfd -liberty +diff -rcp2N gcc-2.7.2.2/config/alpha/xm-alpha.h gcc-2.7.2.2.f.2/config/alpha/xm-alpha.h +*** gcc-2.7.2.2/config/alpha/xm-alpha.h Thu Aug 31 17:52:27 1995 +--- gcc-2.7.2.2.f.2/config/alpha/xm-alpha.h Thu Dec 19 12:31:08 1996 +*************** Boston, MA 02111-1307, USA. */ +*** 46,51 **** +--- 46,53 ---- + #include <alloca.h> + #else ++ #ifndef __alpha__ + extern void *alloca (); + #endif ++ #endif + + /* The host compiler has problems with enum bitfields since it makes +*************** extern void *malloc (), *realloc (), *ca +*** 68,72 **** +--- 70,76 ---- + /* OSF/1 has vprintf. */ + ++ #ifndef linux /* 1996/02/22 mauro@craftwork.com -- unreliable with Linux */ + #define HAVE_VPRINTF ++ #endif + + /* OSF/1 has putenv. */ +diff -rcp2N gcc-2.7.2.2/config/alpha/xm-linux.h gcc-2.7.2.2.f.2/config/alpha/xm-linux.h +*** gcc-2.7.2.2/config/alpha/xm-linux.h Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.2.f.2/config/alpha/xm-linux.h Thu Dec 19 12:31:08 1996 +*************** +*** 0 **** +--- 1,8 ---- ++ #ifndef _XM_LINUX_H ++ #define _XM_LINUX_H ++ ++ #include "xm-alpha.h" ++ ++ #define DONT_DECLARE_SYS_SIGLIST ++ #define USE_BFD ++ #endif +diff -rcp2N gcc-2.7.2.2/config/x-linux gcc-2.7.2.2.f.2/config/x-linux +*** gcc-2.7.2.2/config/x-linux Tue Mar 28 07:43:37 1995 +--- gcc-2.7.2.2.f.2/config/x-linux Thu Dec 19 12:31:08 1996 +*************** BOOT_CFLAGS = -O $(CFLAGS) -Iinclude +*** 13,14 **** +--- 13,17 ---- + # Don't run fixproto + STMP_FIXPROTO = ++ ++ # Don't install "assert.h" in gcc. We use the one in glibc. ++ INSTALL_ASSERT_H = +diff -rcp2N gcc-2.7.2.2/config/x-linux-aout gcc-2.7.2.2.f.2/config/x-linux-aout +*** gcc-2.7.2.2/config/x-linux-aout Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.2.f.2/config/x-linux-aout Thu Dec 19 12:31:08 1996 +*************** +*** 0 **** +--- 1,14 ---- ++ # It is defined in config/xm-linux.h. ++ # X_CFLAGS = -DPOSIX ++ ++ # The following is needed when compiling stages 2 and 3 because gcc's ++ # limits.h must be picked up before /usr/include/limits.h. This is because ++ # each does an #include_next of the other if the other hasn't been included. ++ # /usr/include/limits.h loses if it gets found first because /usr/include is ++ # at the end of the search order. When a new version of gcc is released, ++ # gcc's limits.h hasn't been installed yet and hence isn't found. ++ ++ BOOT_CFLAGS = -O $(CFLAGS) -Iinclude ++ ++ # Don't run fixproto ++ STMP_FIXPROTO = +diff -rcp2N gcc-2.7.2.2/configure gcc-2.7.2.2.f.2/configure +*** gcc-2.7.2.2/configure Thu Feb 20 19:24:33 1997 +--- gcc-2.7.2.2.f.2/configure Sun Feb 23 16:15:12 1997 +*************** exec_prefix='$(prefix)' +*** 82,85 **** +--- 82,86 ---- + # The default g++ include directory is $(libdir)/g++-include. + gxx_include_dir='$(libdir)/g++-include' ++ #gxx_include_dir='$(exec_prefix)/include/g++' + + # Default --program-transform-name to nothing. +*************** for machine in $canon_build $canon_host +*** 548,551 **** +--- 549,559 ---- + use_collect2=yes + ;; ++ alpha-*-linux*) ++ tm_file=alpha/linux.h ++ tmake_file=alpha/t-linux ++ xmake_file=alpha/x-linux ++ fixincludes=Makefile.in ++ xm_file=alpha/xm-linux.h ++ ;; + alpha-dec-osf[23456789]*) + tm_file=alpha/osf2.h +*************** for machine in $canon_build $canon_host +*** 985,989 **** + cpu_type=i386 # with a.out format using pre BFD linkers + xm_file=i386/xm-linux.h +! xmake_file=x-linux + tm_file=i386/linux-oldld.h + fixincludes=Makefile.in # The headers are ok already. +--- 993,997 ---- + cpu_type=i386 # with a.out format using pre BFD linkers + xm_file=i386/xm-linux.h +! xmake_file=x-linux-aout + tm_file=i386/linux-oldld.h + fixincludes=Makefile.in # The headers are ok already. +*************** for machine in $canon_build $canon_host +*** 994,998 **** + cpu_type=i386 # with a.out format + xm_file=i386/xm-linux.h +! xmake_file=x-linux + tm_file=i386/linux-aout.h + fixincludes=Makefile.in # The headers are ok already. +--- 1002,1006 ---- + cpu_type=i386 # with a.out format + xm_file=i386/xm-linux.h +! xmake_file=x-linux-aout + tm_file=i386/linux-aout.h + fixincludes=Makefile.in # The headers are ok already. +*************** for machine in $canon_build $canon_host +*** 1003,1007 **** + cpu_type=i386 # with ELF format, using GNU libc v1. + xm_file=i386/xm-linux.h +! xmake_file=x-linux + tmake_file=t-linux-libc1 + tm_file=i386/linux.h +--- 1011,1015 ---- + cpu_type=i386 # with ELF format, using GNU libc v1. + xm_file=i386/xm-linux.h +! xmake_file=x-linux-aout + tmake_file=t-linux-libc1 + tm_file=i386/linux.h +diff -rcp2N gcc-2.7.2.2/cse.c gcc-2.7.2.2.f.2/cse.c +*** gcc-2.7.2.2/cse.c Sun Nov 26 14:47:05 1995 +--- gcc-2.7.2.2.f.2/cse.c Fri Jan 10 23:18:22 1997 +*************** static struct table_elt *last_jump_equiv +*** 520,544 **** + static int constant_pool_entries_cost; + +- /* Bits describing what kind of values in memory must be invalidated +- for a particular instruction. If all three bits are zero, +- no memory refs need to be invalidated. Each bit is more powerful +- than the preceding ones, and if a bit is set then the preceding +- bits are also set. +- +- Here is how the bits are set: +- Pushing onto the stack invalidates only the stack pointer, +- writing at a fixed address invalidates only variable addresses, +- writing in a structure element at variable address +- invalidates all but scalar variables, +- and writing in anything else at variable address invalidates everything. */ +- +- struct write_data +- { +- int sp : 1; /* Invalidate stack pointer. */ +- int var : 1; /* Invalidate variable addresses. */ +- int nonscalar : 1; /* Invalidate all but scalar variables. */ +- int all : 1; /* Invalidate all memory refs. */ +- }; +- + /* Define maximum length of a branch path. */ + +--- 520,523 ---- +*************** static void merge_equiv_classes PROTO((s +*** 626,632 **** + struct table_elt *)); + static void invalidate PROTO((rtx, enum machine_mode)); + static void remove_invalid_refs PROTO((int)); + static void rehash_using_reg PROTO((rtx)); +! static void invalidate_memory PROTO((struct write_data *)); + static void invalidate_for_call PROTO((void)); + static rtx use_related_value PROTO((rtx, struct table_elt *)); +--- 605,612 ---- + struct table_elt *)); + static void invalidate PROTO((rtx, enum machine_mode)); ++ static int cse_rtx_varies_p PROTO((rtx)); + static void remove_invalid_refs PROTO((int)); + static void rehash_using_reg PROTO((rtx)); +! static void invalidate_memory PROTO((void)); + static void invalidate_for_call PROTO((void)); + static rtx use_related_value PROTO((rtx, struct table_elt *)); +*************** static void set_nonvarying_address_compo +*** 638,644 **** + HOST_WIDE_INT *)); + static int refers_to_p PROTO((rtx, rtx)); +- static int refers_to_mem_p PROTO((rtx, rtx, HOST_WIDE_INT, +- HOST_WIDE_INT)); +- static int cse_rtx_addr_varies_p PROTO((rtx)); + static rtx canon_reg PROTO((rtx, rtx)); + static void find_best_addr PROTO((rtx, rtx *)); +--- 618,621 ---- +*************** static void record_jump_cond PROTO((enum +*** 656,661 **** + rtx, rtx, int)); + static void cse_insn PROTO((rtx, int)); +! static void note_mem_written PROTO((rtx, struct write_data *)); +! static void invalidate_from_clobbers PROTO((struct write_data *, rtx)); + static rtx cse_process_notes PROTO((rtx, rtx)); + static void cse_around_loop PROTO((rtx)); +--- 633,638 ---- + rtx, rtx, int)); + static void cse_insn PROTO((rtx, int)); +! static int note_mem_written PROTO((rtx)); +! static void invalidate_from_clobbers PROTO((rtx)); + static rtx cse_process_notes PROTO((rtx, rtx)); + static void cse_around_loop PROTO((rtx)); +*************** invalidate (x, full_mode) +*** 1512,1517 **** + register int i; + register struct table_elt *p; +- rtx base; +- HOST_WIDE_INT start, end; + + /* If X is a register, dependencies on its contents +--- 1489,1492 ---- +*************** invalidate (x, full_mode) +*** 1605,1611 **** + full_mode = GET_MODE (x); + +- set_nonvarying_address_components (XEXP (x, 0), GET_MODE_SIZE (full_mode), +- &base, &start, &end); +- + for (i = 0; i < NBUCKETS; i++) + { +--- 1580,1583 ---- +*************** invalidate (x, full_mode) +*** 1614,1618 **** + { + next = p->next_same_hash; +! if (refers_to_mem_p (p->exp, base, start, end)) + remove_from_table (p, i); + } +--- 1586,1594 ---- + { + next = p->next_same_hash; +! /* Invalidate ASM_OPERANDS which reference memory (this is easier +! than checking all the aliases). */ +! if (p->in_memory +! && (GET_CODE (p->exp) != MEM +! || true_dependence (x, full_mode, p->exp, cse_rtx_varies_p))) + remove_from_table (p, i); + } +*************** rehash_using_reg (x) +*** 1695,1722 **** + } + +- /* Remove from the hash table all expressions that reference memory, +- or some of them as specified by *WRITES. */ +- +- static void +- invalidate_memory (writes) +- struct write_data *writes; +- { +- register int i; +- register struct table_elt *p, *next; +- int all = writes->all; +- int nonscalar = writes->nonscalar; +- +- for (i = 0; i < NBUCKETS; i++) +- for (p = table[i]; p; p = next) +- { +- next = p->next_same_hash; +- if (p->in_memory +- && (all +- || (nonscalar && p->in_struct) +- || cse_rtx_addr_varies_p (p->exp))) +- remove_from_table (p, i); +- } +- } +- + /* Remove from the hash table any expression that is a call-clobbered + register. Also update their TICK values. */ +--- 1671,1674 ---- +*************** invalidate_for_call () +*** 1756,1759 **** +--- 1708,1717 ---- + next = p->next_same_hash; + ++ if (p->in_memory) ++ { ++ remove_from_table (p, hash); ++ continue; ++ } ++ + if (GET_CODE (p->exp) != REG + || REGNO (p->exp) >= FIRST_PSEUDO_REGISTER) +*************** set_nonvarying_address_components (addr, +*** 2395,2477 **** + } + +! /* Return 1 iff any subexpression of X refers to memory +! at an address of BASE plus some offset +! such that any of the bytes' offsets fall between START (inclusive) +! and END (exclusive). +! +! The value is undefined if X is a varying address (as determined by +! cse_rtx_addr_varies_p). This function is not used in such cases. +! +! When used in the cse pass, `qty_const' is nonzero, and it is used +! to treat an address that is a register with a known constant value +! as if it were that constant value. +! In the loop pass, `qty_const' is zero, so this is not done. */ +! +! static int +! refers_to_mem_p (x, base, start, end) +! rtx x, base; +! HOST_WIDE_INT start, end; +! { +! register HOST_WIDE_INT i; +! register enum rtx_code code; +! register char *fmt; +! +! repeat: +! if (x == 0) +! return 0; +! +! code = GET_CODE (x); +! if (code == MEM) +! { +! register rtx addr = XEXP (x, 0); /* Get the address. */ +! rtx mybase; +! HOST_WIDE_INT mystart, myend; +! +! set_nonvarying_address_components (addr, GET_MODE_SIZE (GET_MODE (x)), +! &mybase, &mystart, &myend); +! +! +! /* refers_to_mem_p is never called with varying addresses. +! If the base addresses are not equal, there is no chance +! of the memory addresses conflicting. */ +! if (! rtx_equal_p (mybase, base)) +! return 0; +! +! return myend > start && mystart < end; +! } +! +! /* X does not match, so try its subexpressions. */ +! +! fmt = GET_RTX_FORMAT (code); +! for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) +! if (fmt[i] == 'e') +! { +! if (i == 0) +! { +! x = XEXP (x, 0); +! goto repeat; +! } +! else +! if (refers_to_mem_p (XEXP (x, i), base, start, end)) +! return 1; +! } +! else if (fmt[i] == 'E') +! { +! int j; +! for (j = 0; j < XVECLEN (x, i); j++) +! if (refers_to_mem_p (XVECEXP (x, i, j), base, start, end)) +! return 1; +! } +! +! return 0; +! } +! +! /* Nonzero if X refers to memory at a varying address; + except that a register which has at the moment a known constant value + isn't considered variable. */ + + static int +! cse_rtx_addr_varies_p (x) +! rtx x; + { + /* We need not check for X and the equivalence class being of the same +--- 2353,2363 ---- + } + +! /* Nonzero if X, a memory address, refers to a varying address; + except that a register which has at the moment a known constant value + isn't considered variable. */ + + static int +! cse_rtx_varies_p (x) +! register rtx x; + { + /* We need not check for X and the equivalence class being of the same +*************** cse_rtx_addr_varies_p (x) +*** 2479,2497 **** + doesn't vary in any mode. */ + +! if (GET_CODE (x) == MEM +! && GET_CODE (XEXP (x, 0)) == REG +! && REGNO_QTY_VALID_P (REGNO (XEXP (x, 0))) +! && GET_MODE (XEXP (x, 0)) == qty_mode[reg_qty[REGNO (XEXP (x, 0))]] +! && qty_const[reg_qty[REGNO (XEXP (x, 0))]] != 0) + return 0; + +! if (GET_CODE (x) == MEM +! && GET_CODE (XEXP (x, 0)) == PLUS +! && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT +! && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG +! && REGNO_QTY_VALID_P (REGNO (XEXP (XEXP (x, 0), 0))) +! && (GET_MODE (XEXP (XEXP (x, 0), 0)) +! == qty_mode[reg_qty[REGNO (XEXP (XEXP (x, 0), 0))]]) +! && qty_const[reg_qty[REGNO (XEXP (XEXP (x, 0), 0))]]) + return 0; + +--- 2365,2381 ---- + doesn't vary in any mode. */ + +! if (GET_CODE (x) == REG +! && REGNO_QTY_VALID_P (REGNO (x)) +! && GET_MODE (x) == qty_mode[reg_qty[REGNO (x)]] +! && qty_const[reg_qty[REGNO (x)]] != 0) + return 0; + +! if (GET_CODE (x) == PLUS +! && GET_CODE (XEXP (x, 1)) == CONST_INT +! && GET_CODE (XEXP (x, 0)) == REG +! && REGNO_QTY_VALID_P (REGNO (XEXP (x, 0))) +! && (GET_MODE (XEXP (x, 0)) +! == qty_mode[reg_qty[REGNO (XEXP (x, 0))]]) +! && qty_const[reg_qty[REGNO (XEXP (x, 0))]]) + return 0; + +*************** cse_rtx_addr_varies_p (x) +*** 2501,2519 **** + load fp minus a constant into a register, then a MEM which is the + sum of the two `constant' registers. */ +! if (GET_CODE (x) == MEM +! && GET_CODE (XEXP (x, 0)) == PLUS +! && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG +! && GET_CODE (XEXP (XEXP (x, 0), 1)) == REG +! && REGNO_QTY_VALID_P (REGNO (XEXP (XEXP (x, 0), 0))) +! && (GET_MODE (XEXP (XEXP (x, 0), 0)) +! == qty_mode[reg_qty[REGNO (XEXP (XEXP (x, 0), 0))]]) +! && qty_const[reg_qty[REGNO (XEXP (XEXP (x, 0), 0))]] +! && REGNO_QTY_VALID_P (REGNO (XEXP (XEXP (x, 0), 1))) +! && (GET_MODE (XEXP (XEXP (x, 0), 1)) +! == qty_mode[reg_qty[REGNO (XEXP (XEXP (x, 0), 1))]]) +! && qty_const[reg_qty[REGNO (XEXP (XEXP (x, 0), 1))]]) + return 0; + +! return rtx_addr_varies_p (x); + } + +--- 2385,2402 ---- + load fp minus a constant into a register, then a MEM which is the + sum of the two `constant' registers. */ +! if (GET_CODE (x) == PLUS +! && GET_CODE (XEXP (x, 0)) == REG +! && GET_CODE (XEXP (x, 1)) == REG +! && REGNO_QTY_VALID_P (REGNO (XEXP (x, 0))) +! && (GET_MODE (XEXP (x, 0)) +! == qty_mode[reg_qty[REGNO (XEXP (x, 0))]]) +! && qty_const[reg_qty[REGNO (XEXP (x, 0))]] +! && REGNO_QTY_VALID_P (REGNO (XEXP (x, 1))) +! && (GET_MODE (XEXP (x, 1)) +! == qty_mode[reg_qty[REGNO (XEXP (x, 1))]]) +! && qty_const[reg_qty[REGNO (XEXP (x, 1))]]) + return 0; + +! return rtx_varies_p (x); + } + +*************** cse_insn (insn, in_libcall_block) +*** 6105,6110 **** + rtx this_insn_cc0 = 0; + enum machine_mode this_insn_cc0_mode; +- struct write_data writes_memory; +- static struct write_data init = {0, 0, 0, 0}; + + rtx src_eqv = 0; +--- 5988,5991 ---- +*************** cse_insn (insn, in_libcall_block) +*** 6118,6122 **** + + this_insn = insn; +- writes_memory = init; + + /* Find all the SETs and CLOBBERs in this instruction. +--- 5999,6002 ---- +*************** cse_insn (insn, in_libcall_block) +*** 6220,6225 **** + else if (GET_CODE (y) == CLOBBER) + { +! /* If we clobber memory, take note of that, +! and canon the address. + This does nothing when a register is clobbered + because we have already invalidated the reg. */ +--- 6100,6104 ---- + else if (GET_CODE (y) == CLOBBER) + { +! /* If we clobber memory, canon the address. + This does nothing when a register is clobbered + because we have already invalidated the reg. */ +*************** cse_insn (insn, in_libcall_block) +*** 6227,6231 **** + { + canon_reg (XEXP (y, 0), NULL_RTX); +! note_mem_written (XEXP (y, 0), &writes_memory); + } + } +--- 6106,6110 ---- + { + canon_reg (XEXP (y, 0), NULL_RTX); +! note_mem_written (XEXP (y, 0)); + } + } +*************** cse_insn (insn, in_libcall_block) +*** 6249,6253 **** + { + canon_reg (XEXP (x, 0), NULL_RTX); +! note_mem_written (XEXP (x, 0), &writes_memory); + } + } +--- 6128,6132 ---- + { + canon_reg (XEXP (x, 0), NULL_RTX); +! note_mem_written (XEXP (x, 0)); + } + } +*************** cse_insn (insn, in_libcall_block) +*** 6674,6678 **** + } + #endif /* LOAD_EXTEND_OP */ +! + if (src == src_folded) + src_folded = 0; +--- 6553,6557 ---- + } + #endif /* LOAD_EXTEND_OP */ +! + if (src == src_folded) + src_folded = 0; +*************** cse_insn (insn, in_libcall_block) +*** 6860,6864 **** + || (GET_CODE (src_folded) != MEM + && ! src_folded_force_flag)) +! && GET_MODE_CLASS (mode) != MODE_CC) + { + src_folded_force_flag = 1; +--- 6739,6744 ---- + || (GET_CODE (src_folded) != MEM + && ! src_folded_force_flag)) +! && GET_MODE_CLASS (mode) != MODE_CC +! && mode != VOIDmode) + { + src_folded_force_flag = 1; +*************** cse_insn (insn, in_libcall_block) +*** 6984,6993 **** + { + dest = fold_rtx (dest, insn); +! +! /* Decide whether we invalidate everything in memory, +! or just things at non-fixed places. +! Writing a large aggregate must invalidate everything +! because we don't know how long it is. */ +! note_mem_written (dest, &writes_memory); + } + +--- 6864,6868 ---- + { + dest = fold_rtx (dest, insn); +! note_mem_written (dest); + } + +*************** cse_insn (insn, in_libcall_block) +*** 7234,7238 **** + sets[i].src_elt = src_eqv_elt; + +! invalidate_from_clobbers (&writes_memory, x); + + /* Some registers are invalidated by subroutine calls. Memory is +--- 7109,7113 ---- + sets[i].src_elt = src_eqv_elt; + +! invalidate_from_clobbers (x); + + /* Some registers are invalidated by subroutine calls. Memory is +*************** cse_insn (insn, in_libcall_block) +*** 7241,7248 **** + if (GET_CODE (insn) == CALL_INSN) + { +- static struct write_data everything = {0, 1, 1, 1}; +- + if (! CONST_CALL_P (insn)) +! invalidate_memory (&everything); + invalidate_for_call (); + } +--- 7116,7121 ---- + if (GET_CODE (insn) == CALL_INSN) + { + if (! CONST_CALL_P (insn)) +! invalidate_memory (); + invalidate_for_call (); + } +*************** cse_insn (insn, in_libcall_block) +*** 7265,7270 **** + we have just done an invalidate_memory that covers even those. */ + if (GET_CODE (dest) == REG || GET_CODE (dest) == SUBREG +! || (GET_CODE (dest) == MEM && ! writes_memory.all +! && ! cse_rtx_addr_varies_p (dest))) + invalidate (dest, VOIDmode); + else if (GET_CODE (dest) == STRICT_LOW_PART +--- 7138,7142 ---- + we have just done an invalidate_memory that covers even those. */ + if (GET_CODE (dest) == REG || GET_CODE (dest) == SUBREG +! || GET_CODE (dest) == MEM) + invalidate (dest, VOIDmode); + else if (GET_CODE (dest) == STRICT_LOW_PART +*************** cse_insn (insn, in_libcall_block) +*** 7532,7580 **** + } + +- /* Store 1 in *WRITES_PTR for those categories of memory ref +- that must be invalidated when the expression WRITTEN is stored in. +- If WRITTEN is null, say everything must be invalidated. */ +- + static void +! note_mem_written (written, writes_ptr) +! rtx written; +! struct write_data *writes_ptr; +! { +! static struct write_data everything = {0, 1, 1, 1}; +! +! if (written == 0) +! *writes_ptr = everything; +! else if (GET_CODE (written) == MEM) +! { +! /* Pushing or popping the stack invalidates just the stack pointer. */ +! rtx addr = XEXP (written, 0); +! if ((GET_CODE (addr) == PRE_DEC || GET_CODE (addr) == PRE_INC +! || GET_CODE (addr) == POST_DEC || GET_CODE (addr) == POST_INC) +! && GET_CODE (XEXP (addr, 0)) == REG +! && REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM) +! { +! writes_ptr->sp = 1; +! return; +! } +! else if (GET_MODE (written) == BLKmode) +! *writes_ptr = everything; +! /* (mem (scratch)) means clobber everything. */ +! else if (GET_CODE (addr) == SCRATCH) +! *writes_ptr = everything; +! else if (cse_rtx_addr_varies_p (written)) +! { +! /* A varying address that is a sum indicates an array element, +! and that's just as good as a structure element +! in implying that we need not invalidate scalar variables. +! However, we must allow QImode aliasing of scalars, because the +! ANSI C standard allows character pointers to alias anything. */ +! if (! ((MEM_IN_STRUCT_P (written) +! || GET_CODE (XEXP (written, 0)) == PLUS) +! && GET_MODE (written) != QImode)) +! writes_ptr->all = 1; +! writes_ptr->nonscalar = 1; +! } +! writes_ptr->var = 1; + } + } + +--- 7404,7447 ---- + } + + static void +! invalidate_memory () +! { +! register int i; +! register struct table_elt *p, *next; +! +! for (i = 0; i < NBUCKETS; i++) +! for (p = table[i]; p; p = next) +! { +! next = p->next_same_hash; +! if (p->in_memory) +! remove_from_table (p, i); +! } +! } +! +! static int +! note_mem_written (mem) +! register rtx mem; +! { +! if (mem == 0 || GET_CODE(mem) != MEM ) +! return 0; +! else +! { +! register rtx addr = XEXP (mem, 0); +! /* Pushing or popping the stack invalidates just the stack pointer. */ +! if ((GET_CODE (addr) == PRE_DEC || GET_CODE (addr) == PRE_INC +! || GET_CODE (addr) == POST_DEC || GET_CODE (addr) == POST_INC) +! && GET_CODE (XEXP (addr, 0)) == REG +! && REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM) +! { +! if (reg_tick[STACK_POINTER_REGNUM] >= 0) +! reg_tick[STACK_POINTER_REGNUM]++; +! +! /* This should be *very* rare. */ +! if (TEST_HARD_REG_BIT (hard_regs_in_table, STACK_POINTER_REGNUM)) +! invalidate (stack_pointer_rtx, VOIDmode); +! return 1; + } ++ return 0; ++ } + } + +*************** note_mem_written (written, writes_ptr) +*** 7584,7612 **** + alias with something that is SET or CLOBBERed. + +- W points to the writes_memory for this insn, a struct write_data +- saying which kinds of memory references must be invalidated. + X is the pattern of the insn. */ + + static void +! invalidate_from_clobbers (w, x) +! struct write_data *w; + rtx x; + { +- /* If W->var is not set, W specifies no action. +- If W->all is set, this step gets all memory refs +- so they can be ignored in the rest of this function. */ +- if (w->var) +- invalidate_memory (w); +- +- if (w->sp) +- { +- if (reg_tick[STACK_POINTER_REGNUM] >= 0) +- reg_tick[STACK_POINTER_REGNUM]++; +- +- /* This should be *very* rare. */ +- if (TEST_HARD_REG_BIT (hard_regs_in_table, STACK_POINTER_REGNUM)) +- invalidate (stack_pointer_rtx, VOIDmode); +- } +- + if (GET_CODE (x) == CLOBBER) + { +--- 7451,7460 ---- + alias with something that is SET or CLOBBERed. + + X is the pattern of the insn. */ + + static void +! invalidate_from_clobbers (x) + rtx x; + { + if (GET_CODE (x) == CLOBBER) + { +*************** invalidate_from_clobbers (w, x) +*** 7615,7619 **** + { + if (GET_CODE (ref) == REG || GET_CODE (ref) == SUBREG +! || (GET_CODE (ref) == MEM && ! w->all)) + invalidate (ref, VOIDmode); + else if (GET_CODE (ref) == STRICT_LOW_PART +--- 7463,7467 ---- + { + if (GET_CODE (ref) == REG || GET_CODE (ref) == SUBREG +! || GET_CODE (ref) == MEM) + invalidate (ref, VOIDmode); + else if (GET_CODE (ref) == STRICT_LOW_PART +*************** invalidate_from_clobbers (w, x) +*** 7634,7638 **** + { + if (GET_CODE (ref) == REG || GET_CODE (ref) == SUBREG +! || (GET_CODE (ref) == MEM && !w->all)) + invalidate (ref, VOIDmode); + else if (GET_CODE (ref) == STRICT_LOW_PART +--- 7482,7486 ---- + { + if (GET_CODE (ref) == REG || GET_CODE (ref) == SUBREG +! || GET_CODE (ref) == MEM) + invalidate (ref, VOIDmode); + else if (GET_CODE (ref) == STRICT_LOW_PART +*************** cse_around_loop (loop_start) +*** 7800,7807 **** + } + +- /* Variable used for communications between the next two routines. */ +- +- static struct write_data skipped_writes_memory; +- + /* Process one SET of an insn that was skipped. We ignore CLOBBERs + since they are done elsewhere. This function is called via note_stores. */ +--- 7648,7651 ---- +*************** invalidate_skipped_set (dest, set) +*** 7812,7815 **** +--- 7656,7675 ---- + rtx dest; + { ++ enum rtx_code code = GET_CODE (dest); ++ ++ if (code == MEM ++ && ! note_mem_written (dest) /* If this is not a stack push ... */ ++ /* There are times when an address can appear varying and be a PLUS ++ during this scan when it would be a fixed address were we to know ++ the proper equivalences. So invalidate all memory if there is ++ a BLKmode or nonscalar memory reference or a reference to a ++ variable address. */ ++ && (MEM_IN_STRUCT_P (dest) || GET_MODE (dest) == BLKmode ++ || cse_rtx_varies_p (XEXP (dest, 0)))) ++ { ++ invalidate_memory (); ++ return; ++ } ++ + if (GET_CODE (set) == CLOBBER + #ifdef HAVE_cc0 +*************** invalidate_skipped_set (dest, set) +*** 7819,7837 **** + return; + +! if (GET_CODE (dest) == MEM) +! note_mem_written (dest, &skipped_writes_memory); +! +! /* There are times when an address can appear varying and be a PLUS +! during this scan when it would be a fixed address were we to know +! the proper equivalences. So promote "nonscalar" to be "all". */ +! if (skipped_writes_memory.nonscalar) +! skipped_writes_memory.all = 1; +! +! if (GET_CODE (dest) == REG || GET_CODE (dest) == SUBREG +! || (! skipped_writes_memory.all && ! cse_rtx_addr_varies_p (dest))) +! invalidate (dest, VOIDmode); +! else if (GET_CODE (dest) == STRICT_LOW_PART +! || GET_CODE (dest) == ZERO_EXTRACT) + invalidate (XEXP (dest, 0), GET_MODE (dest)); + } + +--- 7679,7686 ---- + return; + +! if (code == STRICT_LOW_PART || code == ZERO_EXTRACT) + invalidate (XEXP (dest, 0), GET_MODE (dest)); ++ else if (code == REG || code == SUBREG || code == MEM) ++ invalidate (dest, VOIDmode); + } + +*************** invalidate_skipped_block (start) +*** 7845,7850 **** + { + rtx insn; +- static struct write_data init = {0, 0, 0, 0}; +- static struct write_data everything = {0, 1, 1, 1}; + + for (insn = start; insn && GET_CODE (insn) != CODE_LABEL; +--- 7694,7697 ---- +*************** invalidate_skipped_block (start) +*** 7854,7867 **** + continue; + +- skipped_writes_memory = init; +- + if (GET_CODE (insn) == CALL_INSN) + { + invalidate_for_call (); +- skipped_writes_memory = everything; + } + + note_stores (PATTERN (insn), invalidate_skipped_set); +- invalidate_from_clobbers (&skipped_writes_memory, PATTERN (insn)); + } + } +--- 7701,7712 ---- + continue; + + if (GET_CODE (insn) == CALL_INSN) + { ++ if (! CONST_CALL_P (insn)) ++ invalidate_memory (); + invalidate_for_call (); + } + + note_stores (PATTERN (insn), invalidate_skipped_set); + } + } +*************** cse_set_around_loop (x, insn, loop_start +*** 7913,7920 **** + { + struct table_elt *src_elt; +- static struct write_data init = {0, 0, 0, 0}; +- struct write_data writes_memory; +- +- writes_memory = init; + + /* If this is a SET, see if we can replace SET_SRC, but ignore SETs that +--- 7758,7761 ---- +*************** cse_set_around_loop (x, insn, loop_start +*** 7976,7991 **** + + /* Now invalidate anything modified by X. */ +! note_mem_written (SET_DEST (x), &writes_memory); +! +! if (writes_memory.var) +! invalidate_memory (&writes_memory); +! +! /* See comment on similar code in cse_insn for explanation of these tests. */ +! if (GET_CODE (SET_DEST (x)) == REG || GET_CODE (SET_DEST (x)) == SUBREG +! || (GET_CODE (SET_DEST (x)) == MEM && ! writes_memory.all +! && ! cse_rtx_addr_varies_p (SET_DEST (x)))) +! invalidate (SET_DEST (x), VOIDmode); +! else if (GET_CODE (SET_DEST (x)) == STRICT_LOW_PART +! || GET_CODE (SET_DEST (x)) == ZERO_EXTRACT) + invalidate (XEXP (SET_DEST (x), 0), GET_MODE (SET_DEST (x))); + } +--- 7817,7828 ---- + + /* Now invalidate anything modified by X. */ +! note_mem_written (SET_DEST (x)); +! +! /* See comment on similar code in cse_insn for explanation of these tests. */ +! if (GET_CODE (SET_DEST (x)) == REG || GET_CODE (SET_DEST (x)) == SUBREG +! || GET_CODE (SET_DEST (x)) == MEM) +! invalidate (SET_DEST (x), VOIDmode); +! else if (GET_CODE (SET_DEST (x)) == STRICT_LOW_PART +! || GET_CODE (SET_DEST (x)) == ZERO_EXTRACT) + invalidate (XEXP (SET_DEST (x), 0), GET_MODE (SET_DEST (x))); + } +*************** cse_main (f, nregs, after_loop, file) +*** 8234,8237 **** +--- 8071,8075 ---- + + init_recog (); ++ init_alias_analysis (); + + max_reg = nregs; +diff -rcp2N gcc-2.7.2.2/flags.h gcc-2.7.2.2.f.2/flags.h +*** gcc-2.7.2.2/flags.h Thu Jun 15 07:34:11 1995 +--- gcc-2.7.2.2.f.2/flags.h Fri Jan 10 23:18:22 1997 +*************** extern int flag_unroll_loops; +*** 204,207 **** +--- 204,221 ---- + extern int flag_unroll_all_loops; + ++ /* Nonzero forces all invariant computations in loops to be moved ++ outside the loop. */ ++ ++ extern int flag_move_all_movables; ++ ++ /* Nonzero forces all general induction variables in loops to be ++ strength reduced. */ ++ ++ extern int flag_reduce_all_givs; ++ ++ /* Nonzero gets another run of loop_optimize performed. */ ++ ++ extern int flag_rerun_loop_opt; ++ + /* Nonzero for -fcse-follow-jumps: + have cse follow jumps to do a more extensive job. */ +*************** extern int flag_gnu_linker; +*** 339,342 **** +--- 353,369 ---- + /* Tag all structures with __attribute__(packed) */ + extern int flag_pack_struct; ++ ++ /* 1 if alias checking is enabled: symbols do not alias each other ++ and parameters do not alias the current stack frame. */ ++ extern int flag_alias_check; ++ ++ /* This flag is only tested if alias checking is enabled. ++ 0 if pointer arguments may alias each other. True in C. ++ 1 if pointer arguments may not alias each other but may alias ++ global variables. ++ 2 if pointer arguments may not alias each other and may not ++ alias global variables. True in Fortran. ++ The value is ignored if flag_alias_check is 0. */ ++ extern int flag_argument_noalias; + + /* Other basic status info about current function. */ +diff -rcp2N gcc-2.7.2.2/fold-const.c gcc-2.7.2.2.f.2/fold-const.c +*** gcc-2.7.2.2/fold-const.c Fri Sep 15 18:26:12 1995 +--- gcc-2.7.2.2.f.2/fold-const.c Sun Feb 23 15:25:58 1997 +*************** static tree unextend PROTO((tree, int, i +*** 80,83 **** +--- 80,84 ---- + static tree fold_truthop PROTO((enum tree_code, tree, tree, tree)); + static tree strip_compound_expr PROTO((tree, tree)); ++ static int multiple_of_p PROTO((tree, tree, tree)); + + #ifndef BRANCH_COST +*************** strip_compound_expr (t, s) +*** 3065,3068 **** +--- 3066,3169 ---- + } + ++ /* Determine if first argument is a multiple of second argument. ++ Return 0 if it is not, or is not easily determined to so be. ++ ++ An example of the sort of thing we care about (at this point -- ++ this routine could surely be made more general, and expanded ++ to do what the *_DIV_EXPR's fold() cases do now) is discovering ++ that ++ ++ SAVE_EXPR (I) * SAVE_EXPR (J * 8) ++ ++ is a multiple of ++ ++ SAVE_EXPR (J * 8) ++ ++ when we know that the two `SAVE_EXPR (J * 8)' nodes are the ++ same node (which means they will have the same value at run ++ time, even though we don't know when they'll be assigned). ++ ++ This code also handles discovering that ++ ++ SAVE_EXPR (I) * SAVE_EXPR (J * 8) ++ ++ is a multiple of ++ ++ 8 ++ ++ (of course) so we don't have to worry about dealing with a ++ possible remainder. ++ ++ Note that we _look_ inside a SAVE_EXPR only to determine ++ how it was calculated; it is not safe for fold() to do much ++ of anything else with the internals of a SAVE_EXPR, since ++ fold() cannot know when it will be evaluated at run time. ++ For example, the latter example above _cannot_ be implemented ++ as ++ ++ SAVE_EXPR (I) * J ++ ++ or any variant thereof, since the value of J at evaluation time ++ of the original SAVE_EXPR is not necessarily the same at the time ++ the new expression is evaluated. The only optimization of this ++ sort that would be valid is changing ++ ++ SAVE_EXPR (I) * SAVE_EXPR (SAVE_EXPR (J) * 8) ++ divided by ++ 8 ++ ++ to ++ ++ SAVE_EXPR (I) * SAVE_EXPR (J) ++ ++ (where the same SAVE_EXPR (J) is used in the original and the ++ transformed version). */ ++ ++ static int ++ multiple_of_p (type, top, bottom) ++ tree type; ++ tree top; ++ tree bottom; ++ { ++ if (operand_equal_p (top, bottom, 0)) ++ return 1; ++ ++ if (TREE_CODE (type) != INTEGER_TYPE) ++ return 0; ++ ++ switch (TREE_CODE (top)) ++ { ++ case MULT_EXPR: ++ return (multiple_of_p (type, TREE_OPERAND (top, 0), bottom) ++ || multiple_of_p (type, TREE_OPERAND (top, 1), bottom)); ++ ++ case PLUS_EXPR: ++ case MINUS_EXPR: ++ return (multiple_of_p (type, TREE_OPERAND (top, 0), bottom) ++ && multiple_of_p (type, TREE_OPERAND (top, 1), bottom)); ++ ++ case NOP_EXPR: ++ /* Punt if conversion from non-integral or wider integral type. */ ++ if ((TREE_CODE (TREE_TYPE (TREE_OPERAND (top, 0))) != INTEGER_TYPE) ++ || (TYPE_PRECISION (type) ++ < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (top, 0))))) ++ return 0; ++ /* Fall through. */ ++ case SAVE_EXPR: ++ return multiple_of_p (type, TREE_OPERAND (top, 0), bottom); ++ ++ case INTEGER_CST: ++ if ((TREE_CODE (bottom) != INTEGER_CST) ++ || (tree_int_cst_sgn (top) < 0) ++ || (tree_int_cst_sgn (bottom) < 0)) ++ return 0; ++ return integer_zerop (const_binop (TRUNC_MOD_EXPR, ++ top, bottom, 0)); ++ ++ default: ++ return 0; ++ } ++ } ++ + /* Perform constant folding and related simplification of EXPR. + The related simplifications include x*1 => x, x*0 => 0, etc., +*************** fold (expr) +*** 4010,4013 **** +--- 4111,4121 ---- + case FLOOR_DIV_EXPR: + case CEIL_DIV_EXPR: ++ if (integer_onep (arg1)) ++ return non_lvalue (convert (type, arg0)); ++ /* If arg0 is a multiple of arg1, then rewrite to the fastest div ++ operation, EXACT_DIV_EXPR. Otherwise, handle folding of ++ general divide. */ ++ if (multiple_of_p (type, arg0, arg1)) ++ return fold (build (EXACT_DIV_EXPR, type, arg0, arg1)); + case EXACT_DIV_EXPR: + if (integer_onep (arg1)) +diff -rcp2N gcc-2.7.2.2/gcc.texi gcc-2.7.2.2.f.2/gcc.texi +*** gcc-2.7.2.2/gcc.texi Thu Feb 20 19:24:19 1997 +--- gcc-2.7.2.2.f.2/gcc.texi Sun Feb 23 16:16:49 1997 +*************** original English. +*** 149,152 **** +--- 149,153 ---- + @sp 3 + @center Last updated 29 June 1996 ++ @center (Revised for GNU Fortran 1997-01-10) + @sp 1 + @c The version number appears twice more in this file. +diff -rcp2N gcc-2.7.2.2/glimits.h gcc-2.7.2.2.f.2/glimits.h +*** gcc-2.7.2.2/glimits.h Wed Sep 29 17:30:54 1993 +--- gcc-2.7.2.2.f.2/glimits.h Thu Dec 19 12:31:08 1996 +*************** +*** 64,68 **** + (Same as `int'). */ + #ifndef __LONG_MAX__ +! #define __LONG_MAX__ 2147483647L + #endif + #undef LONG_MIN +--- 64,72 ---- + (Same as `int'). */ + #ifndef __LONG_MAX__ +! # ifndef __alpha__ +! # define __LONG_MAX__ 2147483647L +! # else +! # define __LONG_MAX__ 9223372036854775807LL +! # endif /* __alpha__ */ + #endif + #undef LONG_MIN +diff -rcp2N gcc-2.7.2.2/invoke.texi gcc-2.7.2.2.f.2/invoke.texi +*** gcc-2.7.2.2/invoke.texi Tue Oct 3 11:40:43 1995 +--- gcc-2.7.2.2.f.2/invoke.texi Sun Feb 23 16:18:06 1997 +*************** +*** 1,3 **** +! @c Copyright (C) 1988, 89, 92, 93, 94, 1995 Free Software Foundation, Inc. + @c This is part of the GCC manual. + @c For copying conditions, see the file gcc.texi. +--- 1,3 ---- +! @c Copyright (C) 1988, 89, 92-95, 1997 Free Software Foundation, Inc. + @c This is part of the GCC manual. + @c For copying conditions, see the file gcc.texi. +*************** in the following sections. +*** 149,152 **** +--- 149,153 ---- + -fschedule-insns2 -fstrength-reduce -fthread-jumps + -funroll-all-loops -funroll-loops ++ -fmove-all-movables -freduce-all-givs -frerun-loop-opt + -O -O0 -O1 -O2 -O3 + @end smallexample +*************** in addition to the above: +*** 331,334 **** +--- 332,337 ---- + -fshort-double -fvolatile -fvolatile-global + -fverbose-asm -fpack-struct +e0 +e1 ++ -fargument-alias -fargument-noalias ++ -fargument-noalias-global + @end smallexample + @end table +*************** and usually makes programs run more slow +*** 1941,1944 **** +--- 1944,1992 ---- + implies @samp{-fstrength-reduce} as well as @samp{-frerun-cse-after-loop}. + ++ @item -fmove-all-movables ++ Forces all invariant computations in loops to be moved ++ outside the loop. ++ This option is provided primarily to improve performance ++ for some Fortran code, though it might improve code written ++ in other languages. ++ ++ @emph{Note:} When compiling programs written in Fortran, ++ this option is enabled by default. ++ ++ Analysis of Fortran code optimization and the resulting ++ optimizations triggered by this option, and the ++ @samp{-freduce-all-givs} and @samp{-frerun-loop-opt} ++ options as well, were ++ contributed by Toon Moene (@code{toon@@moene.indiv.nluug.nl}). ++ ++ These three options are intended to be removed someday, once ++ they have helped determine the efficacy of various ++ approaches to improving the performance of Fortran code. ++ ++ Please let us (@code{fortran@@gnu.ai.mit.edu}) ++ know how use of these options affects ++ the performance of your production code. ++ We're very interested in code that runs @emph{slower} ++ when these options are @emph{enabled}. ++ ++ @item -freduce-all-givs ++ Forces all general-induction variables in loops to be ++ strength-reduced. ++ This option is provided primarily to improve performance ++ for some Fortran code, though it might improve code written ++ in other languages. ++ ++ @emph{Note:} When compiling programs written in Fortran, ++ this option is enabled by default. ++ ++ @item -frerun-loop-opt ++ Runs loop optimizations a second time. ++ This option is provided primarily to improve performance ++ for some Fortran code, though it might improve code written ++ in other languages. ++ ++ @emph{Note:} When compiling programs written in Fortran, ++ this option is enabled by default. ++ + @item -fno-peephole + Disable any machine-specific peephole optimizations. +*************** compilation). +*** 4229,4232 **** +--- 4277,4352 ---- + With @samp{+e1}, G++ actually generates the code implementing virtual + functions defined in the code, and makes them publicly visible. ++ ++ @cindex aliasing of parameters ++ @cindex parameters, aliased ++ @item -fargument-alias ++ @item -fargument-noalias ++ @item -fargument-noalias-global ++ Specify the possible relationships among parameters and between ++ parameters and global data. ++ ++ @samp{-fargument-alias} specifies that arguments (parameters) may ++ alias each other and may alias global storage. ++ @samp{-fargument-noalias} specifies that arguments do not alias ++ each other, but may alias global storage. ++ @samp{-fargument-noalias-global} specifies that arguments do not ++ alias each other and do not alias global storage. ++ ++ For code written in C, C++, and Objective-C, @samp{-fargument-alias} ++ is the default. ++ For code written in Fortran, @samp{-fargument-noalias-global} is ++ the default, though this is pertinent only on systems where ++ @code{g77} is installed. ++ (See the documentation for other compilers for information on the ++ defaults for their respective languages.) ++ ++ Normally, @code{gcc} assumes that a write through a pointer ++ passed as a parameter to the current function might modify a ++ value pointed to by another pointer passed as a parameter, or ++ in global storage. ++ ++ For example, consider this code: ++ ++ @example ++ void x(int *i, int *j) ++ @{ ++ extern int k; ++ ++ ++*i; ++ ++*j; ++ ++k; ++ @} ++ @end example ++ ++ When compiling the above function, @code{gcc} assumes that @samp{i} might ++ be a pointer to the same variable as @samp{j}, and that either @samp{i}, ++ @samp{j}, or both might be a pointer to @samp{k}. ++ ++ Therefore, @code{gcc} does not assume it can generate code to read ++ @samp{*i}, @samp{*j}, and @samp{k} into separate registers, increment ++ each register, then write the incremented values back out. ++ ++ Instead, @code{gcc} must generate code that reads @samp{*i}, ++ increments it, and writes it back before reading @samp{*j}, ++ in case @samp{i} and @samp{j} are aliased, and, similarly, ++ that writes @samp{*j} before reading @samp{k}. ++ The result is code that, on many systems, takes longer to execute, ++ due to the way many processors schedule instruction execution. ++ ++ Compiling the above code with the @samp{-fargument-noalias} option ++ allows @code{gcc} to assume that @samp{i} and @samp{j} do not alias ++ each other, but either might alias @samp{k}. ++ ++ Compiling the above code with the @samp{-fargument-noalias-global} ++ option allows @code{gcc} to assume that no combination of @samp{i}, ++ @samp{j}, and @samp{k} are aliases for each other. ++ ++ @emph{Note:} Use the @samp{-fargument-noalias} and ++ @samp{-fargument-noalias-global} options with care. ++ While they can result in faster executables, they can ++ also result in executables with subtle bugs, bugs that ++ show up only when compiled for specific target systems, ++ or bugs that show up only when compiled by specific versions ++ of @code{g77}. + @end table + +diff -rcp2N gcc-2.7.2.2/local-alloc.c gcc-2.7.2.2.f.2/local-alloc.c +*** gcc-2.7.2.2/local-alloc.c Mon Aug 21 13:15:44 1995 +--- gcc-2.7.2.2.f.2/local-alloc.c Fri Jan 10 23:18:22 1997 +*************** validate_equiv_mem_from_store (dest, set +*** 545,549 **** + && reg_overlap_mentioned_p (dest, equiv_mem)) + || (GET_CODE (dest) == MEM +! && true_dependence (dest, equiv_mem))) + equiv_mem_modified = 1; + } +--- 545,549 ---- + && reg_overlap_mentioned_p (dest, equiv_mem)) + || (GET_CODE (dest) == MEM +! && true_dependence (dest, VOIDmode, equiv_mem, rtx_varies_p))) + equiv_mem_modified = 1; + } +*************** memref_referenced_p (memref, x) +*** 630,634 **** + + case MEM: +! if (true_dependence (memref, x)) + return 1; + break; +--- 630,634 ---- + + case MEM: +! if (true_dependence (memref, VOIDmode, x, rtx_varies_p)) + return 1; + break; +diff -rcp2N gcc-2.7.2.2/loop.c gcc-2.7.2.2.f.2/loop.c +*** gcc-2.7.2.2/loop.c Thu Feb 20 19:24:20 1997 +--- gcc-2.7.2.2.f.2/loop.c Sun Feb 23 15:35:42 1997 +*************** int *loop_number_exit_count; +*** 111,116 **** + unsigned HOST_WIDE_INT loop_n_iterations; + +! /* Nonzero if there is a subroutine call in the current loop. +! (unknown_address_altered is also nonzero in this case.) */ + + static int loop_has_call; +--- 111,115 ---- + unsigned HOST_WIDE_INT loop_n_iterations; + +! /* Nonzero if there is a subroutine call in the current loop. */ + + static int loop_has_call; +*************** static char *moved_once; +*** 160,164 **** + here, we just turn on unknown_address_altered. */ + +! #define NUM_STORES 20 + static rtx loop_store_mems[NUM_STORES]; + +--- 159,163 ---- + here, we just turn on unknown_address_altered. */ + +! #define NUM_STORES 50 + static rtx loop_store_mems[NUM_STORES]; + +*************** move_movables (movables, threshold, insn +*** 1629,1632 **** +--- 1628,1632 ---- + + if (already_moved[regno] ++ || flag_move_all_movables + || (threshold * savings * m->lifetime) >= insn_count + || (m->forces && m->forces->done +*************** prescan_loop (start, end) +*** 2199,2203 **** + else if (GET_CODE (insn) == CALL_INSN) + { +! unknown_address_altered = 1; + loop_has_call = 1; + } +--- 2199,2204 ---- + else if (GET_CODE (insn) == CALL_INSN) + { +! if (! CONST_CALL_P (insn)) +! unknown_address_altered = 1; + loop_has_call = 1; + } +*************** invariant_p (x) +*** 2777,2781 **** + /* See if there is any dependence between a store and this load. */ + for (i = loop_store_mems_idx - 1; i >= 0; i--) +! if (true_dependence (loop_store_mems[i], x)) + return 0; + +--- 2778,2782 ---- + /* See if there is any dependence between a store and this load. */ + for (i = loop_store_mems_idx - 1; i >= 0; i--) +! if (true_dependence (loop_store_mems[i], VOIDmode, x, rtx_varies_p)) + return 0; + +*************** strength_reduce (scan_start, end, loop_t +*** 3821,3826 **** + exit. */ + +! if (v->lifetime * threshold * benefit < insn_count +! && ! bl->reversed) + { + if (loop_dump_stream) +--- 3822,3827 ---- + exit. */ + +! if ( ! flag_reduce_all_givs && v->lifetime * threshold * benefit < insn_count +! && ! bl->reversed ) + { + if (loop_dump_stream) +*************** record_giv (v, insn, src_reg, dest_reg, +*** 4375,4378 **** +--- 4376,4381 ---- + v->final_value = 0; + v->same_insn = 0; ++ v->unrolled = 0; ++ v->shared = 0; + + /* The v->always_computable field is used in update_giv_derive, to +*************** check_final_value (v, loop_start, loop_e +*** 4652,4657 **** + if (GET_CODE (p) == JUMP_INSN && JUMP_LABEL (p) + && LABEL_NAME (JUMP_LABEL (p)) +! && ((INSN_LUID (JUMP_LABEL (p)) < INSN_LUID (v->insn) +! && INSN_LUID (JUMP_LABEL (p)) > INSN_LUID (loop_start)) + || (INSN_LUID (JUMP_LABEL (p)) > INSN_LUID (last_giv_use) + && INSN_LUID (JUMP_LABEL (p)) < INSN_LUID (loop_end)))) +--- 4655,4663 ---- + if (GET_CODE (p) == JUMP_INSN && JUMP_LABEL (p) + && LABEL_NAME (JUMP_LABEL (p)) +! && ((INSN_UID (JUMP_LABEL (p)) >= max_uid_for_loop) +! || (INSN_UID (v->insn) >= max_uid_for_loop) +! || (INSN_UID (last_giv_use) >= max_uid_for_loop) +! || (INSN_LUID (JUMP_LABEL (p)) < INSN_LUID (v->insn) +! && INSN_LUID (JUMP_LABEL (p)) > INSN_LUID (loop_start)) + || (INSN_LUID (JUMP_LABEL (p)) > INSN_LUID (last_giv_use) + && INSN_LUID (JUMP_LABEL (p)) < INSN_LUID (loop_end)))) +*************** emit_iv_add_mult (b, m, a, reg, insert_b +*** 5560,5563 **** +--- 5566,5571 ---- + + emit_insn_before (seq, insert_before); ++ ++ record_base_value (REGNO (reg), b); + } + +diff -rcp2N gcc-2.7.2.2/loop.h gcc-2.7.2.2.f.2/loop.h +*** gcc-2.7.2.2/loop.h Fri Jul 14 08:23:28 1995 +--- gcc-2.7.2.2.f.2/loop.h Fri Jan 10 23:18:23 1997 +*************** struct induction +*** 89,92 **** +--- 89,95 ---- + we won't use it to eliminate a biv, it + would probably lose. */ ++ unsigned unrolled : 1; /* 1 if new register has been allocated in ++ unrolled loop. */ ++ unsigned shared : 1; + int lifetime; /* Length of life of this giv */ + int times_used; /* # times this giv is used. */ +diff -rcp2N gcc-2.7.2.2/real.c gcc-2.7.2.2.f.2/real.c +*** gcc-2.7.2.2/real.c Tue Aug 15 17:57:18 1995 +--- gcc-2.7.2.2.f.2/real.c Thu Dec 19 12:31:09 1996 +*************** make_nan (nan, sign, mode) +*** 5625,5633 **** + } + +! /* Convert an SFmode target `float' value to a REAL_VALUE_TYPE. +! This is the inverse of the function `etarsingle' invoked by + REAL_VALUE_TO_TARGET_SINGLE. */ + + REAL_VALUE_TYPE + ereal_from_float (f) + HOST_WIDE_INT f; +--- 5625,5699 ---- + } + +! /* This is the inverse of the function `etarsingle' invoked by + REAL_VALUE_TO_TARGET_SINGLE. */ + + REAL_VALUE_TYPE ++ ereal_unto_float (f) ++ long f; ++ { ++ REAL_VALUE_TYPE r; ++ unsigned EMUSHORT s[2]; ++ unsigned EMUSHORT e[NE]; ++ ++ /* Convert 32 bit integer to array of 16 bit pieces in target machine order. ++ This is the inverse operation to what the function `endian' does. */ ++ if (REAL_WORDS_BIG_ENDIAN) ++ { ++ s[0] = (unsigned EMUSHORT) (f >> 16); ++ s[1] = (unsigned EMUSHORT) f; ++ } ++ else ++ { ++ s[0] = (unsigned EMUSHORT) f; ++ s[1] = (unsigned EMUSHORT) (f >> 16); ++ } ++ /* Convert and promote the target float to E-type. */ ++ e24toe (s, e); ++ /* Output E-type to REAL_VALUE_TYPE. */ ++ PUT_REAL (e, &r); ++ return r; ++ } ++ ++ ++ /* This is the inverse of the function `etardouble' invoked by ++ REAL_VALUE_TO_TARGET_DOUBLE. */ ++ ++ REAL_VALUE_TYPE ++ ereal_unto_double (d) ++ long d[]; ++ { ++ REAL_VALUE_TYPE r; ++ unsigned EMUSHORT s[4]; ++ unsigned EMUSHORT e[NE]; ++ ++ /* Convert array of HOST_WIDE_INT to equivalent array of 16-bit pieces. */ ++ if (REAL_WORDS_BIG_ENDIAN) ++ { ++ s[0] = (unsigned EMUSHORT) (d[0] >> 16); ++ s[1] = (unsigned EMUSHORT) d[0]; ++ s[2] = (unsigned EMUSHORT) (d[1] >> 16); ++ s[3] = (unsigned EMUSHORT) d[1]; ++ } ++ else ++ { ++ /* Target float words are little-endian. */ ++ s[0] = (unsigned EMUSHORT) d[0]; ++ s[1] = (unsigned EMUSHORT) (d[0] >> 16); ++ s[2] = (unsigned EMUSHORT) d[1]; ++ s[3] = (unsigned EMUSHORT) (d[1] >> 16); ++ } ++ /* Convert target double to E-type. */ ++ e53toe (s, e); ++ /* Output E-type to REAL_VALUE_TYPE. */ ++ PUT_REAL (e, &r); ++ return r; ++ } ++ ++ ++ /* Convert an SFmode target `float' value to a REAL_VALUE_TYPE. ++ This is somewhat like ereal_unto_float, but the input types ++ for these are different. */ ++ ++ REAL_VALUE_TYPE + ereal_from_float (f) + HOST_WIDE_INT f; +*************** ereal_from_float (f) +*** 5658,5663 **** + + /* Convert a DFmode target `double' value to a REAL_VALUE_TYPE. +! This is the inverse of the function `etardouble' invoked by +! REAL_VALUE_TO_TARGET_DOUBLE. + + The DFmode is stored as an array of HOST_WIDE_INT in the target's +--- 5724,5729 ---- + + /* Convert a DFmode target `double' value to a REAL_VALUE_TYPE. +! This is somewhat like ereal_unto_double, but the input types +! for these are different. + + The DFmode is stored as an array of HOST_WIDE_INT in the target's +diff -rcp2N gcc-2.7.2.2/real.h gcc-2.7.2.2.f.2/real.h +*** gcc-2.7.2.2/real.h Thu Jun 15 07:57:56 1995 +--- gcc-2.7.2.2.f.2/real.h Thu Dec 19 12:31:09 1996 +*************** extern void ereal_to_decimal PROTO((REAL +*** 152,155 **** +--- 152,157 ---- + extern int ereal_cmp PROTO((REAL_VALUE_TYPE, REAL_VALUE_TYPE)); + extern int ereal_isneg PROTO((REAL_VALUE_TYPE)); ++ extern REAL_VALUE_TYPE ereal_unto_float PROTO((long)); ++ extern REAL_VALUE_TYPE ereal_unto_double PROTO((long *)); + extern REAL_VALUE_TYPE ereal_from_float PROTO((HOST_WIDE_INT)); + extern REAL_VALUE_TYPE ereal_from_double PROTO((HOST_WIDE_INT *)); +*************** extern REAL_VALUE_TYPE real_value_trunca +*** 197,200 **** +--- 199,208 ---- + /* IN is a REAL_VALUE_TYPE. OUT is a long. */ + #define REAL_VALUE_TO_TARGET_SINGLE(IN, OUT) ((OUT) = etarsingle ((IN))) ++ ++ /* Inverse of REAL_VALUE_TO_TARGET_DOUBLE. */ ++ #define REAL_VALUE_UNTO_TARGET_DOUBLE(d) (ereal_unto_double (d)) ++ ++ /* Inverse of REAL_VALUE_TO_TARGET_SINGLE. */ ++ #define REAL_VALUE_UNTO_TARGET_SINGLE(f) (ereal_unto_float (f)) + + /* d is an array of HOST_WIDE_INT that holds a double precision +diff -rcp2N gcc-2.7.2.2/reload.c gcc-2.7.2.2.f.2/reload.c +*** gcc-2.7.2.2/reload.c Sat Nov 11 08:23:54 1995 +--- gcc-2.7.2.2.f.2/reload.c Thu Feb 27 23:03:05 1997 +*************** +*** 1,4 **** + /* Search an insn for pseudo regs that must be in hard regs and are not. +! Copyright (C) 1987, 88, 89, 92, 93, 94, 1995 Free Software Foundation, Inc. + + This file is part of GNU CC. +--- 1,4 ---- + /* Search an insn for pseudo regs that must be in hard regs and are not. +! Copyright (C) 1987, 88, 89, 92-5, 1996 Free Software Foundation, Inc. + + This file is part of GNU CC. +*************** static int push_secondary_reload PROTO(( +*** 292,295 **** +--- 292,296 ---- + enum machine_mode, enum reload_type, + enum insn_code *)); ++ static enum reg_class find_valid_class PROTO((enum machine_mode, int)); + static int push_reload PROTO((rtx, rtx, rtx *, rtx *, enum reg_class, + enum machine_mode, enum machine_mode, +*************** push_secondary_reload (in_p, x, opnum, o +*** 361,364 **** +--- 362,368 ---- + mode and object being reloaded. */ + if (GET_CODE (x) == SUBREG ++ #ifdef CLASS_CANNOT_CHANGE_SIZE ++ && reload_class != CLASS_CANNOT_CHANGE_SIZE ++ #endif + && (GET_MODE_SIZE (GET_MODE (x)) + > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))) +*************** clear_secondary_mem () +*** 689,692 **** +--- 693,728 ---- + #endif /* SECONDARY_MEMORY_NEEDED */ + ++ /* Find the largest class for which every register number plus N is valid in ++ M1 (if in range). Abort if no such class exists. */ ++ ++ static enum reg_class ++ find_valid_class (m1, n) ++ enum machine_mode m1; ++ int n; ++ { ++ int class; ++ int regno; ++ enum reg_class best_class; ++ int best_size = 0; ++ ++ for (class = 1; class < N_REG_CLASSES; class++) ++ { ++ int bad = 0; ++ for (regno = 0; regno < FIRST_PSEUDO_REGISTER && ! bad; regno++) ++ if (TEST_HARD_REG_BIT (reg_class_contents[class], regno) ++ && TEST_HARD_REG_BIT (reg_class_contents[class], regno + n) ++ && ! HARD_REGNO_MODE_OK (regno + n, m1)) ++ bad = 1; ++ ++ if (! bad && reg_class_size[class] > best_size) ++ best_class = class, best_size = reg_class_size[class]; ++ } ++ ++ if (best_size == 0) ++ abort (); ++ ++ return best_class; ++ } ++ + /* Record one reload that needs to be performed. + IN is an rtx saying where the data are to be found before this instruction. +*************** push_reload (in, out, inloc, outloc, cla +*** 894,898 **** + && GET_CODE (SUBREG_REG (in)) == REG + && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER +! && (! HARD_REGNO_MODE_OK (REGNO (SUBREG_REG (in)), inmode) + || (GET_MODE_SIZE (inmode) <= UNITS_PER_WORD + && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))) +--- 930,935 ---- + && GET_CODE (SUBREG_REG (in)) == REG + && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER +! && (! HARD_REGNO_MODE_OK (REGNO (SUBREG_REG (in)) + SUBREG_WORD (in), +! inmode) + || (GET_MODE_SIZE (inmode) <= UNITS_PER_WORD + && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))) +*************** push_reload (in, out, inloc, outloc, cla +*** 909,913 **** + output before the outer reload. */ + push_reload (SUBREG_REG (in), NULL_RTX, &SUBREG_REG (in), NULL_PTR, +! GENERAL_REGS, VOIDmode, VOIDmode, 0, 0, opnum, type); + dont_remove_subreg = 1; + } +--- 946,951 ---- + output before the outer reload. */ + push_reload (SUBREG_REG (in), NULL_RTX, &SUBREG_REG (in), NULL_PTR, +! find_valid_class (inmode, SUBREG_WORD (in)), +! VOIDmode, VOIDmode, 0, 0, opnum, type); + dont_remove_subreg = 1; + } +*************** push_reload (in, out, inloc, outloc, cla +*** 982,986 **** + && GET_CODE (SUBREG_REG (out)) == REG + && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER +! && (! HARD_REGNO_MODE_OK (REGNO (SUBREG_REG (out)), outmode) + || (GET_MODE_SIZE (outmode) <= UNITS_PER_WORD + && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))) +--- 1020,1025 ---- + && GET_CODE (SUBREG_REG (out)) == REG + && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER +! && (! HARD_REGNO_MODE_OK (REGNO (SUBREG_REG (out)) + SUBREG_WORD (out), +! outmode) + || (GET_MODE_SIZE (outmode) <= UNITS_PER_WORD + && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))) +*************** push_reload (in, out, inloc, outloc, cla +*** 998,1002 **** + dont_remove_subreg = 1; + push_reload (SUBREG_REG (out), SUBREG_REG (out), &SUBREG_REG (out), +! &SUBREG_REG (out), ALL_REGS, VOIDmode, VOIDmode, 0, 0, + opnum, RELOAD_OTHER); + } +--- 1037,1043 ---- + dont_remove_subreg = 1; + push_reload (SUBREG_REG (out), SUBREG_REG (out), &SUBREG_REG (out), +! &SUBREG_REG (out), +! find_valid_class (outmode, SUBREG_WORD (out)), +! VOIDmode, VOIDmode, 0, 0, + opnum, RELOAD_OTHER); + } +*************** find_equiv_reg (goal, insn, class, other +*** 5518,5522 **** + and is also a register that appears in the address of GOAL. */ + +! if (goal_mem && value == SET_DEST (PATTERN (where)) + && refers_to_regno_for_reload_p (valueno, + (valueno +--- 5559,5563 ---- + and is also a register that appears in the address of GOAL. */ + +! if (goal_mem && value == SET_DEST (single_set (where)) + && refers_to_regno_for_reload_p (valueno, + (valueno +*************** debug_reload() +*** 5900,5904 **** + + if (reload_nocombine[r]) +! fprintf (stderr, ", can combine", reload_nocombine[r]); + + if (reload_secondary_p[r]) +--- 5941,5945 ---- + + if (reload_nocombine[r]) +! fprintf (stderr, ", can't combine %d", reload_nocombine[r]); + + if (reload_secondary_p[r]) +diff -rcp2N gcc-2.7.2.2/rtl.h gcc-2.7.2.2.f.2/rtl.h +*** gcc-2.7.2.2/rtl.h Thu Jun 15 08:03:16 1995 +--- gcc-2.7.2.2.f.2/rtl.h Fri Jan 10 23:18:23 1997 +*************** enum reg_note { REG_DEAD = 1, REG_INC = +*** 349,353 **** + REG_NONNEG = 8, REG_NO_CONFLICT = 9, REG_UNUSED = 10, + REG_CC_SETTER = 11, REG_CC_USER = 12, REG_LABEL = 13, +! REG_DEP_ANTI = 14, REG_DEP_OUTPUT = 15 }; + + /* Define macros to extract and insert the reg-note kind in an EXPR_LIST. */ +--- 349,353 ---- + REG_NONNEG = 8, REG_NO_CONFLICT = 9, REG_UNUSED = 10, + REG_CC_SETTER = 11, REG_CC_USER = 12, REG_LABEL = 13, +! REG_DEP_ANTI = 14, REG_DEP_OUTPUT = 15, REG_NOALIAS = 16 }; + + /* Define macros to extract and insert the reg-note kind in an EXPR_LIST. */ +*************** extern char *reg_note_name[]; +*** 432,436 **** + #define NOTE_INSN_FUNCTION_BEG -13 + +- + #if 0 /* These are not used, and I don't know what they were for. --rms. */ + #define NOTE_DECL_NAME(INSN) ((INSN)->fld[3].rtstr) +--- 432,435 ---- +*************** extern char *note_insn_name[]; +*** 576,579 **** +--- 575,579 ---- + /* For a TRAP_IF rtx, TRAP_CONDITION is an expression. */ + #define TRAP_CONDITION(RTX) ((RTX)->fld[0].rtx) ++ #define TRAP_CODE(RTX) ((RTX)->fld[1].rtint) + + /* 1 in a SYMBOL_REF if it addresses this function's constants pool. */ +*************** extern rtx eliminate_constant_term PROTO +*** 817,820 **** +--- 817,830 ---- + extern rtx expand_complex_abs PROTO((enum machine_mode, rtx, rtx, int)); + extern enum machine_mode choose_hard_reg_mode PROTO((int, int)); ++ extern int rtx_varies_p PROTO((rtx)); ++ extern int may_trap_p PROTO((rtx)); ++ extern int side_effects_p PROTO((rtx)); ++ extern int volatile_refs_p PROTO((rtx)); ++ extern int volatile_insn_p PROTO((rtx)); ++ extern void remove_note PROTO((rtx, rtx)); ++ extern void note_stores PROTO((rtx, void (*)())); ++ extern int refers_to_regno_p PROTO((int, int, rtx, rtx *)); ++ extern int reg_overlap_mentioned_p PROTO((rtx, rtx)); ++ + + /* Maximum number of parallel sets and clobbers in any insn in this fn. +*************** extern rtx *regno_reg_rtx; +*** 967,968 **** +--- 977,985 ---- + + extern int rtx_to_tree_code PROTO((enum rtx_code)); ++ ++ extern int true_dependence PROTO((rtx, enum machine_mode, rtx, int (*)())); ++ extern int read_dependence PROTO((rtx, rtx)); ++ extern int anti_dependence PROTO((rtx, rtx)); ++ extern int output_dependence PROTO((rtx, rtx)); ++ extern void init_alias_analysis PROTO((void)); ++ extern void end_alias_analysis PROTO((void)); +diff -rcp2N gcc-2.7.2.2/sched.c gcc-2.7.2.2.f.2/sched.c +*** gcc-2.7.2.2/sched.c Thu Jun 15 08:06:39 1995 +--- gcc-2.7.2.2.f.2/sched.c Fri Jan 10 23:18:24 1997 +*************** Boston, MA 02111-1307, USA. */ +*** 126,129 **** +--- 126,132 ---- + #include "insn-attr.h" + ++ extern char *reg_known_equiv_p; ++ extern rtx *reg_known_value; ++ + #ifdef INSN_SCHEDULING + /* Arrays set up by scheduling for the same respective purposes as +*************** static int *sched_reg_live_length; +*** 143,146 **** +--- 146,150 ---- + by splitting insns. */ + static rtx *reg_last_uses; ++ static int reg_last_uses_size; + static rtx *reg_last_sets; + static regset reg_pending_sets; +*************** struct sometimes +*** 294,302 **** + + /* Forward declarations. */ +- static rtx canon_rtx PROTO((rtx)); +- static int rtx_equal_for_memref_p PROTO((rtx, rtx)); +- static rtx find_symbolic_term PROTO((rtx)); +- static int memrefs_conflict_p PROTO((int, rtx, int, rtx, +- HOST_WIDE_INT)); + static void add_dependence PROTO((rtx, rtx, enum reg_note)); + static void remove_dependence PROTO((rtx, rtx)); +--- 298,301 ---- +*************** void schedule_insns PROTO((FILE *)); +*** 346,885 **** + #endif /* INSN_SCHEDULING */ + +- #define SIZE_FOR_MODE(X) (GET_MODE_SIZE (GET_MODE (X))) +- +- /* Vector indexed by N giving the initial (unchanging) value known +- for pseudo-register N. */ +- static rtx *reg_known_value; +- +- /* Vector recording for each reg_known_value whether it is due to a +- REG_EQUIV note. Future passes (viz., reload) may replace the +- pseudo with the equivalent expression and so we account for the +- dependences that would be introduced if that happens. */ +- /* ??? This is a problem only on the Convex. The REG_EQUIV notes created in +- assign_parms mention the arg pointer, and there are explicit insns in the +- RTL that modify the arg pointer. Thus we must ensure that such insns don't +- get scheduled across each other because that would invalidate the REG_EQUIV +- notes. One could argue that the REG_EQUIV notes are wrong, but solving +- the problem in the scheduler will likely give better code, so we do it +- here. */ +- static char *reg_known_equiv_p; +- +- /* Indicates number of valid entries in reg_known_value. */ +- static int reg_known_value_size; +- +- static rtx +- canon_rtx (x) +- rtx x; +- { +- if (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER +- && REGNO (x) <= reg_known_value_size) +- return reg_known_value[REGNO (x)]; +- else if (GET_CODE (x) == PLUS) +- { +- rtx x0 = canon_rtx (XEXP (x, 0)); +- rtx x1 = canon_rtx (XEXP (x, 1)); +- +- if (x0 != XEXP (x, 0) || x1 != XEXP (x, 1)) +- { +- /* We can tolerate LO_SUMs being offset here; these +- rtl are used for nothing other than comparisons. */ +- if (GET_CODE (x0) == CONST_INT) +- return plus_constant_for_output (x1, INTVAL (x0)); +- else if (GET_CODE (x1) == CONST_INT) +- return plus_constant_for_output (x0, INTVAL (x1)); +- return gen_rtx (PLUS, GET_MODE (x), x0, x1); +- } +- } +- return x; +- } +- +- /* Set up all info needed to perform alias analysis on memory references. */ +- +- void +- init_alias_analysis () +- { +- int maxreg = max_reg_num (); +- rtx insn; +- rtx note; +- rtx set; +- +- reg_known_value_size = maxreg; +- +- reg_known_value +- = (rtx *) oballoc ((maxreg-FIRST_PSEUDO_REGISTER) * sizeof (rtx)) +- - FIRST_PSEUDO_REGISTER; +- bzero ((char *) (reg_known_value + FIRST_PSEUDO_REGISTER), +- (maxreg-FIRST_PSEUDO_REGISTER) * sizeof (rtx)); +- +- reg_known_equiv_p +- = (char *) oballoc ((maxreg -FIRST_PSEUDO_REGISTER) * sizeof (char)) +- - FIRST_PSEUDO_REGISTER; +- bzero (reg_known_equiv_p + FIRST_PSEUDO_REGISTER, +- (maxreg - FIRST_PSEUDO_REGISTER) * sizeof (char)); +- +- /* Fill in the entries with known constant values. */ +- for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) +- if ((set = single_set (insn)) != 0 +- && GET_CODE (SET_DEST (set)) == REG +- && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER +- && (((note = find_reg_note (insn, REG_EQUAL, 0)) != 0 +- && reg_n_sets[REGNO (SET_DEST (set))] == 1) +- || (note = find_reg_note (insn, REG_EQUIV, NULL_RTX)) != 0) +- && GET_CODE (XEXP (note, 0)) != EXPR_LIST) +- { +- int regno = REGNO (SET_DEST (set)); +- reg_known_value[regno] = XEXP (note, 0); +- reg_known_equiv_p[regno] = REG_NOTE_KIND (note) == REG_EQUIV; +- } +- +- /* Fill in the remaining entries. */ +- while (--maxreg >= FIRST_PSEUDO_REGISTER) +- if (reg_known_value[maxreg] == 0) +- reg_known_value[maxreg] = regno_reg_rtx[maxreg]; +- } +- +- /* Return 1 if X and Y are identical-looking rtx's. +- +- We use the data in reg_known_value above to see if two registers with +- different numbers are, in fact, equivalent. */ +- +- static int +- rtx_equal_for_memref_p (x, y) +- rtx x, y; +- { +- register int i; +- register int j; +- register enum rtx_code code; +- register char *fmt; +- +- if (x == 0 && y == 0) +- return 1; +- if (x == 0 || y == 0) +- return 0; +- x = canon_rtx (x); +- y = canon_rtx (y); +- +- if (x == y) +- return 1; +- +- code = GET_CODE (x); +- /* Rtx's of different codes cannot be equal. */ +- if (code != GET_CODE (y)) +- return 0; +- +- /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent. +- (REG:SI x) and (REG:HI x) are NOT equivalent. */ +- +- if (GET_MODE (x) != GET_MODE (y)) +- return 0; +- +- /* REG, LABEL_REF, and SYMBOL_REF can be compared nonrecursively. */ +- +- if (code == REG) +- return REGNO (x) == REGNO (y); +- if (code == LABEL_REF) +- return XEXP (x, 0) == XEXP (y, 0); +- if (code == SYMBOL_REF) +- return XSTR (x, 0) == XSTR (y, 0); +- +- /* For commutative operations, the RTX match if the operand match in any +- order. Also handle the simple binary and unary cases without a loop. */ +- if (code == EQ || code == NE || GET_RTX_CLASS (code) == 'c') +- return ((rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 0)) +- && rtx_equal_for_memref_p (XEXP (x, 1), XEXP (y, 1))) +- || (rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 1)) +- && rtx_equal_for_memref_p (XEXP (x, 1), XEXP (y, 0)))); +- else if (GET_RTX_CLASS (code) == '<' || GET_RTX_CLASS (code) == '2') +- return (rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 0)) +- && rtx_equal_for_memref_p (XEXP (x, 1), XEXP (y, 1))); +- else if (GET_RTX_CLASS (code) == '1') +- return rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 0)); +- +- /* Compare the elements. If any pair of corresponding elements +- fail to match, return 0 for the whole things. */ +- +- fmt = GET_RTX_FORMAT (code); +- for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) +- { +- switch (fmt[i]) +- { +- case 'w': +- if (XWINT (x, i) != XWINT (y, i)) +- return 0; +- break; +- +- case 'n': +- case 'i': +- if (XINT (x, i) != XINT (y, i)) +- return 0; +- break; +- +- case 'V': +- case 'E': +- /* Two vectors must have the same length. */ +- if (XVECLEN (x, i) != XVECLEN (y, i)) +- return 0; +- +- /* And the corresponding elements must match. */ +- for (j = 0; j < XVECLEN (x, i); j++) +- if (rtx_equal_for_memref_p (XVECEXP (x, i, j), XVECEXP (y, i, j)) == 0) +- return 0; +- break; +- +- case 'e': +- if (rtx_equal_for_memref_p (XEXP (x, i), XEXP (y, i)) == 0) +- return 0; +- break; +- +- case 'S': +- case 's': +- if (strcmp (XSTR (x, i), XSTR (y, i))) +- return 0; +- break; +- +- case 'u': +- /* These are just backpointers, so they don't matter. */ +- break; +- +- case '0': +- break; +- +- /* It is believed that rtx's at this level will never +- contain anything but integers and other rtx's, +- except for within LABEL_REFs and SYMBOL_REFs. */ +- default: +- abort (); +- } +- } +- return 1; +- } +- +- /* Given an rtx X, find a SYMBOL_REF or LABEL_REF within +- X and return it, or return 0 if none found. */ +- +- static rtx +- find_symbolic_term (x) +- rtx x; +- { +- register int i; +- register enum rtx_code code; +- register char *fmt; +- +- code = GET_CODE (x); +- if (code == SYMBOL_REF || code == LABEL_REF) +- return x; +- if (GET_RTX_CLASS (code) == 'o') +- return 0; +- +- fmt = GET_RTX_FORMAT (code); +- for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) +- { +- rtx t; +- +- if (fmt[i] == 'e') +- { +- t = find_symbolic_term (XEXP (x, i)); +- if (t != 0) +- return t; +- } +- else if (fmt[i] == 'E') +- break; +- } +- return 0; +- } +- +- /* Return nonzero if X and Y (memory addresses) could reference the +- same location in memory. C is an offset accumulator. When +- C is nonzero, we are testing aliases between X and Y + C. +- XSIZE is the size in bytes of the X reference, +- similarly YSIZE is the size in bytes for Y. +- +- If XSIZE or YSIZE is zero, we do not know the amount of memory being +- referenced (the reference was BLKmode), so make the most pessimistic +- assumptions. +- +- We recognize the following cases of non-conflicting memory: +- +- (1) addresses involving the frame pointer cannot conflict +- with addresses involving static variables. +- (2) static variables with different addresses cannot conflict. +- +- Nice to notice that varying addresses cannot conflict with fp if no +- local variables had their addresses taken, but that's too hard now. */ +- +- /* ??? In Fortran, references to a array parameter can never conflict with +- another array parameter. */ +- +- static int +- memrefs_conflict_p (xsize, x, ysize, y, c) +- rtx x, y; +- int xsize, ysize; +- HOST_WIDE_INT c; +- { +- if (GET_CODE (x) == HIGH) +- x = XEXP (x, 0); +- else if (GET_CODE (x) == LO_SUM) +- x = XEXP (x, 1); +- else +- x = canon_rtx (x); +- if (GET_CODE (y) == HIGH) +- y = XEXP (y, 0); +- else if (GET_CODE (y) == LO_SUM) +- y = XEXP (y, 1); +- else +- y = canon_rtx (y); +- +- if (rtx_equal_for_memref_p (x, y)) +- return (xsize == 0 || ysize == 0 || +- (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0)); +- +- if (y == frame_pointer_rtx || y == hard_frame_pointer_rtx +- || y == stack_pointer_rtx) +- { +- rtx t = y; +- int tsize = ysize; +- y = x; ysize = xsize; +- x = t; xsize = tsize; +- } +- +- if (x == frame_pointer_rtx || x == hard_frame_pointer_rtx +- || x == stack_pointer_rtx) +- { +- rtx y1; +- +- if (CONSTANT_P (y)) +- return 0; +- +- if (GET_CODE (y) == PLUS +- && canon_rtx (XEXP (y, 0)) == x +- && (y1 = canon_rtx (XEXP (y, 1))) +- && GET_CODE (y1) == CONST_INT) +- { +- c += INTVAL (y1); +- return (xsize == 0 || ysize == 0 +- || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0)); +- } +- +- if (GET_CODE (y) == PLUS +- && (y1 = canon_rtx (XEXP (y, 0))) +- && CONSTANT_P (y1)) +- return 0; +- +- return 1; +- } +- +- if (GET_CODE (x) == PLUS) +- { +- /* The fact that X is canonicalized means that this +- PLUS rtx is canonicalized. */ +- rtx x0 = XEXP (x, 0); +- rtx x1 = XEXP (x, 1); +- +- if (GET_CODE (y) == PLUS) +- { +- /* The fact that Y is canonicalized means that this +- PLUS rtx is canonicalized. */ +- rtx y0 = XEXP (y, 0); +- rtx y1 = XEXP (y, 1); +- +- if (rtx_equal_for_memref_p (x1, y1)) +- return memrefs_conflict_p (xsize, x0, ysize, y0, c); +- if (rtx_equal_for_memref_p (x0, y0)) +- return memrefs_conflict_p (xsize, x1, ysize, y1, c); +- if (GET_CODE (x1) == CONST_INT) +- if (GET_CODE (y1) == CONST_INT) +- return memrefs_conflict_p (xsize, x0, ysize, y0, +- c - INTVAL (x1) + INTVAL (y1)); +- else +- return memrefs_conflict_p (xsize, x0, ysize, y, c - INTVAL (x1)); +- else if (GET_CODE (y1) == CONST_INT) +- return memrefs_conflict_p (xsize, x, ysize, y0, c + INTVAL (y1)); +- +- /* Handle case where we cannot understand iteration operators, +- but we notice that the base addresses are distinct objects. */ +- x = find_symbolic_term (x); +- if (x == 0) +- return 1; +- y = find_symbolic_term (y); +- if (y == 0) +- return 1; +- return rtx_equal_for_memref_p (x, y); +- } +- else if (GET_CODE (x1) == CONST_INT) +- return memrefs_conflict_p (xsize, x0, ysize, y, c - INTVAL (x1)); +- } +- else if (GET_CODE (y) == PLUS) +- { +- /* The fact that Y is canonicalized means that this +- PLUS rtx is canonicalized. */ +- rtx y0 = XEXP (y, 0); +- rtx y1 = XEXP (y, 1); +- +- if (GET_CODE (y1) == CONST_INT) +- return memrefs_conflict_p (xsize, x, ysize, y0, c + INTVAL (y1)); +- else +- return 1; +- } +- +- if (GET_CODE (x) == GET_CODE (y)) +- switch (GET_CODE (x)) +- { +- case MULT: +- { +- /* Handle cases where we expect the second operands to be the +- same, and check only whether the first operand would conflict +- or not. */ +- rtx x0, y0; +- rtx x1 = canon_rtx (XEXP (x, 1)); +- rtx y1 = canon_rtx (XEXP (y, 1)); +- if (! rtx_equal_for_memref_p (x1, y1)) +- return 1; +- x0 = canon_rtx (XEXP (x, 0)); +- y0 = canon_rtx (XEXP (y, 0)); +- if (rtx_equal_for_memref_p (x0, y0)) +- return (xsize == 0 || ysize == 0 +- || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0)); +- +- /* Can't properly adjust our sizes. */ +- if (GET_CODE (x1) != CONST_INT) +- return 1; +- xsize /= INTVAL (x1); +- ysize /= INTVAL (x1); +- c /= INTVAL (x1); +- return memrefs_conflict_p (xsize, x0, ysize, y0, c); +- } +- } +- +- if (CONSTANT_P (x)) +- { +- if (GET_CODE (x) == CONST_INT && GET_CODE (y) == CONST_INT) +- { +- c += (INTVAL (y) - INTVAL (x)); +- return (xsize == 0 || ysize == 0 +- || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0)); +- } +- +- if (GET_CODE (x) == CONST) +- { +- if (GET_CODE (y) == CONST) +- return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)), +- ysize, canon_rtx (XEXP (y, 0)), c); +- else +- return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)), +- ysize, y, c); +- } +- if (GET_CODE (y) == CONST) +- return memrefs_conflict_p (xsize, x, ysize, +- canon_rtx (XEXP (y, 0)), c); +- +- if (CONSTANT_P (y)) +- return (rtx_equal_for_memref_p (x, y) +- && (xsize == 0 || ysize == 0 +- || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0))); +- +- return 1; +- } +- return 1; +- } +- +- /* Functions to compute memory dependencies. +- +- Since we process the insns in execution order, we can build tables +- to keep track of what registers are fixed (and not aliased), what registers +- are varying in known ways, and what registers are varying in unknown +- ways. +- +- If both memory references are volatile, then there must always be a +- dependence between the two references, since their order can not be +- changed. A volatile and non-volatile reference can be interchanged +- though. +- +- A MEM_IN_STRUCT reference at a non-QImode varying address can never +- conflict with a non-MEM_IN_STRUCT reference at a fixed address. We must +- allow QImode aliasing because the ANSI C standard allows character +- pointers to alias anything. We are assuming that characters are +- always QImode here. */ +- +- /* Read dependence: X is read after read in MEM takes place. There can +- only be a dependence here if both reads are volatile. */ +- +- int +- read_dependence (mem, x) +- rtx mem; +- rtx x; +- { +- return MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem); +- } +- +- /* True dependence: X is read after store in MEM takes place. */ +- +- int +- true_dependence (mem, x) +- rtx mem; +- rtx x; +- { +- /* If X is an unchanging read, then it can't possibly conflict with any +- non-unchanging store. It may conflict with an unchanging write though, +- because there may be a single store to this address to initialize it. +- Just fall through to the code below to resolve the case where we have +- both an unchanging read and an unchanging write. This won't handle all +- cases optimally, but the possible performance loss should be +- negligible. */ +- if (RTX_UNCHANGING_P (x) && ! RTX_UNCHANGING_P (mem)) +- return 0; +- +- return ((MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem)) +- || (memrefs_conflict_p (SIZE_FOR_MODE (mem), XEXP (mem, 0), +- SIZE_FOR_MODE (x), XEXP (x, 0), 0) +- && ! (MEM_IN_STRUCT_P (mem) && rtx_addr_varies_p (mem) +- && GET_MODE (mem) != QImode +- && ! MEM_IN_STRUCT_P (x) && ! rtx_addr_varies_p (x)) +- && ! (MEM_IN_STRUCT_P (x) && rtx_addr_varies_p (x) +- && GET_MODE (x) != QImode +- && ! MEM_IN_STRUCT_P (mem) && ! rtx_addr_varies_p (mem)))); +- } +- +- /* Anti dependence: X is written after read in MEM takes place. */ +- +- int +- anti_dependence (mem, x) +- rtx mem; +- rtx x; +- { +- /* If MEM is an unchanging read, then it can't possibly conflict with +- the store to X, because there is at most one store to MEM, and it must +- have occurred somewhere before MEM. */ +- if (RTX_UNCHANGING_P (mem)) +- return 0; +- +- return ((MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem)) +- || (memrefs_conflict_p (SIZE_FOR_MODE (mem), XEXP (mem, 0), +- SIZE_FOR_MODE (x), XEXP (x, 0), 0) +- && ! (MEM_IN_STRUCT_P (mem) && rtx_addr_varies_p (mem) +- && GET_MODE (mem) != QImode +- && ! MEM_IN_STRUCT_P (x) && ! rtx_addr_varies_p (x)) +- && ! (MEM_IN_STRUCT_P (x) && rtx_addr_varies_p (x) +- && GET_MODE (x) != QImode +- && ! MEM_IN_STRUCT_P (mem) && ! rtx_addr_varies_p (mem)))); +- } +- +- /* Output dependence: X is written after store in MEM takes place. */ +- +- int +- output_dependence (mem, x) +- rtx mem; +- rtx x; +- { +- return ((MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem)) +- || (memrefs_conflict_p (SIZE_FOR_MODE (mem), XEXP (mem, 0), +- SIZE_FOR_MODE (x), XEXP (x, 0), 0) +- && ! (MEM_IN_STRUCT_P (mem) && rtx_addr_varies_p (mem) +- && GET_MODE (mem) != QImode +- && ! MEM_IN_STRUCT_P (x) && ! rtx_addr_varies_p (x)) +- && ! (MEM_IN_STRUCT_P (x) && rtx_addr_varies_p (x) +- && GET_MODE (x) != QImode +- && ! MEM_IN_STRUCT_P (mem) && ! rtx_addr_varies_p (mem)))); +- } +- + /* Helper functions for instruction scheduling. */ + +--- 345,348 ---- +*************** sched_analyze_2 (x, insn) +*** 1922,1926 **** + /* If a dependency already exists, don't create a new one. */ + if (! find_insn_list (XEXP (pending, 0), LOG_LINKS (insn))) +! if (true_dependence (XEXP (pending_mem, 0), x)) + add_dependence (insn, XEXP (pending, 0), 0); + +--- 1385,1390 ---- + /* If a dependency already exists, don't create a new one. */ + if (! find_insn_list (XEXP (pending, 0), LOG_LINKS (insn))) +! if (true_dependence (XEXP (pending_mem, 0), VOIDmode, +! x, rtx_varies_p)) + add_dependence (insn, XEXP (pending, 0), 0); + +*************** sched_analyze_insn (x, insn, loop_notes) +*** 2021,2025 **** + register RTX_CODE code = GET_CODE (x); + rtx link; +! int maxreg = max_reg_num (); + int i; + +--- 1485,1489 ---- + register RTX_CODE code = GET_CODE (x); + rtx link; +! int maxreg = reg_last_uses_size; + int i; + +*************** sched_analyze_insn (x, insn, loop_notes) +*** 2058,2062 **** + if (loop_notes) + { +! int max_reg = max_reg_num (); + rtx link; + +--- 1522,1526 ---- + if (loop_notes) + { +! int max_reg = reg_last_uses_size; + rtx link; + +*************** sched_analyze (head, tail) +*** 2202,2207 **** + && NOTE_LINE_NUMBER (NEXT_INSN (insn)) == NOTE_INSN_SETJMP) + { +! int max_reg = max_reg_num (); +! for (i = 0; i < max_reg; i++) + { + for (u = reg_last_uses[i]; u; u = XEXP (u, 1)) +--- 1666,1670 ---- + && NOTE_LINE_NUMBER (NEXT_INSN (insn)) == NOTE_INSN_SETJMP) + { +! for (i = 0; i < reg_last_uses_size; i++) + { + for (u = reg_last_uses[i]; u; u = XEXP (u, 1)) +*************** sched_note_set (b, x, death) +*** 2372,2380 **** + + #define SCHED_SORT(READY, NEW_READY, OLD_READY) \ +! do { if ((NEW_READY) - (OLD_READY) == 1) \ +! swap_sort (READY, NEW_READY); \ +! else if ((NEW_READY) - (OLD_READY) > 1) \ +! qsort (READY, NEW_READY, sizeof (rtx), rank_for_schedule); } \ +! while (0) + + /* Returns a positive value if y is preferred; returns a negative value if +--- 1835,1842 ---- + + #define SCHED_SORT(READY, NEW_READY, OLD_READY) \ +! if ((NEW_READY) - (OLD_READY) == 1) \ +! swap_sort (READY, NEW_READY); \ +! else if ((NEW_READY) - (OLD_READY) > 1) \ +! qsort (READY, NEW_READY, sizeof (rtx), rank_for_schedule); else \ + + /* Returns a positive value if y is preferred; returns a negative value if +*************** schedule_block (b, file) +*** 3174,3178 **** + b, INSN_UID (basic_block_head[b]), INSN_UID (basic_block_end[b])); + +! i = max_reg_num (); + reg_last_uses = (rtx *) alloca (i * sizeof (rtx)); + bzero ((char *) reg_last_uses, i * sizeof (rtx)); +--- 2636,2640 ---- + b, INSN_UID (basic_block_head[b]), INSN_UID (basic_block_end[b])); + +! reg_last_uses_size = i = max_reg_num (); + reg_last_uses = (rtx *) alloca (i * sizeof (rtx)); + bzero ((char *) reg_last_uses, i * sizeof (rtx)); +*************** schedule_insns (dump_file) +*** 4718,4721 **** +--- 4180,4198 ---- + max_regno * sizeof (short)); + init_alias_analysis (); ++ #if 0 ++ if (dump_file) ++ { ++ extern rtx *reg_base_value; ++ extern int reg_base_value_size; ++ int i; ++ for (i = 0; i < reg_base_value_size; i++) ++ if (reg_base_value[i]) ++ { ++ fprintf (dump_file, ";; reg_base_value[%d] = ", i); ++ print_rtl (dump_file, reg_base_value[i]); ++ fputc ('\n', dump_file); ++ } ++ } ++ #endif + } + else +*************** schedule_insns (dump_file) +*** 4726,4731 **** + bb_dead_regs = 0; + bb_live_regs = 0; +! if (! flag_schedule_insns) +! init_alias_analysis (); + } + +--- 4203,4207 ---- + bb_dead_regs = 0; + bb_live_regs = 0; +! init_alias_analysis (); + } + +diff -rcp2N gcc-2.7.2.2/toplev.c gcc-2.7.2.2.f.2/toplev.c +*** gcc-2.7.2.2/toplev.c Fri Oct 20 17:56:35 1995 +--- gcc-2.7.2.2.f.2/toplev.c Fri Jan 10 23:18:24 1997 +*************** int flag_unroll_loops; +*** 388,391 **** +--- 388,405 ---- + int flag_unroll_all_loops; + ++ /* Nonzero forces all invariant computations in loops to be moved ++ outside the loop. */ ++ ++ int flag_move_all_movables = 0; ++ ++ /* Nonzero forces all general induction variables in loops to be ++ strength reduced. */ ++ ++ int flag_reduce_all_givs = 0; ++ ++ /* Nonzero gets another run of loop_optimize performed. */ ++ ++ int flag_rerun_loop_opt = 0; ++ + /* Nonzero for -fwritable-strings: + store string constants in data segment and don't uniquize them. */ +*************** int flag_gnu_linker = 1; +*** 522,525 **** +--- 536,550 ---- + int flag_pack_struct = 0; + ++ /* 1 if alias checking is on (by default, when -O). */ ++ int flag_alias_check = 0; ++ ++ /* 0 if pointer arguments may alias each other. True in C. ++ 1 if pointer arguments may not alias each other but may alias ++ global variables. ++ 2 if pointer arguments may not alias each other and may not ++ alias global variables. True in Fortran. ++ This defaults to 0 for C. */ ++ int flag_argument_noalias = 0; ++ + /* Table of language-independent -f options. + STRING is the option name. VARIABLE is the address of the variable. +*************** struct { char *string; int *variable; in +*** 542,545 **** +--- 567,573 ---- + {"unroll-loops", &flag_unroll_loops, 1}, + {"unroll-all-loops", &flag_unroll_all_loops, 1}, ++ {"move-all-movables", &flag_move_all_movables, 1}, ++ {"reduce-all-givs", &flag_reduce_all_givs, 1}, ++ {"rerun-loop-opt", &flag_rerun_loop_opt, 1}, + {"writable-strings", &flag_writable_strings, 1}, + {"peephole", &flag_no_peephole, 0}, +*************** struct { char *string; int *variable; in +*** 568,572 **** + {"gnu-linker", &flag_gnu_linker, 1}, + {"pack-struct", &flag_pack_struct, 1}, +! {"bytecode", &output_bytecode, 1} + }; + +--- 596,604 ---- + {"gnu-linker", &flag_gnu_linker, 1}, + {"pack-struct", &flag_pack_struct, 1}, +! {"bytecode", &output_bytecode, 1}, +! {"alias-check", &flag_alias_check, 1}, +! {"argument-alias", &flag_argument_noalias, 0}, +! {"argument-noalias", &flag_argument_noalias, 1}, +! {"argument-noalias-global", &flag_argument_noalias, 2} + }; + +*************** rest_of_compilation (decl) +*** 2894,2897 **** +--- 2926,2931 ---- + { + loop_optimize (insns, loop_dump_file); ++ if (flag_rerun_loop_opt) ++ loop_optimize (insns, loop_dump_file); + }); + } +*************** main (argc, argv, envp) +*** 3383,3386 **** +--- 3417,3421 ---- + flag_omit_frame_pointer = 1; + #endif ++ flag_alias_check = 1; + } + +diff -rcp2N gcc-2.7.2.2/unroll.c gcc-2.7.2.2.f.2/unroll.c +*** gcc-2.7.2.2/unroll.c Sat Aug 19 17:33:26 1995 +--- gcc-2.7.2.2.f.2/unroll.c Fri Jan 10 23:18:24 1997 +*************** unroll_loop (loop_end, insn_count, loop_ +*** 995,1000 **** + for (j = FIRST_PSEUDO_REGISTER; j < max_reg_before_loop; j++) + if (local_regno[j]) +! map->reg_map[j] = gen_reg_rtx (GET_MODE (regno_reg_rtx[j])); +! + /* The last copy needs the compare/branch insns at the end, + so reset copy_end here if the loop ends with a conditional +--- 995,1003 ---- + for (j = FIRST_PSEUDO_REGISTER; j < max_reg_before_loop; j++) + if (local_regno[j]) +! { +! map->reg_map[j] = gen_reg_rtx (GET_MODE (regno_reg_rtx[j])); +! record_base_value (REGNO (map->reg_map[j]), +! regno_reg_rtx[j]); +! } + /* The last copy needs the compare/branch insns at the end, + so reset copy_end here if the loop ends with a conditional +*************** unroll_loop (loop_end, insn_count, loop_ +*** 1136,1140 **** + for (j = FIRST_PSEUDO_REGISTER; j < max_reg_before_loop; j++) + if (local_regno[j]) +! map->reg_map[j] = gen_reg_rtx (GET_MODE (regno_reg_rtx[j])); + + /* If loop starts with a branch to the test, then fix it so that +--- 1139,1147 ---- + for (j = FIRST_PSEUDO_REGISTER; j < max_reg_before_loop; j++) + if (local_regno[j]) +! { +! map->reg_map[j] = gen_reg_rtx (GET_MODE (regno_reg_rtx[j])); +! record_base_value (REGNO (map->reg_map[j]), +! regno_reg_rtx[j]); +! } + + /* If loop starts with a branch to the test, then fix it so that +*************** copy_loop_body (copy_start, copy_end, ma +*** 1631,1635 **** + incrementing the shared pseudo reg more than + once. */ +! if (! tv->same_insn) + { + /* tv->dest_reg may actually be a (PLUS (REG) +--- 1638,1642 ---- + incrementing the shared pseudo reg more than + once. */ +! if (! tv->same_insn && ! tv->shared) + { + /* tv->dest_reg may actually be a (PLUS (REG) +*************** copy_loop_body (copy_start, copy_end, ma +*** 1757,1760 **** +--- 1764,1768 ---- + giv_dest_reg = tem; + map->reg_map[regno] = tem; ++ record_base_value (REGNO (tem), giv_src_reg); + } + else +*************** find_splittable_regs (unroll_type, loop_ +*** 2443,2447 **** + { + rtx tem = gen_reg_rtx (bl->biv->mode); +! + emit_insn_before (gen_move_insn (tem, bl->biv->src_reg), + loop_start); +--- 2451,2456 ---- + { + rtx tem = gen_reg_rtx (bl->biv->mode); +! +! record_base_value (REGNO (tem), bl->biv->add_val); + emit_insn_before (gen_move_insn (tem, bl->biv->src_reg), + loop_start); +*************** find_splittable_regs (unroll_type, loop_ +*** 2500,2503 **** +--- 2509,2514 ---- + exits. */ + rtx tem = gen_reg_rtx (bl->biv->mode); ++ record_base_value (REGNO (tem), bl->biv->add_val); ++ + emit_insn_before (gen_move_insn (tem, bl->biv->src_reg), + loop_start); +*************** find_splittable_givs (bl, unroll_type, l +*** 2675,2678 **** +--- 2686,2690 ---- + rtx tem = gen_reg_rtx (bl->biv->mode); + ++ record_base_value (REGNO (tem), bl->biv->add_val); + emit_insn_before (gen_move_insn (tem, bl->biv->src_reg), + loop_start); +*************** find_splittable_givs (bl, unroll_type, l +*** 2716,2719 **** +--- 2728,2732 ---- + { + rtx tem = gen_reg_rtx (v->mode); ++ record_base_value (REGNO (tem), v->add_val); + emit_iv_add_mult (bl->initial_value, v->mult_val, + v->add_val, tem, loop_start); +*************** find_splittable_givs (bl, unroll_type, l +*** 2734,2747 **** + register for the split addr giv, just to be safe. */ + +! /* ??? If there are multiple address givs which have been +! combined with the same dest_reg giv, then we may only need +! one new register for them. Pulling out constants below will +! catch some of the common cases of this. Currently, I leave +! the work of simplifying multiple address givs to the +! following cse pass. */ +! +! /* As a special case, if we have multiple identical address givs +! within a single instruction, then we do use a single pseudo +! reg for both. This is necessary in case one is a match_dup + of the other. */ + +--- 2747,2753 ---- + register for the split addr giv, just to be safe. */ + +! /* If we have multiple identical address givs within a +! single instruction, then use a single pseudo reg for +! both. This is necessary in case one is a match_dup + of the other. */ + +*************** find_splittable_givs (bl, unroll_type, l +*** 2756,2759 **** +--- 2762,2776 ---- + INSN_UID (v->insn)); + } ++ /* If multiple address GIVs have been combined with the ++ same dest_reg GIV, do not create a new register for ++ each. */ ++ else if (unroll_type != UNROLL_COMPLETELY ++ && v->giv_type == DEST_ADDR ++ && v->same && v->same->giv_type == DEST_ADDR ++ && v->same->unrolled) ++ { ++ v->dest_reg = v->same->dest_reg; ++ v->shared = 1; ++ } + else if (unroll_type != UNROLL_COMPLETELY) + { +*************** find_splittable_givs (bl, unroll_type, l +*** 2761,2765 **** + register to hold the split value of the DEST_ADDR giv. + Emit insn to initialize its value before loop start. */ +! tem = gen_reg_rtx (v->mode); + + /* If the address giv has a constant in its new_reg value, +--- 2778,2785 ---- + register to hold the split value of the DEST_ADDR giv. + Emit insn to initialize its value before loop start. */ +! +! rtx tem = gen_reg_rtx (v->mode); +! record_base_value (REGNO (tem), v->add_val); +! v->unrolled = 1; + + /* If the address giv has a constant in its new_reg value, +*************** find_splittable_givs (bl, unroll_type, l +*** 2772,2776 **** + v->dest_reg + = plus_constant (tem, INTVAL (XEXP (v->new_reg,1))); +! + /* Only succeed if this will give valid addresses. + Try to validate both the first and the last +--- 2792,2796 ---- + v->dest_reg + = plus_constant (tem, INTVAL (XEXP (v->new_reg,1))); +! + /* Only succeed if this will give valid addresses. + Try to validate both the first and the last +*************** final_biv_value (bl, loop_start, loop_en +*** 3061,3064 **** +--- 3081,3085 ---- + + tem = gen_reg_rtx (bl->biv->mode); ++ record_base_value (REGNO (tem), bl->biv->add_val); + /* Make sure loop_end is not the last insn. */ + if (NEXT_INSN (loop_end) == 0) +*************** final_giv_value (v, loop_start, loop_end +*** 3154,3157 **** +--- 3175,3179 ---- + /* Put the final biv value in tem. */ + tem = gen_reg_rtx (bl->biv->mode); ++ record_base_value (REGNO (tem), bl->biv->add_val); + emit_iv_add_mult (increment, GEN_INT (loop_n_iterations), + bl->initial_value, tem, insert_before); +diff -rcp2N gcc-2.7.2.2/version.c gcc-2.7.2.2.f.2/version.c +*** gcc-2.7.2.2/version.c Thu Feb 20 19:24:33 1997 +--- gcc-2.7.2.2.f.2/version.c Sun Feb 23 16:30:36 1997 +*************** +*** 1 **** +! char *version_string = "2.7.2.2"; +--- 1 ---- +! char *version_string = "2.7.2.2.f.2"; diff --git a/gnu/usr.bin/gcc/f/gbe/2.7.2.diff b/gnu/usr.bin/gcc/f/gbe/2.7.2.diff deleted file mode 100644 index 4b27bae56d5..00000000000 --- a/gnu/usr.bin/gcc/f/gbe/2.7.2.diff +++ /dev/null @@ -1,801 +0,0 @@ -*** gcc-2.7.2/flags.h Thu Jun 15 07:34:11 1995 ---- g77-new/flags.h Wed Mar 6 10:32:55 1996 -*************** extern int flag_unroll_loops; -*** 204,207 **** ---- 204,221 ---- - extern int flag_unroll_all_loops; - -+ /* Nonzero forces all invariant computations in loops to be moved -+ outside the loop. */ -+ -+ extern int flag_move_all_movables; -+ -+ /* Nonzero forces all general induction variables in loops to be -+ strength reduced. */ -+ -+ extern int flag_reduce_all_givs; -+ -+ /* Nonzero gets another run of loop_optimize performed. */ -+ -+ extern int flag_rerun_loop_opt; -+ - /* Nonzero for -fcse-follow-jumps: - have cse follow jumps to do a more extensive job. */ -*** gcc-2.7.2/gcc.info Wed Mar 6 10:23:38 1996 ---- g77-new/gcc.info Fri Mar 15 02:17:17 1996 -*************** Indirect: -*** 34,60 **** - gcc.info-1: 1382 - gcc.info-2: 42854 -! gcc.info-3: 80578 -! gcc.info-4: 127608 -! gcc.info-5: 173792 -! gcc.info-6: 214726 -! gcc.info-7: 235436 -! gcc.info-8: 285158 -! gcc.info-9: 333642 -! gcc.info-10: 382691 -! gcc.info-11: 419654 -! gcc.info-12: 468472 -! gcc.info-13: 517503 -! gcc.info-14: 564845 -! gcc.info-15: 604398 -! gcc.info-16: 654371 -! gcc.info-17: 703324 -! gcc.info-18: 751502 -! gcc.info-19: 797360 -! gcc.info-20: 846162 -! gcc.info-21: 890260 -! gcc.info-22: 933466 -! gcc.info-23: 982355 -! gcc.info-24: 1032258 -! gcc.info-25: 1067513 - - Tag Table: ---- 34,60 ---- - gcc.info-1: 1382 - gcc.info-2: 42854 -! gcc.info-3: 80645 -! gcc.info-4: 129158 -! gcc.info-5: 175342 -! gcc.info-6: 216276 -! gcc.info-7: 236986 -! gcc.info-8: 286708 -! gcc.info-9: 335192 -! gcc.info-10: 384241 -! gcc.info-11: 421204 -! gcc.info-12: 470022 -! gcc.info-13: 519053 -! gcc.info-14: 566395 -! gcc.info-15: 605948 -! gcc.info-16: 655921 -! gcc.info-17: 704874 -! gcc.info-18: 753052 -! gcc.info-19: 798910 -! gcc.info-20: 847712 -! gcc.info-21: 891810 -! gcc.info-22: 935016 -! gcc.info-23: 983905 -! gcc.info-24: 1033808 -! gcc.info-25: 1069063 - - Tag Table: -*************** Node: G++ and GCC37258 -*** 68,297 **** - Node: Invoking GCC39475 - Node: Option Summary42854 -! Node: Overall Options53305 -! Node: Invoking G++57868 -! Node: C Dialect Options59742 -! Node: C++ Dialect Options69842 -! Node: Warning Options80578 -! Node: Debugging Options95513 -! Node: Optimize Options105094 -! Node: Preprocessor Options115596 -! Node: Assembler Options122059 -! Node: Link Options122426 -! Node: Directory Options127608 -! Node: Target Options131100 -! Node: Submodel Options134757 -! Node: M680x0 Options136138 -! Node: VAX Options139647 -! Node: SPARC Options140182 -! Node: Convex Options146602 -! Node: AMD29K Options148783 -! Node: ARM Options151814 -! Node: M88K Options153231 -! Node: RS/6000 and PowerPC Options161178 -! Node: RT Options172088 -! Node: MIPS Options173792 -! Node: i386 Options181418 -! Node: HPPA Options186857 -! Node: Intel 960 Options189953 -! Node: DEC Alpha Options192563 -! Node: Clipper Options194235 -! Node: H8/300 Options194634 -! Node: System V Options195079 -! Node: Code Gen Options195765 -! Node: Environment Variables204274 -! Node: Running Protoize208497 -! Node: Installation214726 -! Node: Configurations235436 -! Node: Other Dir271347 -! Node: Cross-Compiler273063 -! Node: Steps of Cross274894 -! Node: Configure Cross276012 -! Node: Tools and Libraries276649 -! Node: Cross Runtime279092 -! Node: Cross Headers283173 -! Node: Build Cross285158 -! Node: Sun Install287034 -! Node: VMS Install288166 -! Node: Collect2298095 -! Node: Header Dirs300804 -! Node: C Extensions302218 -! Node: Statement Exprs305497 -! Node: Local Labels307391 -! Node: Labels as Values309453 -! Node: Nested Functions311318 -! Node: Constructing Calls315174 -! Node: Naming Types317231 -! Node: Typeof318325 -! Node: Lvalues320190 -! Node: Conditionals322630 -! Node: Long Long323521 -! Node: Complex324965 -! Node: Zero Length326827 -! Node: Variable Length327501 -! Node: Macro Varargs330026 -! Node: Subscripting332129 -! Node: Pointer Arith332612 -! Node: Initializers333177 -! Node: Constructors333642 -! Node: Labeled Elements335336 -! Node: Case Ranges337965 -! Node: Cast to Union338646 -! Node: Function Attributes339724 -! Node: Function Prototypes348987 -! Node: C++ Comments350786 -! Node: Dollar Signs351322 -! Node: Character Escapes352102 -! Node: Alignment352383 -! Node: Variable Attributes353855 -! Node: Type Attributes361763 -! Node: Inline368282 -! Node: Extended Asm372159 -! Node: Asm Labels382691 -! Node: Explicit Reg Vars384010 -! Node: Global Reg Vars385258 -! Node: Local Reg Vars389823 -! Node: Alternate Keywords391415 -! Node: Incomplete Enums392817 -! Node: Function Names393573 -! Node: C++ Extensions394824 -! Node: Naming Results396061 -! Node: Min and Max399375 -! Node: Destructors and Goto400825 -! Node: C++ Interface401375 -! Node: Template Instantiation406598 -! Node: C++ Signatures412330 -! Node: Trouble416674 -! Node: Actual Bugs418385 -! Node: Installation Problems419654 -! Node: Cross-Compiler Problems433440 -! Node: Interoperation434911 -! Node: External Bugs448275 -! Node: Incompatibilities450407 -! Node: Fixed Headers458957 -! Node: Standard Libraries461299 -! Node: Disappointments462546 -! Node: C++ Misunderstandings466771 -! Node: Static Definitions467418 -! Node: Temporaries468472 -! Node: Protoize Caveats470676 -! Node: Non-bugs474632 -! Node: Warnings and Errors483592 -! Node: Bugs485362 -! Node: Bug Criteria486722 -! Node: Bug Lists489152 -! Node: Bug Reporting490545 -! Node: Sending Patches502963 -! Node: Service508350 -! Node: VMS508911 -! Node: Include Files and VMS509304 -! Node: Global Declarations513194 -! Node: VMS Misc517503 -! Node: Portability521829 -! Node: Interface523592 -! Node: Passes528225 -! Node: RTL545568 -! Node: RTL Objects547456 -! Node: Accessors550500 -! Node: Flags555826 -! Node: Machine Modes564845 -! Node: Constants572479 -! Node: Regs and Memory577667 -! Node: Arithmetic589377 -! Node: Comparisons595275 -! Node: Bit Fields599337 -! Node: Conversions600701 -! Node: RTL Declarations603589 -! Node: Side Effects604398 -! Node: Incdec616945 -! Node: Assembler619461 -! Node: Insns620983 -! Node: Calls641836 -! Node: Sharing644431 -! Node: Reading RTL647507 -! Node: Machine Desc648446 -! Node: Patterns650299 -! Node: Example653243 -! Node: RTL Template654371 -! Node: Output Template666569 -! Node: Output Statement670530 -! Node: Constraints674243 -! Node: Simple Constraints675246 -! Node: Multi-Alternative686679 -! Node: Class Preferences689515 -! Node: Modifiers690395 -! Node: Machine Constraints693555 -! Node: No Constraints702203 -! Node: Standard Names703324 -! Node: Pattern Ordering731232 -! Node: Dependent Patterns732458 -! Node: Jump Patterns735273 -! Node: Insn Canonicalizations741089 -! Node: Peephole Definitions744584 -! Node: Expander Definitions751502 -! Node: Insn Splitting758948 -! Node: Insn Attributes765962 -! Node: Defining Attributes767009 -! Node: Expressions769021 -! Node: Tagging Insns775333 -! Node: Attr Example779696 -! Node: Insn Lengths782072 -! Node: Constant Attributes785436 -! Node: Delay Slots786596 -! Node: Function Units789807 -! Node: Target Macros795477 -! Node: Driver797360 -! Node: Run-time Target809090 -! Node: Storage Layout814977 -! Node: Type Layout828925 -! Node: Registers835348 -! Node: Register Basics836328 -! Node: Allocation Order840365 -! Node: Values in Registers841783 -! Node: Leaf Functions846162 -! Node: Stack Registers848637 -! Node: Obsolete Register Macros849470 -! Node: Register Classes852165 -! Node: Stack and Calling871700 -! Node: Frame Layout872136 -! Node: Frame Registers875576 -! Node: Elimination879386 -! Node: Stack Arguments883642 -! Node: Register Arguments890260 -! Node: Scalar Return898935 -! Node: Aggregate Return902898 -! Node: Caller Saves906613 -! Node: Function Entry907763 -! Node: Profiling916691 -! Node: Varargs919595 -! Node: Trampolines927004 -! Node: Library Calls933466 -! Node: Addressing Modes941524 -! Node: Condition Code949112 -! Node: Costs955311 -! Node: Sections963690 -! Node: PIC968479 -! Node: Assembler Format971189 -! Node: File Framework972194 -! Node: Data Output976431 -! Node: Uninitialized Data982355 -! Node: Label Output985062 -! Node: Initialization994456 -! Node: Macros for Initialization1000599 -! Node: Instruction Output1005196 -! Node: Dispatch Tables1013191 -! Node: Alignment Output1015568 -! Node: Debugging Info1017308 -! Node: All Debuggers1017917 -! Node: DBX Options1020331 -! Node: DBX Hooks1025216 -! Node: File Names and DBX1028555 -! Node: SDB and DWARF1030528 -! Node: Cross-compilation1032258 -! Node: Misc1038705 -! Node: Config1055831 -! Node: Fragments1063276 -! Node: Target Fragment1063873 -! Node: Host Fragment1066911 -! Node: Index1067513 - - End Tag Table ---- 68,297 ---- - Node: Invoking GCC39475 - Node: Option Summary42854 -! Node: Overall Options53372 -! Node: Invoking G++57935 -! Node: C Dialect Options59809 -! Node: C++ Dialect Options69909 -! Node: Warning Options80645 -! Node: Debugging Options95580 -! Node: Optimize Options105161 -! Node: Preprocessor Options117146 -! Node: Assembler Options123609 -! Node: Link Options123976 -! Node: Directory Options129158 -! Node: Target Options132650 -! Node: Submodel Options136307 -! Node: M680x0 Options137688 -! Node: VAX Options141197 -! Node: SPARC Options141732 -! Node: Convex Options148152 -! Node: AMD29K Options150333 -! Node: ARM Options153364 -! Node: M88K Options154781 -! Node: RS/6000 and PowerPC Options162728 -! Node: RT Options173638 -! Node: MIPS Options175342 -! Node: i386 Options182968 -! Node: HPPA Options188407 -! Node: Intel 960 Options191503 -! Node: DEC Alpha Options194113 -! Node: Clipper Options195785 -! Node: H8/300 Options196184 -! Node: System V Options196629 -! Node: Code Gen Options197315 -! Node: Environment Variables205824 -! Node: Running Protoize210047 -! Node: Installation216276 -! Node: Configurations236986 -! Node: Other Dir272897 -! Node: Cross-Compiler274613 -! Node: Steps of Cross276444 -! Node: Configure Cross277562 -! Node: Tools and Libraries278199 -! Node: Cross Runtime280642 -! Node: Cross Headers284723 -! Node: Build Cross286708 -! Node: Sun Install288584 -! Node: VMS Install289716 -! Node: Collect2299645 -! Node: Header Dirs302354 -! Node: C Extensions303768 -! Node: Statement Exprs307047 -! Node: Local Labels308941 -! Node: Labels as Values311003 -! Node: Nested Functions312868 -! Node: Constructing Calls316724 -! Node: Naming Types318781 -! Node: Typeof319875 -! Node: Lvalues321740 -! Node: Conditionals324180 -! Node: Long Long325071 -! Node: Complex326515 -! Node: Zero Length328377 -! Node: Variable Length329051 -! Node: Macro Varargs331576 -! Node: Subscripting333679 -! Node: Pointer Arith334162 -! Node: Initializers334727 -! Node: Constructors335192 -! Node: Labeled Elements336886 -! Node: Case Ranges339515 -! Node: Cast to Union340196 -! Node: Function Attributes341274 -! Node: Function Prototypes350537 -! Node: C++ Comments352336 -! Node: Dollar Signs352872 -! Node: Character Escapes353652 -! Node: Alignment353933 -! Node: Variable Attributes355405 -! Node: Type Attributes363313 -! Node: Inline369832 -! Node: Extended Asm373709 -! Node: Asm Labels384241 -! Node: Explicit Reg Vars385560 -! Node: Global Reg Vars386808 -! Node: Local Reg Vars391373 -! Node: Alternate Keywords392965 -! Node: Incomplete Enums394367 -! Node: Function Names395123 -! Node: C++ Extensions396374 -! Node: Naming Results397611 -! Node: Min and Max400925 -! Node: Destructors and Goto402375 -! Node: C++ Interface402925 -! Node: Template Instantiation408148 -! Node: C++ Signatures413880 -! Node: Trouble418224 -! Node: Actual Bugs419935 -! Node: Installation Problems421204 -! Node: Cross-Compiler Problems434990 -! Node: Interoperation436461 -! Node: External Bugs449825 -! Node: Incompatibilities451957 -! Node: Fixed Headers460507 -! Node: Standard Libraries462849 -! Node: Disappointments464096 -! Node: C++ Misunderstandings468321 -! Node: Static Definitions468968 -! Node: Temporaries470022 -! Node: Protoize Caveats472226 -! Node: Non-bugs476182 -! Node: Warnings and Errors485142 -! Node: Bugs486912 -! Node: Bug Criteria488272 -! Node: Bug Lists490702 -! Node: Bug Reporting492095 -! Node: Sending Patches504513 -! Node: Service509900 -! Node: VMS510461 -! Node: Include Files and VMS510854 -! Node: Global Declarations514744 -! Node: VMS Misc519053 -! Node: Portability523379 -! Node: Interface525142 -! Node: Passes529775 -! Node: RTL547118 -! Node: RTL Objects549006 -! Node: Accessors552050 -! Node: Flags557376 -! Node: Machine Modes566395 -! Node: Constants574029 -! Node: Regs and Memory579217 -! Node: Arithmetic590927 -! Node: Comparisons596825 -! Node: Bit Fields600887 -! Node: Conversions602251 -! Node: RTL Declarations605139 -! Node: Side Effects605948 -! Node: Incdec618495 -! Node: Assembler621011 -! Node: Insns622533 -! Node: Calls643386 -! Node: Sharing645981 -! Node: Reading RTL649057 -! Node: Machine Desc649996 -! Node: Patterns651849 -! Node: Example654793 -! Node: RTL Template655921 -! Node: Output Template668119 -! Node: Output Statement672080 -! Node: Constraints675793 -! Node: Simple Constraints676796 -! Node: Multi-Alternative688229 -! Node: Class Preferences691065 -! Node: Modifiers691945 -! Node: Machine Constraints695105 -! Node: No Constraints703753 -! Node: Standard Names704874 -! Node: Pattern Ordering732782 -! Node: Dependent Patterns734008 -! Node: Jump Patterns736823 -! Node: Insn Canonicalizations742639 -! Node: Peephole Definitions746134 -! Node: Expander Definitions753052 -! Node: Insn Splitting760498 -! Node: Insn Attributes767512 -! Node: Defining Attributes768559 -! Node: Expressions770571 -! Node: Tagging Insns776883 -! Node: Attr Example781246 -! Node: Insn Lengths783622 -! Node: Constant Attributes786986 -! Node: Delay Slots788146 -! Node: Function Units791357 -! Node: Target Macros797027 -! Node: Driver798910 -! Node: Run-time Target810640 -! Node: Storage Layout816527 -! Node: Type Layout830475 -! Node: Registers836898 -! Node: Register Basics837878 -! Node: Allocation Order841915 -! Node: Values in Registers843333 -! Node: Leaf Functions847712 -! Node: Stack Registers850187 -! Node: Obsolete Register Macros851020 -! Node: Register Classes853715 -! Node: Stack and Calling873250 -! Node: Frame Layout873686 -! Node: Frame Registers877126 -! Node: Elimination880936 -! Node: Stack Arguments885192 -! Node: Register Arguments891810 -! Node: Scalar Return900485 -! Node: Aggregate Return904448 -! Node: Caller Saves908163 -! Node: Function Entry909313 -! Node: Profiling918241 -! Node: Varargs921145 -! Node: Trampolines928554 -! Node: Library Calls935016 -! Node: Addressing Modes943074 -! Node: Condition Code950662 -! Node: Costs956861 -! Node: Sections965240 -! Node: PIC970029 -! Node: Assembler Format972739 -! Node: File Framework973744 -! Node: Data Output977981 -! Node: Uninitialized Data983905 -! Node: Label Output986612 -! Node: Initialization996006 -! Node: Macros for Initialization1002149 -! Node: Instruction Output1006746 -! Node: Dispatch Tables1014741 -! Node: Alignment Output1017118 -! Node: Debugging Info1018858 -! Node: All Debuggers1019467 -! Node: DBX Options1021881 -! Node: DBX Hooks1026766 -! Node: File Names and DBX1030105 -! Node: SDB and DWARF1032078 -! Node: Cross-compilation1033808 -! Node: Misc1040255 -! Node: Config1057381 -! Node: Fragments1064826 -! Node: Target Fragment1065423 -! Node: Host Fragment1068461 -! Node: Index1069063 - - End Tag Table -*** gcc-2.7.2/gcc.info-2 Wed Mar 6 10:23:35 1996 ---- g77-new/gcc.info-2 Fri Mar 15 02:17:16 1996 -*************** are in the following sections. -*** 92,95 **** ---- 92,96 ---- - -fschedule-insns2 -fstrength-reduce -fthread-jumps - -funroll-all-loops -funroll-loops -+ -fmove-all-movables -freduce-all-givs -frerun-loop-opt - -O -O0 -O1 -O2 -O3 - -*** gcc-2.7.2/gcc.info-3 Wed Mar 6 10:23:35 1996 ---- g77-new/gcc.info-3 Fri Mar 15 02:17:16 1996 -*************** of optimizations to be performed is desi -*** 907,910 **** ---- 907,946 ---- - `-frerun-cse-after-loop'. - -+ `-fmove-all-movables' -+ Forces all invariant computations in loops to be moved outside the -+ loop. This option is provided primarily to improve performance -+ for some Fortran code, though it might improve code written in -+ other languages. -+ -+ *Note:* When compiling programs written in Fortran, this option is -+ enabled by default. -+ -+ Analysis of Fortran code optimization and the resulting -+ optimizations triggered by this option, and the -+ `-freduce-all-givs' and `-frerun-loop-opt' options as well, were -+ contributed by Toon Moene (`toon@moene.indiv.nluug.nl'). -+ -+ Please let us (`fortran@gnu.ai.mit.edu') know how use of these -+ options affects the performance of your production code. We're -+ very interested in code that runs *slower* when these options are -+ *enabled*. -+ -+ `-freduce-all-givs' -+ Forces all general-induction variables in loops to be -+ strength-reduced. This option is provided primarily to improve -+ performance for some Fortran code, though it might improve code -+ written in other languages. -+ -+ *Note:* When compiling programs written in Fortran, this option is -+ enabled by default. -+ -+ `-frerun-loop-opt' -+ Runs loop optimizations a second time. This option is provided -+ primarily to improve performance for some Fortran code, though it -+ might improve code written in other languages. -+ -+ *Note:* When compiling programs written in Fortran, this option is -+ enabled by default. -+ - `-fno-peephole' - Disable any machine-specific peephole optimizations. -*** gcc-2.7.2/gcc.texi Wed Mar 6 10:20:58 1996 ---- g77-new/gcc.texi Wed Mar 6 14:30:40 1996 -*************** original English. -*** 149,152 **** ---- 149,153 ---- - @sp 3 - @center Last updated 26 November 1995 -+ @center (Revised for GNU Fortran 1996-03-06) - @sp 1 - @c The version number appears twice more in this file. -*** gcc-2.7.2/invoke.texi Tue Oct 3 11:40:43 1995 ---- g77-new/invoke.texi Fri Mar 15 01:49:11 1996 -*************** in the following sections. -*** 149,152 **** ---- 149,153 ---- - -fschedule-insns2 -fstrength-reduce -fthread-jumps - -funroll-all-loops -funroll-loops -+ -fmove-all-movables -freduce-all-givs -frerun-loop-opt - -O -O0 -O1 -O2 -O3 - @end smallexample -*************** Perform the optimization of loop unrolli -*** 1940,1943 **** ---- 1941,1985 ---- - and usually makes programs run more slowly. @samp{-funroll-all-loops} - implies @samp{-fstrength-reduce} as well as @samp{-frerun-cse-after-loop}. -+ -+ @item -fmove-all-movables -+ Forces all invariant computations in loops to be moved -+ outside the loop. -+ This option is provided primarily to improve performance -+ for some Fortran code, though it might improve code written -+ in other languages. -+ -+ @emph{Note:} When compiling programs written in Fortran, -+ this option is enabled by default. -+ -+ Analysis of Fortran code optimization and the resulting -+ optimizations triggered by this option, and the -+ @samp{-freduce-all-givs} and @samp{-frerun-loop-opt} -+ options as well, were -+ contributed by Toon Moene (@code{toon@@moene.indiv.nluug.nl}). -+ -+ Please let us (@code{fortran@@gnu.ai.mit.edu}) -+ know how use of these options affects -+ the performance of your production code. -+ We're very interested in code that runs @emph{slower} -+ when these options are @emph{enabled}. -+ -+ @item -freduce-all-givs -+ Forces all general-induction variables in loops to be -+ strength-reduced. -+ This option is provided primarily to improve performance -+ for some Fortran code, though it might improve code written -+ in other languages. -+ -+ @emph{Note:} When compiling programs written in Fortran, -+ this option is enabled by default. -+ -+ @item -frerun-loop-opt -+ Runs loop optimizations a second time. -+ This option is provided primarily to improve performance -+ for some Fortran code, though it might improve code written -+ in other languages. -+ -+ @emph{Note:} When compiling programs written in Fortran, -+ this option is enabled by default. - - @item -fno-peephole -*** gcc-2.7.2/loop.c Tue Oct 3 12:17:16 1995 ---- g77-new/loop.c Wed Mar 6 10:32:58 1996 -*************** move_movables (movables, threshold, insn -*** 1629,1632 **** ---- 1629,1633 ---- - - if (already_moved[regno] -+ || flag_move_all_movables - || (threshold * savings * m->lifetime) >= insn_count - || (m->forces && m->forces->done -*************** strength_reduce (scan_start, end, loop_t -*** 3821,3826 **** - exit. */ - -! if (v->lifetime * threshold * benefit < insn_count -! && ! bl->reversed) - { - if (loop_dump_stream) ---- 3822,3827 ---- - exit. */ - -! if ( ! flag_reduce_all_givs && v->lifetime * threshold * benefit < insn_count -! && ! bl->reversed ) - { - if (loop_dump_stream) -*** gcc-2.7.2/toplev.c Fri Oct 20 17:56:35 1995 ---- g77-new/toplev.c Wed Mar 6 10:32:59 1996 -*************** int flag_unroll_loops; -*** 388,391 **** ---- 388,405 ---- - int flag_unroll_all_loops; - -+ /* Nonzero forces all invariant computations in loops to be moved -+ outside the loop. */ -+ -+ int flag_move_all_movables = 0; -+ -+ /* Nonzero forces all general induction variables in loops to be -+ strength reduced. */ -+ -+ int flag_reduce_all_givs = 0; -+ -+ /* Nonzero gets another run of loop_optimize performed. */ -+ -+ int flag_rerun_loop_opt = 0; -+ - /* Nonzero for -fwritable-strings: - store string constants in data segment and don't uniquize them. */ -*************** struct { char *string; int *variable; in -*** 542,545 **** ---- 556,562 ---- - {"unroll-loops", &flag_unroll_loops, 1}, - {"unroll-all-loops", &flag_unroll_all_loops, 1}, -+ {"move-all-movables", &flag_move_all_movables, 1}, -+ {"reduce-all-givs", &flag_reduce_all_givs, 1}, -+ {"rerun-loop-opt", &flag_rerun_loop_opt, 1}, - {"writable-strings", &flag_writable_strings, 1}, - {"peephole", &flag_no_peephole, 0}, -*************** rest_of_compilation (decl) -*** 2894,2897 **** ---- 2911,2916 ---- - { - loop_optimize (insns, loop_dump_file); -+ if (flag_rerun_loop_opt) -+ loop_optimize (insns, loop_dump_file); - }); - } -*** gcc-2.7.2/tree.c Sun Oct 1 21:26:56 1995 ---- g77-new/tree.c Wed Mar 6 10:33:00 1996 -*************** saveable_tree_cons (purpose, value, chai -*** 1965,1968 **** ---- 1965,1992 ---- - } - -+ /* Try to find out whether the type for which the size is to be determined -+ is an ARRAY(of ARRAY(of ARRAY ... of something with a constant size -+ which is an integral multiple of BITS_PER_UNIT)). -+ In that case, the size in bytes can be determined using an EXACT_DIV_EXPR. -+ */ -+ enum tree_code -+ which_div_expr(type) -+ tree type; -+ { -+ tree t; -+ -+ if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != ARRAY_TYPE) -+ return CEIL_DIV_EXPR; -+ -+ for (t = TREE_TYPE (type); TREE_CODE (t) == ARRAY_TYPE; t = TREE_TYPE (t)) -+ ; -+ -+ if (TYPE_SIZE (t) != 0 && TREE_CODE (TYPE_SIZE (t)) == INTEGER_CST && -+ TREE_INT_CST_LOW (TYPE_SIZE (t)) % BITS_PER_UNIT == 0) -+ return EXACT_DIV_EXPR; -+ else -+ return CEIL_DIV_EXPR; -+ } -+ - /* Return the size nominally occupied by an object of type TYPE - when it resides in memory. The value is measured in units of bytes, -*************** size_in_bytes (type) -*** 1985,1989 **** - return integer_zero_node; - } -! t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), - size_int (BITS_PER_UNIT)); - if (TREE_CODE (t) == INTEGER_CST) ---- 2009,2013 ---- - return integer_zero_node; - } -! t = size_binop (which_div_expr (type), TYPE_SIZE (type), - size_int (BITS_PER_UNIT)); - if (TREE_CODE (t) == INTEGER_CST) -*************** int_size_in_bytes (type) -*** 2009,2013 **** - if (TREE_INT_CST_HIGH (TYPE_SIZE (type)) != 0) - { -! tree t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), - size_int (BITS_PER_UNIT)); - return TREE_INT_CST_LOW (t); ---- 2033,2037 ---- - if (TREE_INT_CST_HIGH (TYPE_SIZE (type)) != 0) - { -! tree t = size_binop (which_div_expr (type), TYPE_SIZE (type), - size_int (BITS_PER_UNIT)); - return TREE_INT_CST_LOW (t); -*** gcc-2.7.2/version.c Wed Mar 6 10:21:01 1996 ---- g77-new/version.c Mon Mar 25 21:17:27 1996 -*************** -*** 1 **** -! char *version_string = "2.7.2"; ---- 1 ---- -! char *version_string = "2.7.2.f.1"; diff --git a/gnu/usr.bin/gcc/f/gbe/README b/gnu/usr.bin/gcc/f/gbe/README index 1752b600aed..90fc29f183e 100644 --- a/gnu/usr.bin/gcc/f/gbe/README +++ b/gnu/usr.bin/gcc/f/gbe/README @@ -1,28 +1,27 @@ -961207 +970223 This directory contains .diff files for various GNU CC distributions supported by this version of GNU Fortran. The name of a file includes which gcc version to which it applies. -For example, 2.7.2.1.diff is the patch file for gcc version 2.7.2.1. +For example, 2.7.2.2.diff is the patch file for gcc version 2.7.2.2. -To apply a .diff file to, say, gcc 2.7.2, one might use the following +To apply a .diff file to, say, gcc 2.7.2.2, one might use the following command (where the current directory contains the gcc source distribution after merging into it the g77 source distribution, which would be -named gcc-2.7.2 in this example): +named gcc-2.7.2.2 in this example): - patch -p1 -d gcc-2.7.2 < gcc-2.7.2/f/gbe/2.7.2.diff + patch -p1 -d gcc-2.7.2.2 < gcc-2.7.2.2/f/gbe/2.7.2.2.diff -This version of g77 is best combined with gcc versions 2.7.2 or 2.7.2.1. +This version of g77 is best combined with gcc versions 2.7.2.2. -However, note that applying the patch for version 2.7.2.1 -does _not_ update the gcc.info* files that constitute the Info -documentation for gcc. Therefore, after applying the 2.7.2.1.diff -patch to the gcc-2.7.2.1 source directory, you must rebuild the -Info documentation yourself via: +However, note that applying any of these patches does _not_ update +the gcc.info* files that constitute the Info documentation for gcc. +Therefore, after applying the patch, you must rebuild the Info +documentation yourself via: - cd gcc-2.7.2.1; make -f Makefile.in gcc.info + cd gcc; make -f Makefile.in gcc.info If the above command doesn't work because you don't have makeinfo installed, you are STRONGLY encouraged to obtain the most recent @@ -30,15 +29,8 @@ version of the GNU texinfo package (texinfo-3.9.tar.gz as of this writing), build, and install it, then try the above command (as makeinfo is part of texinfo). -(The 2.7.2.1 patch omits the gcc.info* patches because your gcc-2.7.2.1 -might have one of at least two different versions of these gcc.info* -files, depending on how you obtained the gcc source directory -- by -unpacking gcc-2.7.2.1.tar.gz directly, or by applying a patch to upgrade -a copy of gcc-2.7.2.) - This distribution of g77 is not supported for versions of gcc prior -to 2.6.2. The 2.6.3 patch file should work for version 2.6.2, but -you should probably use gcc-2.6.3 in any case if that is possible. +to 2.7.2.2. If you are using a version of gcc more recent than the most recent .diff file's version, try the most recent .diff ONLY @@ -49,5 +41,5 @@ a more major release like gcc-2.8.0 or gcc-3.0.0, and you shouldn't try it. If the .diff file is missing, don't bother asking `fortran@gnu.ai.mit.edu' for it -- it is certainly being worked on. In the meantime, watch the usual place -(`info -f g77') for information on support for the recent -versions of gcc. +(ftp://alpha.gnu.ai.mit.edu:g77.plan) for information on support +for the recent versions of gcc. diff --git a/gnu/usr.bin/gcc/f/global.c b/gnu/usr.bin/gcc/f/global.c index 41b9e37c7ad..94d7c7b6d40 100644 --- a/gnu/usr.bin/gcc/f/global.c +++ b/gnu/usr.bin/gcc/f/global.c @@ -348,6 +348,27 @@ ffeglobal_pad_common (ffesymbol s, ffetargetAlign pad, ffewhereLine wl, } } +/* Return a global for a promoted symbol (one that has heretofore + been assumed to be local, but since discovered to be global). */ + +ffeglobal +ffeglobal_promoted (ffesymbol s) +{ +#if FFEGLOBAL_ENABLED + ffename n; + ffeglobal g; + + assert (ffesymbol_global (s) == NULL); + + n = ffename_find (ffeglobal_filewide_, ffename_token (ffesymbol_name (s))); + g = ffename_global (n); + + return g; +#else + return NULL; +#endif +} + /* ffeglobal_save_common -- Check SAVE status of common area ffesymbol s; // the common area diff --git a/gnu/usr.bin/gcc/f/global.h b/gnu/usr.bin/gcc/f/global.h index 5e9a76124ac..e28b944ffef 100644 --- a/gnu/usr.bin/gcc/f/global.h +++ b/gnu/usr.bin/gcc/f/global.h @@ -93,6 +93,7 @@ void ffeglobal_new_progunit_ (ffesymbol s, ffelexToken t, ffeglobalType type); void ffeglobal_new_common (ffesymbol s, ffelexToken t, bool blank); void ffeglobal_pad_common (ffesymbol s, ffetargetAlign pad, ffewhereLine wl, ffewhereColumn wc); +ffeglobal ffeglobal_promoted (ffesymbol s); void ffeglobal_save_common (ffesymbol s, bool save, ffewhereLine wl, ffewhereColumn wc); bool ffeglobal_size_common (ffesymbol s, long size); diff --git a/gnu/usr.bin/gcc/f/install.texi b/gnu/usr.bin/gcc/f/install.texi index 08ee8003ffc..04e498517e6 100644 --- a/gnu/usr.bin/gcc/f/install.texi +++ b/gnu/usr.bin/gcc/f/install.texi @@ -1,11 +1,11 @@ -@c Copyright (C) 1995, 1996 Free Software Foundation, Inc. +@c Copyright (C) 1995-1997 Free Software Foundation, Inc. @c This is part of the G77 manual. @c For copying conditions, see the file g77.texi. @c The text of this file appears in the file INSTALL @c in the G77 distribution, as well as in the G77 manual. -@c 1996-12-01 +@c 1997-02-25 @ifclear INSTALLONLY @node Installation @@ -13,15 +13,6 @@ @end ifclear @cindex installing GNU Fortran -@menu -* Prerequisites:: Make sure your system is ready for @code{g77}. -* Problems Installing:: Known trouble areas. -* Quick Start:: The easier procedure for non-experts. -* Complete Installation:: For experts, or those who want to be: the details. -* Distributing Binaries:: If you plan on distributing your @code{g77}. -* Settings:: Some notes on @code{g77} internals. -@end menu - The following information describes how to install @code{g77}. The information in this file generally pertains to dealing @@ -36,6 +27,15 @@ Nevertheless, efforts to make @code{g77} easier to both build and install from source and package up as a binary distribution are ongoing. +@menu +* Prerequisites:: Make sure your system is ready for @code{g77}. +* Problems Installing:: Known trouble areas. +* Settings:: Changing @code{g77} internals before building. +* Quick Start:: The easier procedure for non-experts. +* Complete Installation:: For experts, or those who want to be: the details. +* Distributing Binaries:: If you plan on distributing your @code{g77}. +@end menu + @node Prerequisites @section Prerequisites @cindex prerequisites @@ -61,15 +61,15 @@ There are GNU versions of all these available---in fact, a complete GNU UNIX system can be put together on most systems, if desired. -@item @file{gcc-2.7.2.tar.gz} +@item @file{gcc-2.7.2.2.tar.gz} You need to have this, or some other applicable, version of @code{gcc} on your system. The version should be an exact copy of a distribution from the FSF. It is approximately 7MB large. -If you've already unpacked @file{gcc-2.7.2.tar.gz} into a -directory (named @file{gcc-2.7.2}) called the @dfn{source tree} +If you've already unpacked @file{gcc-2.7.2.2.tar.gz} into a +directory (named @file{gcc-2.7.2.2}) called the @dfn{source tree} for @code{gcc}, you can delete the distribution itself, but you'll need to remember to skip any instructions to unpack this distribution. @@ -78,7 +78,7 @@ Without an applicable @code{gcc} source tree, you cannot build @code{g77}. You can obtain an FSF distribution of @code{gcc} from the FSF. -@item @file{g77-0.5.19.tar.gz} +@item @file{g77-0.5.20.tar.gz} You probably have already unpacked this distribution, or you are reading an advanced copy of this manual, which is contained in this distribution. @@ -187,15 +187,79 @@ either @code{gcc} or @code{g77}. @node General Problems @subsection General Problems -@itemize @bullet -@item +These problems can occur on most or all systems. + +@menu +* GNU C Required:: Why even ANSI C is not enough. +* Patching GNU CC Necessary:: Why @code{gcc} must be patched first. +* Building GNU CC Necessary:: Why you can't build @emph{just} Fortran. +* Missing strtoul:: If linking @code{f771} fails due to an + unresolved reference to @code{strtoul}. +* Object File Differences:: It's okay that @samp{make compare} will + flag @file{f/zzz.o}. +* Cleanup Kills Stage Directories:: A minor nit for @code{g77} developers. +@end menu + +@node GNU C Required +@subsubsection GNU C Required +@cindex GNU C required +@cindex requirements, GNU C + +Compiling @code{g77} requires GNU C, not just ANSI C. +Fixing this wouldn't +be very hard (just tedious), but the code using GNU extensions to +the C language is expected to be rewritten for 0.6 anyway, +so there are no plans for an interim fix. + +This requirement does not mean you must already have @code{gcc} +installed to build @code{g77}. +As long as you have a working C compiler, you can use a +bootstrap build to automate the process of first building +@code{gcc} using the working C compiler you have, then building +@code{g77} and rebuilding @code{gcc} using that just-built @code{gcc}, +and so on. + +@node Patching GNU CC Necessary +@subsubsection Patching GNU CC Necessary +@cindex patch files +@cindex GBE + +@code{g77} currently requires application of a patch file to the gcc compiler +tree. +The necessary patches should be folded in to the mainline gcc distribution. + +Some combinations +of versions of @code{g77} and @code{gcc} might actually @emph{require} no +patches, but the patch files will be provided anyway as long as +there are more changes expected in subsequent releases. +These patch files might contain +unnecessary, but possibly helpful, patches. +As a result, it is possible this issue might never be +resolved, except by eliminating the need for the person +configuring @code{g77} to apply a patch by hand, by going +to a more automated approach (such as configure-time patching). + +@node Building GNU CC Necessary +@subsubsection Building GNU CC Necessary +@cindex gcc, building +@cindex building gcc + +It should be possible to build the runtime without building @code{cc1} +and other non-Fortran items, but, for now, an easy way to do that +is not yet established. + +@node Missing strtoul +@subsubsection Missing strtoul +@cindex strtoul @cindex _strtoul @cindex undefined reference (_strtoul) @cindex f771, linking error for @cindex linking error for f771 @cindex ld error for f771 @cindex ld can't find _strtoul -On SunOS systems, linking the @code{f771} program produces +@cindex SunOS4 + +On SunOS4 systems, linking the @code{f771} program produces an error message concerning an undefined symbol named @samp{_strtoul}. @@ -217,60 +281,45 @@ that appeared to have conforming ANSI C environments, and it was decided that, lacking resources to more fully investigate the problem, it was better to not punish users of those systems either by requiring them to work around the problem by hand or -by always substituting an incomplete @samp{strtoul()} implementation +by always substituting an incomplete @code{strtoul()} implementation when their systems had a complete, working one. Unfortunately, this meant inconveniencing users of systems not -having @samp{strtoul()}, but they're using obsolete (and generally +having @code{strtoul()}, but they're using obsolete (and generally unsupported) systems anyway. -@item -It'd be helpful if @code{g77}'s @file{Makefile.in} or @file{Make-lang.in} -would create the various @file{stage@var{n}} directories and their -subdirectories, so expert installers wouldn't have to reconfigure -after cleaning up. - -@item -Improvements to the way @code{libf2c} is built could make -building @code{g77} as a cross-compiler easier---for example, -passing and using @samp{LD} and @samp{AR} in the appropriate -ways. - -@cindex patch files -@cindex GBE -@item -@code{g77} currently requires application of a patch file to the gcc compiler -tree. -The necessary patches should be folded in to the mainline gcc distribution. - -Some combinations -of versions of @code{g77} and @code{gcc} might actually @emph{require} no -patches, but the patch files will be provided anyway as long as -there are more changes expected in subsequent releases. -These patch files might contain -unnecessary, but possibly helpful, patches. -As a result, it is possible this issue might never be -resolved, except by eliminating the need for the person -configuring @code{g77} to apply a patch by hand, by going -to a more automated approach (such as configure-time patching). +@node Object File Differences +@subsubsection Object File Differences +@cindex zzz.o +@cindex zzz.c +@cindex object file, differences +@cindex differences between object files +@cindex make compare + +A comparison of object files after building Stage 3 during a +bootstrap build will result in @file{gcc/f/zzz.o} being flagged +as different from the Stage 2 version. +That is because it +contains a string with an expansion of the @code{__TIME__} macro, +which expands to the current time of day. +It is nothing to worry about, since +@file{gcc/f/zzz.c} doesn't contain any actual code. +It does allow you to override its use of @code{__DATE__} and +@code{__TIME__} by defining macros for the compilation---see the +source code for details. -@item -It should be possible to build the runtime without building @code{cc1} -and other non-Fortran items, but, for now, an easy way to do that -is not yet established. +@node Cleanup Kills Stage Directories +@subsubsection Cleanup Kills Stage Directories +@cindex stage directories +@cindex make clean -@cindex GNU C required -@cindex requirements, GNU C -@item -Compiling @code{g77} requires GNU C, not just ANSI C. -Fixing this wouldn't -be very hard (just tedious), but the code using GNU extensions to -the C language is expected to be rewritten for 0.6 anyway, -so there are no plans for an interim fix. -@end itemize +It'd be helpful if @code{g77}'s @file{Makefile.in} or @file{Make-lang.in} +would create the various @file{stage@var{n}} directories and their +subdirectories, so developers and expert installers wouldn't have to +reconfigure after cleaning up. @node Cross-compiler Problems @subsection Cross-compiler Problems -@cindex cross-compilation +@cindex cross-compiler, problems @code{g77} has been in alpha testing since September of 1992, and in public beta testing since February of 1995. @@ -312,6 +361,12 @@ For example, it might not know how to handle floating-point constants. @item +Improvements to the way @code{libf2c} is built could make +building @code{g77} as a cross-compiler easier---for example, +passing and using @samp{LD} and @samp{AR} in the appropriate +ways. + +@item There are still some challenges putting together the right run-time libraries (needed by @code{libf2c}) for a target system, depending on the systems involved in the configuration. @@ -319,6 +374,235 @@ system, depending on the systems involved in the configuration. @code{gcc} in particular.) @end itemize +@node Settings +@section Changing Settings Before Building + +Here are some internal @code{g77} settings that can be changed +by editing source files in @file{gcc/f/} before building. + +This information, and perhaps even these settings, represent +stop-gap solutions to problems people doing various ports +of @code{g77} have encountered. +As such, none of the following information is expected to +be pertinent in future versions of @code{g77}. + +@menu +* Larger File Unit Numbers:: Raising @samp{MXUNIT}. +* Always Flush Output:: Synchronizing write errors. +* Maximum Stackable Size:: Large arrays are forced off the stack frame. +* Floating-point Bit Patterns:: Possible programs building cross-compiler. +* Large Initialization:: Large arrays with @code{DATA} initialization. +* Alpha Problems Fixed:: Problems 64-bit systems like Alphas now fixed? +@end menu + +@node Larger File Unit Numbers +@subsection Larger File Unit Numbers +@cindex MXUNIT +@cindex unit numbers +@cindex maximum unit number +@cindex illegal unit number +@cindex increasing maximum unit number + +As distributed, whether as part of @code{f2c} or @code{g77}, +@code{libf2c} accepts file unit numbers only in the range +0 through 99. +For example, a statement such as @samp{WRITE (UNIT=100)} causes +a run-time crash in @code{libf2c}, because the unit number, +100, is out of range. + +If you know that Fortran programs at your installation require +the use of unit numbers higher than 99, you can change the +value of the @samp{MXUNIT} macro, which represents the maximum unit +number, to an appropriately higher value. + +To do this, edit the file @file{f/runtime/libI77/fio.h} in your +@code{g77} source tree, changing the following line: + +@example +#define MXUNIT 100 +@end example + +Change the line so that the value of @samp{MXUNIT} is defined to be +at least one @emph{greater} than the maximum unit number used by +the Fortran programs on your system. + +(For example, a program that does @samp{WRITE (UNIT=255)} would require +@samp{MXUNIT} set to at least 256 to avoid crashing.) + +Then build or rebuild @code{g77} as appropriate. + +@emph{Note:} Changing this macro has @emph{no} effect on other limits +your system might place on the number of files open at the same time. +That is, the macro might allow a program to do @samp{WRITE (UNIT=100)}, +but the library and operating system underlying @code{libf2c} might +disallow it if many other files have already been opened (via @code{OPEN} or +implicitly via @code{READ}, @code{WRITE}, and so on). +Information on how to increase these other limits should be found +in your system's documentation. + +@node Always Flush Output +@subsection Always Flush Output +@cindex ALWAYS_FLUSH +@cindex synchronous write errors +@cindex disk full +@cindex flushing output +@cindex fflush() +@cindex I/O, flushing +@cindex output, flushing +@cindex writes, flushing +@cindex NFS +@cindex network file system + +Some Fortran programs require output +(writes) to be flushed to the operating system (under UNIX, +via the @code{fflush()} library call) so that errors, +such as disk full, are immediately flagged via the relevant +@code{ERR=} and @code{IOSTAT=} mechanism, instead of such +errors being flagged later as subsequent writes occur, forcing +the previously written data to disk, or when the file is +closed. + +Essentially, the difference can be viewed as synchronous error +reporting (immediate flagging of errors during writes) versus +asynchronous, or, more precisely, buffered error reporting +(detection of errors might be delayed). + +@code{libf2c} supports flagging write errors immediately when +it is built with the @samp{ALWAYS_FLUSH} macro defined. +This results in a @code{libf2c} that runs slower, sometimes +quite a bit slower, under certain circumstances---for example, +accessing files via the networked file system NFS---but the +effect can be more reliable, robust file I/O. + +If you know that Fortran programs requiring this level of precision +of error reporting are to be compiled using the +version of @code{g77} you are building, you might wish to +modify the @code{g77} source tree so that the version of +@code{libf2c} is built with the @samp{ALWAYS_FLUSH} macro +defined, enabling this behavior. + +To do this, find this line in @file{f/runtime/configure.in} in +your @code{g77} source tree: + +@example +dnl AC_DEFINE(ALWAYS_FLUSH) +@end example + +Remove the leading @samp{dnl@w{ }}, so the line begins with +@samp{AC_DEFINE(}, and run @code{autoconf} in that file's directory. +(Or, if you don't have @code{autoconf}, you can modify @file{f2c.h.in} +in the same directory to include the line @samp{#define ALWAYS_FLUSH} +after @samp{#define F2C_INCLUDE}.) + +Then build or rebuild @code{g77} as appropriate. + +@node Maximum Stackable Size +@subsection Maximum Stackable Size +@vindex FFECOM_sizeMAXSTACKITEM +@cindex code, stack variables +@cindex maximum stackable size +@cindex stack allocation +@cindex segmentation violation +@code{g77}, on most machines, puts many variables and arrays on the stack +where possible, and can be configured (by changing +@samp{FFECOM_sizeMAXSTACKITEM} in @file{gcc/f/com.c}) to force +smaller-sized entities into static storage (saving +on stack space) or permit larger-sized entities to be put on the +stack (which can improve run-time performance, as it presents +more opportunities for the GBE to optimize the generated code). + +@emph{Note:} Putting more variables and arrays on the stack +might cause problems due to system-dependent limits on stack size. +Also, the value of @samp{FFECOM_sizeMAXSTACKITEM} has no +effect on automatic variables and arrays. +@xref{But-bugs}, for more information. + +@node Floating-point Bit Patterns +@subsection Floating-point Bit Patterns + +@cindex cross-compiler, building +@cindex floating-point bit patterns +@cindex bit patterns +The @code{g77} build will crash if an attempt is made to build +it as a cross-compiler +for a target when @code{g77} cannot reliably determine the bit pattern of +floating-point constants for the target. +Planned improvements for g77-0.6 +will give it the capabilities it needs to not have to crash the build +but rather generate correct code for the target. +(Currently, @code{g77} +would generate bad code under such circumstances if it didn't crash +during the build, e.g. when compiling a source file that does +something like @samp{EQUIVALENCE (I,R)} and @samp{DATA R/9.43578/}.) + +@node Large Initialization +@subsection Initialization of Large Aggregate Areas + +@cindex speed, compiler +@cindex slow compiler +@cindex memory utilization +@cindex large initialization +@cindex aggregate initialization +A warning message is issued when @code{g77} sees code that provides +initial values (e.g. via @code{DATA}) to an aggregate area (@code{COMMON} +or @code{EQUIVALENCE}, or even a large enough array or @code{CHARACTER} +variable) +that is large enough to increase @code{g77}'s compile time by roughly +a factor of 10. + +This size currently is quite small, since @code{g77} +currently has a known bug requiring too much memory +and time to handle such cases. +In @file{gcc/f/data.c}, the macro +@samp{FFEDATA_sizeTOO_BIG_INIT_} is defined +to the minimum size for the warning to appear. +The size is specified in storage units, +which can be bytes, words, or whatever, on a case-by-case basis. + +After changing this macro definition, you must +(of course) rebuild and reinstall @code{g77} for +the change to take effect. + +Note that, as of version 0.5.18, improvements have +reduced the scope of the problem for @emph{sparse} +initialization of large arrays, especially those +with large, contiguous uninitialized areas. +However, the warning is issued at a point prior to +when @code{g77} knows whether the initialization is sparse, +and delaying the warning could mean it is produced +too late to be helpful. + +Therefore, the macro definition should not be adjusted to +reflect sparse cases. +Instead, adjust it to generate the warning when densely +initialized arrays begin to cause responses noticeably slower +than linear performance would suggest. + +@node Alpha Problems Fixed +@subsection Alpha Problems Fixed + +@cindex Alpha, support +@cindex 64-bit systems +@code{g77} used to warn when it was used to compile Fortran code +for a target configuration that is not basically a 32-bit +machine (such as an Alpha, which is a 64-bit machine, especially +if it has a 64-bit operating system running on it). +That was because @code{g77} was known to not work +properly on such configurations. + +As of version 0.5.20, @code{g77} is believed to work well +enough on such systems. +So, the warning is no longer needed or provided. + +However, support for 64-bit systems, especially in +areas such as cross-compilation and handling of +intrinsics, is still incomplete. +The symptoms +are believed to be compile-time diagnostics rather +than the generation of bad code. +It is hoped that version 0.6 will completely support 64-bit +systems. + @node Quick Start @section Quick Start @cindex quick start @@ -345,10 +629,18 @@ already reside in @file{/usr/FSF}, a naming convention used by the author of @code{g77} on his own system: @example -/usr/FSF/gcc-2.7.2.tar.gz -/usr/FSF/g77-0.5.19.tar.gz +/usr/FSF/gcc-2.7.2.2.tar.gz +/usr/FSF/g77-0.5.20.tar.gz @end example +@c (You can use @file{gcc-2.7.2.1.tar.gz} instead, or +@c the equivalent of it obtained by applying the +@c patch distributed as @file{gcc-2.7.2-2.7.2.1.diff.gz} +@c to version 2.7.2 of @code{gcc}, +@c if you remember to make the appropriate adjustments in the +@c instructions below.) + +@cindex SunOS4 Users of the following systems should not blindly follow these quick-start instructions, because of problems their systems have coping with straightforward installation of @@ -356,9 +648,7 @@ systems have coping with straightforward installation of @itemize @bullet @item -SunOS -@item -Alpha +SunOS4 @end itemize Instead, see @ref{Complete Installation}, for detailed information @@ -381,49 +671,49 @@ These explanations follow this list of steps. @example sh[ 1]# @kbd{cd /usr/src} @set source-dir 1 -sh[ 2]# @kbd{gunzip -c < /usr/FSF/gcc-2.7.2.tar.gz | tar xf -} -@set unpack-gcc 2 +sh[ 2]# @kbd{gunzip -c < /usr/FSF/gcc-2.7.2.2.tar.gz | tar xf -} [Might say "Broken pipe"...that is normal on some systems.] -sh[ 3]# @kbd{gunzip -c < /usr/FSF/g77-0.5.19.tar.gz | tar xf -} -@set unpack-g77 3 +@set unpack-gcc 2 +sh[ 3]# @kbd{gunzip -c < /usr/FSF/g77-0.5.20.tar.gz | tar xf -} ["Broken pipe" again possible.] -sh[ 4]# @kbd{ln -s gcc-2.7.2 gcc} +@set unpack-g77 3 +sh[ 4]# @kbd{ln -s gcc-2.7.2.2 gcc} @set link-gcc 4 -sh[ 5]# @kbd{ln -s g77-0.5.19 g77} +sh[ 5]# @kbd{ln -s g77-0.5.20 g77} @set link-g77 5 sh[ 6]# @kbd{mv -i g77/* gcc} -@set merge-g77 6 [No questions should be asked by mv here; or, you made a mistake.] -sh[ 7]# @kbd{patch -p1 -V t -d gcc-2.7.2 < gcc-2.7.2/f/gbe/2.7.2.diff} -@set apply-patch 7 +@set merge-g77 6 +sh[ 7]# @kbd{patch -p1 -V t -d gcc < gcc/f/gbe/2.7.2.2.diff} [Unless patch complains about rejected patches, this step worked.] +@set apply-patch 7 sh[ 8]# @kbd{cd gcc} sh[ 9]# @kbd{touch f77-install-ok} -@set f77-install-ok 9 [Do not do the above if your system already has an f77 command, unless you've checked that overwriting it is okay.] +@set f77-install-ok 9 sh[10]# @kbd{touch f2c-install-ok} -@set f2c-install-ok 10 [Do not do the above if your system already has an f2c command, unless you've checked that overwriting it is okay. Else, @kbd{touch f2c-exists-ok}.] +@set f2c-install-ok 10 sh[11]# @kbd{./configure --prefix=/usr} -@set configure-gcc 11 [Do not do the above if gcc is not installed in /usr/bin. You might need a different @kbd{--prefix=@dots{}}, as described below.] +@set configure-gcc 11 sh[12]# @kbd{make bootstrap} -@set build-gcc 12 [This takes a long time, and is where most problems occur.] +@set build-gcc 12 sh[13]# @kbd{rm -fr stage1} @set rm-stage1 13 sh[14]# @kbd{make -k install} -@set install-g77 14 [The actual installation.] +@set install-g77 14 sh[15]# @kbd{g77 -v} -@set show-version 15 [Verify that g77 is installed, obtain version info.] +@set show-version 15 sh[16]# @set end-procedure 16 @end example @@ -443,26 +733,37 @@ By convention, this manual assumes @file{/usr/src}. It might be helpful if other users on your system knew where to look for the source code for the installed version of @code{g77} and @code{gcc} in any case. -@c -@c @item Step @value{unpack-gcc}: @kbd{gunzip -d @dots{}} -@c Some systems have a version of @code{tar} that support -@c uncompressing @code{gzip} files. -@c -@c @item Step @value{unpack-g77}: @kbd{gunzip -d < /usr/FSF/g77-0.5.19.tar.gz | tar xf -} -@item Step @value{link-gcc}: @kbd{ln -s gcc-2.7.2 gcc} -@item Step @value{link-g77}: @kbd{ln -s g77-0.5.19 g77} +@c @item Step @value{unpack-gcc}: @kbd{gunzip -d @dots{}} +@c Here, you might wish to use @file{gcc-2.7.2.1.tar.gz} +@c instead, or apply @file{gcc-2.7.2-2.7.2.1.diff.gz} to achieve +@c similar results. + +@item Step @value{unpack-g77}: @kbd{gunzip -d < /usr/FSF/g77-0.5.20.tar.gz | tar xf -} +It is not always necessary to obtain the latest version of +@code{g77} as a complete @file{.tar.gz} file if you have +a complete, earlier distribution of @code{g77}. +If appropriate, you can unpack that earlier +version of @code{g77}, and then apply the appropriate patches +to achieve the same result---a source tree containing version +0.5.20 of @code{g77}. + +@item Step @value{link-gcc}: @kbd{ln -s gcc-2.7.2.2 gcc} +@item Step @value{link-g77}: @kbd{ln -s g77-0.5.20 g77} These commands mainly help reduce typing, and help reduce visual clutter in examples in this manual showing what to type to install @code{g77}. +@c Of course, if appropriate, @kbd{ln -s gcc-2.7.2.1 gcc} or +@c similar. + @xref{Unpacking}, for information on using distributions of @code{g77} made by organizations other than the FSF. @item Step @value{merge-g77}: @kbd{mv -i g77/* gcc} After doing this, you can, if you like, type -@samp{rm g77} and @samp{rmdir g77-0.5.19} to remove +@samp{rm g77} and @samp{rmdir g77-0.5.20} to remove the empty directory and the symbol link to it. But, it might be helpful to leave them around as quick reminders of which version(s) of @code{g77} are @@ -473,6 +774,8 @@ on the contents of the @file{g77} directory (as merged into the @file{gcc} directory). @item Step @value{apply-patch}: @kbd{patch -p1 @dots{}} +@c (Or `@kbd{@dots{} < gcc/f/gbe/2.7.2.1.diff}', if appropriate.) +@c This can produce a wide variety of printed output, from @samp{Hmm, I can't seem to find a patch in there anywhere...} to long lists of messages indicated that patches are @@ -524,7 +827,7 @@ Otherwise, installing @code{g77} so that it does not fully replace the existing installation of @code{gcc} is likely to result in the inability to compile Fortran programs. -@xref{Where to Install,,Where in the World Does Fortran (and GNU C) Go?}, +@xref{Where to Install,,Where in the World Does Fortran (and GNU CC) Go?}, for more information on determining where to install @code{g77}. @xref{Configuring gcc}, for more information on the configuration process triggered by invoking the @file{./configure} @@ -554,8 +857,53 @@ make -k install install-libf77 install-f2c-all @xref{Updating Documentation,,Updating Your Info Directory}, for information on entering this manual into your system's list of texinfo manuals. -@c -@c @item Step @value{show-version}: @kbd{g77 -v} + +@item Step @value{show-version}: @kbd{g77 -v} +If this command prints approximately 25 lines of output, +including the GNU Fortran Front End version number (which +should be the same as the version number for the version +of @code{g77} you just built and installed) and the +version numbers for the three parts of the @code{libf2c} +library (@code{libF77}, @code{libI77}, @code{libU77}), and +those version numbers are all in agreement, then there is +a high likelihood that the installation has been successfully +completed. + +You might consider doing further testing. +For example, log in as a non-privileged user, then create +a small Fortran program, such as: + +@example + PROGRAM SMTEST + DO 10 I=1, 10 + PRINT *, 'Hello World #', I +10 CONTINUE + END +@end example + +Compile, link, and run the above program, and, assuming you named +the source file @file{smtest.f}, the session should look like this: + +@example +sh# @kbd{g77 -o smtest smtest.f} +sh# @kbd{./smtest} + Hello World # 1 + Hello World # 2 + Hello World # 3 + Hello World # 4 + Hello World # 5 + Hello World # 6 + Hello World # 7 + Hello World # 8 + Hello World # 9 + Hello World # 10 +sh# +@end example + +After proper installation, you don't +need to keep your gcc and g77 source and build directories +around anymore. +Removing them can free up a lot of disk space. @end table @node Complete Installation @@ -614,10 +962,10 @@ and @code{g77} is: @example sh# @kbd{cd /usr/src} -sh# @kbd{gunzip -d < /usr/FSF/gcc-2.7.2.tar.gz | tar xf -} -sh# @kbd{gunzip -d < /usr/FSF/g77-0.5.19.tar.gz | tar xf -} -sh# @kbd{ln -s gcc-2.7.2 gcc} -sh# @kbd{ln -s g77-0.5.19 g77} +sh# @kbd{gunzip -d < /usr/FSF/gcc-2.7.2.2.tar.gz | tar xf -} +sh# @kbd{gunzip -d < /usr/FSF/g77-0.5.20.tar.gz | tar xf -} +sh# @kbd{ln -s gcc-2.7.2.2 gcc} +sh# @kbd{ln -s g77-0.5.20 g77} sh# @kbd{mv -i g77/* gcc} @end example @@ -642,7 +990,7 @@ g77/f All three entries should be moved (or copied) into a @code{gcc} source tree (typically named after its version number and -as it appears in the FSF distributions---e.g. @file{gcc-2.7.2}). +as it appears in the FSF distributions---e.g. @file{gcc-2.7.2.2}). @file{g77/f} is the subdirectory containing all of the code, documentation, and other information that is specific @@ -709,7 +1057,7 @@ The format is, generally, @var{major}.@var{minor}.@var{patch}, with each field being a decimal number. (You can safely ignore -leading zeros; for example, 1.5.3 is the same as 1.5.03.) +leading zeros; for example, 1.5.3 is the same as 1.5.03.)@ The @var{major} field only increases with time. The other two fields are reset to 0 when the field to their left is incremented; otherwise, they, too, only @@ -842,7 +1190,7 @@ When you enable installation of @code{f77}, either a link to or a direct copy of the @code{g77} command is made. Similarly, @file{f77.1} is installed as a man page. -(The @samp{uninstall} target in the @file{gcc/Makefile} also tests +(The @code{uninstall} target in the @file{gcc/Makefile} also tests this macro and file, when invoked, to determine whether to delete the installed copies of @code{f77} and @file{f77.1}.) @@ -927,7 +1275,7 @@ or edit @file{gcc/f/Make-lang.in} and change the definition of the @node Patching GNU Fortran @subsection Patching GNU Fortran -If you're using a SunOS system, you'll need to make the following +If you're using a SunOS4 system, you'll need to make the following change to @file{gcc/f/proj.h}: edit the line reading @example @@ -938,21 +1286,21 @@ change to @file{gcc/f/proj.h}: edit the line reading by replacing the @samp{1} with @samp{0}. Or, you can avoid editing the source by adding @example -CFLAGS='-DFFEPROJ_STRTOUL=0 -g' +CFLAGS='-DFFEPROJ_STRTOUL=0 -g -O' @end example to the command line for @code{make} when you invoke it. (@samp{-g} is the default for @samp{CFLAGS}.) -This causes a minimal version of @samp{strtoul()} provided +This causes a minimal version of @code{strtoul()} provided as part of the @code{g77} distribution to be compiled and linked into whatever @code{g77} programs need it, since -some systems (like SunOS) do not provide this function -in their system libraries. +some systems (like SunOS4 with only the bundled compiler and its +runtime) do not provide this function in their system libraries. -Similarly, a minimal version of @samp{bsearch()} is available +Similarly, a minimal version of @code{bsearch()} is available and can be enabled by editing a line similar to the one -for @samp{strtoul()} above in @file{gcc/f/proj.h}, if -your system libraries lack @samp{bsearch()}. +for @code{strtoul()} above in @file{gcc/f/proj.h}, if +your system libraries lack @code{bsearch()}. The method of overriding @samp{X_CFLAGS} may also be used. These are not problems with @code{g77}, which requires an @@ -963,11 +1311,11 @@ of @code{gcc} to provide one to all @code{gcc}-based compilers in future @code{gcc} distributions. @xref{Problems Installing}, for more information on -why @samp{strtoul()} comes up missing and on approaches +why @code{strtoul()} comes up missing and on approaches to dealing with this problem that have already been tried. @node Where to Install -@subsection Where in the World Does Fortran (and GNU C) Go? +@subsection Where in the World Does Fortran (and GNU CC) Go? Before configuring, you should make sure you know where you want the @code{g77} and @code{gcc} @@ -987,7 +1335,7 @@ version of @code{gcc} on the system. Sometimes people make the mistake of installing @code{gcc} as @file{/usr/local/bin/gcc}, leaving an older, non-Fortran-aware version in @file{/usr/bin/gcc}. -(Or, the opposite happens.) +(Or, the opposite happens.)@ This can result in @code{g77} being unable to compile Fortran source files, because when it calls on @code{gcc} to do the actual compilation, @code{gcc} complains that it does not @@ -1079,9 +1427,9 @@ has been configured. If it does not, there is a problem. @emph{Note:} Configuring with the @samp{--srcdir} argument is known -to work with GNU @samp{make}, but it is not known to work with -other variants of @samp{make}. -Irix5.2 and SunOS4.1 versions of @samp{make} definitely +to work with GNU @code{make}, but it is not known to work with +other variants of @code{make}. +Irix5.2 and SunOS4.1 versions of @code{make} definitely won't work outside the source directory at present. @code{g77}'s portion of the @file{configure} script issues a warning message @@ -1180,21 +1528,14 @@ To save some disk space during installation, after Stage 2 is built, you can type @samp{rm -fr stage1} to remove the binaries built during Stage 1. -@pindex zzz.o -@pindex zzz.c -@emph{Note:} If you do build Stage 3 -and you compare the object files produced by various stages, -the file @file{gcc/f/zzz.o} @strong{will} be different. -That is because it -contains a string with an expansion of the @samp{__TIME__} macro, -which expands to the current time of day. -It is nothing to worry about, since -@file{gcc/f/zzz.c} doesn't contain any actual code. -It does allow you to override its use of @samp{__DATE__} and -@samp{__TIME__} by defining macros for the compilation---see the -source code for details. +@emph{Note:} @xref{Object File Differences}, for information on +expected differences in object files produced during Stage 2 and +Stage 3 of a bootstrap build. +These differences will be encountered as a result of using +the @samp{make compare} or similar command sequence recommended +by the GNU CC installation documentation. -@xref{Installation,,Installing GNU CC,gcc,Using and Porting GNU CC}, +Also, @xref{Installation,,Installing GNU CC,gcc,Using and Porting GNU CC}, for important information on building @code{gcc} that is not described in this @code{g77} manual. For example, explanations of diagnostic messages @@ -1265,43 +1606,51 @@ printed by them when they work: @example sh# @kbd{cd /usr/src/gcc} sh# @kbd{./g77 --driver=./xgcc -B./ -v} - ./xgcc -B./ -v -fnull-version -o /tmp/gfa03648 @dots{} +g77 version 0.5.20 + ./xgcc -B./ -v -fnull-version -o /tmp/gfa18047 @dots{} Reading specs from ./specs -gcc version 2.7.1 +gcc version 2.7.2.2.f.2 ./cpp -lang-c -v -isystem ./include -undef @dots{} -GNU CPP version 2.7.1 (80386, BSD syntax) +GNU CPP version 2.7.2.2.f.2 (Linux/Alpha) #include "..." search starts here: #include <...> search starts here: ./include - /usr/include - /usr/i486-unknown-linuxaout/include - /usr/lib/gcc-lib/i486-unknown-linuxaout/2.7.1/include + /usr/local/include + /usr/alpha-unknown-linux/include + /usr/lib/gcc-lib/alpha-unknown-linux/2.7.2.2.f.2/include /usr/include End of search list. - ./f771 /tmp/cca03648.i -quiet -dumpbase null.F -version @dots{} -GNU F77 version 2.7.1 (80386, BSD syntax) compiled @dots{} -GNU Fortran Front End version 0.5.19 compiled: @dots{} - as -o /tmp/cca036481.o /tmp/cca03648.s - ld -m i386linux -o /tmp/gfa03648 /usr/lib/crt0.o -L. @dots{} -/usr/lib/crt0.o(.text+0x35): undefined reference to `main' + ./f771 /tmp/cca18048.i -fset-g77-defaults -quiet -dumpbase @dots{} +GNU F77 version 2.7.2.2.f.2 (Linux/Alpha) compiled @dots{} +GNU Fortran Front End version 0.5.20-970224 compiled: @dots{} + as -nocpp -o /tmp/cca180481.o /tmp/cca18048.s + ld -G 8 -O1 -o /tmp/gfa18047 /usr/lib/crt0.o -L. @dots{} +__G77_LIBF77_VERSION__: 0.5.20 +@@(#)LIBF77 VERSION 19960619 +__G77_LIBI77_VERSION__: 0.5.20 +@@(#) LIBI77 VERSION pjw,dmg-mods 19961209 +__G77_LIBU77_VERSION__: 0.5.20 +@@(#) LIBU77 VERSION 19970204 sh# @kbd{./xgcc -B./ -v -o /tmp/delete-me -xc /dev/null -xnone} Reading specs from ./specs -gcc version 2.7.1 +gcc version 2.7.2.2.f.2 ./cpp -lang-c -v -isystem ./include -undef @dots{} -GNU CPP version 2.7.1 (80386, BSD syntax) +GNU CPP version 2.7.2.2.f.2 (Linux/Alpha) #include "..." search starts here: #include <...> search starts here: ./include - /usr/include - /usr/i486-unknown-linuxaout/include - /usr/lib/gcc-lib/i486-unknown-linuxaout/2.7.1/include + /usr/local/include + /usr/alpha-unknown-linux/include + /usr/lib/gcc-lib/alpha-unknown-linux/2.7.2.2.f.2/include /usr/include End of search list. - ./cc1 /tmp/cca03659.i -quiet -dumpbase null.c -version @dots{} -GNU C version 2.7.1 (80386, BSD syntax) compiled @dots{} - as -o /tmp/cca036591.o /tmp/cca03659.s - ld -m i386linux -o /tmp/delete-me /usr/lib/crt0.o -L. @dots{} -/usr/lib/crt0.o(.text+0x35): undefined reference to `main' + ./cc1 /tmp/cca18063.i -quiet -dumpbase null.c -version @dots{} +GNU C version 2.7.2.2.f.2 (Linux/Alpha) compiled @dots{} + as -nocpp -o /tmp/cca180631.o /tmp/cca18063.s + ld -G 8 -O1 -o /tmp/delete-me /usr/lib/crt0.o -L. @dots{} +/usr/lib/crt0.o: In function `__start': +crt0.S:110: undefined reference to `main' +/usr/lib/crt0.o(.lita+0x28): undefined reference to `main' sh# @end example @@ -1311,11 +1660,10 @@ used to indicate such truncations.) The above two commands test whether @code{g77} and @code{gcc}, respectively, are able to compile empty (null) source files, whether invocation of the C preprocessor works, whether libraries -can be linked (even though there is an undefined reference due -to there being no main program unit), and so on. +can be linked, and so on. If the output you get from either of the above two commands -is noticably different, especially if it is shorter or longer +is noticeably different, especially if it is shorter or longer in ways that do not look consistent with the above sample output, you probably should not install @code{gcc} and @code{g77} until you have investigated further. @@ -1381,7 +1729,7 @@ require this alternate command, but they do. Note that using the @samp{-k} option tells @code{make} to continue after some installation problems, like not having @code{makeinfo} installed on your system. -It might not be necessary. +It might not be necessary for your system. @node Updating Documentation @subsection Updating Your Info Directory @@ -1405,17 +1753,25 @@ file in the @code{info} directory on your system (perhaps @end example If the menu in @file{dir} is organized into sections, @code{g77} -probably belongs in a section with a name such as the following: +probably belongs in a section with a name such as one of +the following: @itemize @bullet @item +Fortran Programming + +@item Writing Programs + @item Programming Languages + @item Languages Other Than C + @item Scientific/Engineering Tools + @item GNU Compilers @end itemize @@ -1543,6 +1899,9 @@ not get overwritten. @item info/g77.info* This is the documentation for @code{g77}. +If it is not included, users will have trouble understanding +diagnostics messages and other such things, and will send +you a lot of email asking questions. Please edit this documentation (by editing @file{gcc/f/*.texi} and doing @samp{make doc} from the @file{/usr/src/gcc} directory) @@ -1560,6 +1919,8 @@ easily. @item man/man1/g77.1 This is the short man page for @code{g77}. +It is out of date, but you might as well include it +for people who really like man pages. @item man/man1/f77.1 In installations where @code{f77} is the same as @code{g77}, @@ -1604,129 +1965,9 @@ until you're sure your distribution is widely used and has been well tested. This especially goes for those of you making any changes to the @code{g77} sources to port @code{g77}, e.g. to OS/2. -@samp{fortran@@gnu.ai.mit.edu} has received a fair amount of bug +@email{fortran@@gnu.ai.mit.edu} has received a fair number of bug reports that turned out to be problems with other peoples' ports and distributions, about which nothing could be done for the user. Once you are quite certain a bug report does not involve your efforts, you can forward it to us. - -@node Settings -@section Changing Settings Before Building - -Here are some internal @code{g77} settings that can be changed -by editing source files in @file{gcc/f/} before building. - -This information, and perhaps even these settings, represent -stop-gap solutions to problems people doing various ports -of @code{g77} have encountered. -As such, none of the following information is expected to -be pertinent in future versions of @code{g77}. - -@menu -* Maximum Stackable Size:: Large arrays are forced off the stack frame. -* Floating-point Bit Patterns:: Possible programs building cross-compiler. -* Large Initialization:: Large arrays with @samp{DATA} initialization. -* Alpha Problems:: Problems with 64-bit systems like Alphas. -@end menu - -@node Maximum Stackable Size -@subsection Maximum Stackable Size - -@vindex FFECOM_sizeMAXSTACKITEM -@cindex code, stack variables -@cindex maximum stackable size -@cindex stack allocation -@cindex segmentation violation -@code{g77}, on most machines, puts many variables and arrays on the stack -where possible, and can be configured (by changing -@samp{FFECOM_sizeMAXSTACKITEM} in @file{gcc/f/com.c}) to force -smaller-sized entities into static storage (saving -on stack space) or permit larger-sized entities to be put on the -stack (which can improve run-time performance, as it presents -more opportunities for the GBE to optimize the generated code). - -@emph{Note:} Putting more variables and arrays on the stack -might cause problems due to system-dependent limits on stack size. -Also, the value of @samp{FFECOM_sizeMAXSTACKITEM} has no -effect on automatic variables and arrays. -@xref{But-bugs}, for more information. - -@node Floating-point Bit Patterns -@subsection Floating-point Bit Patterns - -@cindex cross-compiler, building -@cindex floating-point bit patterns -@cindex bit patterns -The @code{g77} build will crash if an attempt is made to build -it as a cross-compiler -for a target when @code{g77} cannot reliably determine the bit pattern of -floating-point constants for the target. -Planned improvements for g77-0.6 -will give it the capabilities it needs to not have to crash the build -but rather generate correct code for the target. -(Currently, @code{g77} -would generate bad code under such circumstances if it didn't crash -during the build, e.g. when compiling a source file that does -something like @samp{EQUIVALENCE (I,R)} and @samp{DATA R/9.43578/}.) - -@node Large Initialization -@subsection Initialization of Large Aggregate Areas - -@cindex speed, compiler -@cindex slow compiler -@cindex memory utilization -@cindex large initialization -@cindex aggregate initialization -A warning message is issued when @code{g77} sees code that provides -initial values (e.g. via @samp{DATA}) to an aggregate area (@samp{COMMON} -or @samp{EQUIVALENCE}, or even a large enough array or @samp{CHARACTER} -variable) -that is large enough to increase @code{g77}'s compile time by roughly -a factor of 10. - -This size currently is quite small, since @code{g77} -currently has a known bug requiring too much memory -and time to handle such cases. -In @file{gcc/f/data.c}, the macro -@samp{FFEDATA_sizeTOO_BIG_INIT_} is defined -to the minimum size for the warning to appear. -The size is specified in storage units, -which can be bytes, words, or whatever, on a case-by-case basis. - -After changing this macro definition, you must -(of course) rebuild and reinstall @code{g77} for -the change to take effect. - -Note that, as of version 0.5.18, improvements have -reduced the scope of the problem for @emph{sparse} -initialization of large arrays, especially those -with large, contiguous uninitialized areas. -However, the warning is issued at a point prior to -when @code{g77} knows whether the initialization is sparse, -and delaying the warning could mean it is produced -too late to be helpful. - -Therefore, the macro definition should not be adjusted to -reflect sparse cases. -Instead, adjust it to generate the warning when densely -initialized arrays begin to cause responses noticably slower -than linear performance would suggest. - -@node Alpha Problems -@subsection Alpha Problems - -@cindex Alpha, bugs -@cindex 64-bit systems -@code{g77} might warn when it is used to compile Fortran code -for a target configuration that is not basically a 32-bit -machine (such as an Alpha, which is a 64-bit machine, especially -if it has a 64-bit operating system running on it). -This is because @code{g77} is known to not work -properly on such configurations. -This is expected to be completely fixed -at 0.6, at which point the warning would be dropped. - -(Version 0.5.20 is expected to solve most of these -problems, though, as of this writing, work is still -progressing in this area.) diff --git a/gnu/usr.bin/gcc/f/intdoc.c b/gnu/usr.bin/gcc/f/intdoc.c new file mode 100644 index 00000000000..478f3e0779e --- /dev/null +++ b/gnu/usr.bin/gcc/f/intdoc.c @@ -0,0 +1,1248 @@ +/* intdoc.c + Copyright (C) 1997 Free Software Foundation, Inc. + Contributed by James Craig Burley (burley@gnu.ai.mit.edu). + +This file is part of GNU Fortran. + +GNU Fortran is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Fortran is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Fortran; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ + +#include "proj.h" +#define FFEINTRIN_DOC 1 +#include "intrin.h" + +char *family_name (ffeintrinFamily family); +static void dumpif (ffeintrinFamily fam); +static void dumpendif (void); +static void dumpclearif (void); +static void dumpem (void); +static void dumpgen (int menu, char *name, char *name_uc, + ffeintrinGen gen); +static void dumpspec (int menu, char *name, char *name_uc, + ffeintrinSpec spec); +static void dumpimp (int menu, char *name, char *name_uc, + size_t genno, ffeintrinFamily family, ffeintrinImp imp); +static char *argument_info_ptr (ffeintrinImp imp, int argno); +static char *argument_info_string (ffeintrinImp imp, int argno); +static char *argument_name_ptr (ffeintrinImp imp, int argno); +static char *argument_name_string (ffeintrinImp imp, int argno); +#if 0 +static char *elaborate_if_complex (ffeintrinImp imp, int argno); +static char *elaborate_if_maybe_complex (ffeintrinImp imp, int argno); +static char *elaborate_if_real (ffeintrinImp imp, int argno); +#endif +static void print_type_string (char *c); + +int +main (int argc, char **argv __attribute__ ((unused))) +{ + if (argc != 1) + { + fprintf (stderr, "\ +Usage: intdoc > intdoc.texi + Collects and dumps documentation on g77 intrinsics + to the file named intdoc.texi.\n"); + exit (1); + } + + dumpem (); + return 0; +} + +struct _ffeintrin_name_ + { + char *name_uc; + char *name_lc; + char *name_ic; + ffeintrinGen generic; + ffeintrinSpec specific; + }; + +struct _ffeintrin_gen_ + { + char *name; /* Name as seen in program. */ + ffeintrinSpec specs[2]; + }; + +struct _ffeintrin_spec_ + { + char *name; /* Uppercase name as seen in source code, + lowercase if no source name, "none" if no + name at all (NONE case). */ + bool is_actualarg; /* Ok to pass as actual arg if -pedantic. */ + ffeintrinFamily family; + ffeintrinImp implementation; + }; + +struct _ffeintrin_imp_ + { + char *name; /* Name of implementation. */ + ffeintrinImp cg_imp; /* Unique code-generation code. */ +#if 0 /* FFECOM_targetCURRENT == FFECOM_targetGCC */ + ffecomGfrt gfrt; /* gfrt index in library. */ +#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */ + char *control; + }; + +static struct _ffeintrin_name_ names[] = { +#define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC) \ + { UPPER, LOWER, MIXED, FFEINTRIN_ ## GEN, FFEINTRIN_ ## SPEC }, +#define DEFGEN(CODE,NAME,SPEC1,SPEC2) +#define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP) +#define DEFIMP(CODE,NAME,GFRT,CONTROL) +#define DEFIMQ(CODE,NAME,GFRT,CONTROL,CGIMP) +#include "intrin.def" +#undef DEFNAME +#undef DEFGEN +#undef DEFSPEC +#undef DEFIMP +#undef DEFIMQ +}; + +static struct _ffeintrin_gen_ gens[] = { +#define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC) +#define DEFGEN(CODE,NAME,SPEC1,SPEC2) \ + { NAME, { SPEC1, SPEC2, }, }, +#define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP) +#define DEFIMP(CODE,NAME,GFRT,CONTROL) +#define DEFIMQ(CODE,NAME,GFRT,CONTROL,CGIMP) +#include "intrin.def" +#undef DEFNAME +#undef DEFGEN +#undef DEFSPEC +#undef DEFIMP +#undef DEFIMQ +}; + +static struct _ffeintrin_imp_ imps[] = { +#define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC) +#define DEFGEN(CODE,NAME,SPEC1,SPEC2) +#define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP) +#if 0 /* FFECOM_targetCURRENT == FFECOM_targetGCC */ +#define DEFIMP(CODE,NAME,GFRT,CONTROL) \ + { NAME, FFEINTRIN_imp ## CODE, FFECOM_gfrt ## GFRT, CONTROL }, +#define DEFIMQ(CODE,NAME,GFRT,CONTROL,CGIMP) \ + { NAME, FFEINTRIN_imp ## CGIMP, FFECOM_gfrt ## GFRT, CONTROL }, +#elif 1 /* FFECOM_targetCURRENT == FFECOM_targetFFE */ +#define DEFIMP(CODE,NAME,GFRT,CONTROL) \ + { NAME, FFEINTRIN_imp ## CODE, CONTROL }, +#define DEFIMQ(CODE,NAME,GFRT,CONTROL,CGIMP) \ + { NAME, FFEINTRIN_imp ## CGIMP, CONTROL }, +#else +#error +#endif +#include "intrin.def" +#undef DEFNAME +#undef DEFGEN +#undef DEFSPEC +#undef DEFIMP +#undef DEFIMQ +}; + +static struct _ffeintrin_spec_ specs[] = { +#define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC) +#define DEFGEN(CODE,NAME,SPEC1,SPEC2) +#define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP) \ + { NAME, CALLABLE, FAMILY, IMP, }, +#define DEFIMP(CODE,NAME,GFRT,CONTROL) +#define DEFIMQ(CODE,NAME,GFRT,CONTROL,CGIMP) +#include "intrin.def" +#undef DEFGEN +#undef DEFSPEC +#undef DEFIMP +#undef DEFIMQ +}; + +static char *descriptions[FFEINTRIN_imp] = { +#define DEFDOC(IMP,SUMMARY,DESCRIPTION) [FFEINTRIN_imp ## IMP] DESCRIPTION, +#include "intdoc.h" +#undef DEFDOC +}; + +static char *summaries[FFEINTRIN_imp] = { +#define DEFDOC(IMP,SUMMARY,DESCRIPTION) [FFEINTRIN_imp ## IMP] SUMMARY, +#include "intdoc.h" +#undef DEFDOC +}; + +char * +family_name (ffeintrinFamily family) +{ + switch (family) + { + case FFEINTRIN_familyF77: + return "familyF77"; + + case FFEINTRIN_familyASC: + return "familyASC"; + + case FFEINTRIN_familyMIL: + return "familyMIL"; + + case FFEINTRIN_familyGNU: + return "familyGNU"; + + case FFEINTRIN_familyF90: + return "familyF90"; + + case FFEINTRIN_familyVXT: + return "familyVXT"; + + case FFEINTRIN_familyFVZ: + return "familyFVZ"; + + case FFEINTRIN_familyF2C: + return "familyF2C"; + + case FFEINTRIN_familyF2U: + return "familyF2U"; + + default: + assert ("bad family" == NULL); + return "??"; + } +} + +static int in_ifset = 0; +static ffeintrinFamily latest_family = FFEINTRIN_familyNONE; + +static void +dumpif (ffeintrinFamily fam) +{ + assert (fam != FFEINTRIN_familyNONE); + if ((in_ifset != 2) + || (fam != latest_family)) + { + if (in_ifset == 2) + printf ("@end ifset\n"); + latest_family = fam; + printf ("@ifset %s\n", family_name (fam)); + } + in_ifset = 1; +} + +static void +dumpendif () +{ + in_ifset = 2; +} + +static void +dumpclearif () +{ + if ((in_ifset == 2) + || (latest_family != FFEINTRIN_familyNONE)) + printf ("@end ifset\n"); + latest_family = FFEINTRIN_familyNONE; + in_ifset = 0; +} + +static void +dumpem () +{ + int i; + + printf ("@menu\n"); + for (i = 0; ((size_t) i) < ARRAY_SIZE (names); ++i) + { + if (names[i].generic != FFEINTRIN_genNONE) + dumpgen (1, names[i].name_ic, names[i].name_uc, + names[i].generic); + if (names[i].specific != FFEINTRIN_specNONE) + dumpspec (1, names[i].name_ic, names[i].name_uc, + names[i].specific); + } + dumpclearif (); + + printf ("@end menu\n\n"); + + for (i = 0; ((size_t) i) < ARRAY_SIZE (names); ++i) + { + if (names[i].generic != FFEINTRIN_genNONE) + dumpgen (0, names[i].name_ic, names[i].name_uc, + names[i].generic); + if (names[i].specific != FFEINTRIN_specNONE) + dumpspec (0, names[i].name_ic, names[i].name_uc, + names[i].specific); + } + dumpclearif (); +} + +static void +dumpgen (int menu, char *name, char *name_uc, ffeintrinGen gen) +{ + size_t i; + + for (i = 0; i < ARRAY_SIZE (gens[gen].specs); ++i) + { + ffeintrinSpec spec; + + if ((spec = gens[gen].specs[i]) == FFEINTRIN_specNONE) + continue; + + if (specs[spec].implementation == FFEINTRIN_impNONE) + continue; + + dumpif (specs[spec].family); + dumpimp (menu, name, name_uc, i, specs[spec].family, specs[spec].implementation); + dumpendif (); + } +} + +static void +dumpspec (int menu, char *name, char *name_uc, ffeintrinSpec spec) +{ + if (specs[spec].implementation == FFEINTRIN_impNONE) + return; + + dumpif (specs[spec].family); + dumpimp (menu, name, name_uc, 0, specs[spec].family, specs[spec].implementation); + dumpendif (); +} + +static void +dumpimp (int menu, char *name, char *name_uc, size_t genno, ffeintrinFamily family, ffeintrinImp imp) +{ + char *c = imps[imp].control; + bool subr = (c[0] == '-'); + char *argc; + char *argi; + int colon = (c[2] == ':') ? 2 : 3; + int argno; + + if (menu) + { + printf ("* %s Intrinsic", + name); + if (genno) + printf (" (Form %s)", imps[imp].name); + printf ("::"); + if (summaries[imp] != NULL) + { +#define INDENT_SUMMARY 24 + int spaces = INDENT_SUMMARY - 14 - strlen (name); + char *c = summaries[imp]; + + if (genno != 0) + spaces -= (8 + strlen (imps[imp].name)); + if (spaces < 1) + spaces = 1; + while (spaces--) + fputc (' ', stdout); + + while (c[0] != '\0') + { + if ((c[0] == '@') + && (c[1] >= '0') + && (c[1] <= '9')) + { + int argno = c[1] - '0'; + + c += 2; + while ((c[0] >= '0') + && (c[0] <= '9')) + { + argno = 10 * argno + (c[0] - '0'); + ++c; + } + assert (c[0] == '@'); + if (argno == 0) + printf ("%s", name); + else if (argno == 99) + { /* Yeah, this is a major kludge. */ + printf ("\n"); + spaces = INDENT_SUMMARY + 1; + while (spaces--) + fputc (' ', stdout); + } + else + printf ("%s", argument_name_string (imp, argno - 1)); + } + else + fputc (c[0], stdout); + ++c; + } + } + printf ("\n"); + return; + } + + printf ("@node %s Intrinsic", name); + if (genno) + printf (" (Form %s)", imps[imp].name); + printf ("\n@subsubsection %s Intrinsic", name); + if (genno) + printf (" (Form %s)", imps[imp].name); + printf ("\n@cindex %s intrinsic\n@cindex intrinsics, %s\n +@noindent +@example +%s%s(", + name, name, (subr ? "CALL " : ""), name); + + fflush (stdout); + + for (argno = 0; ; ++argno) + { + argc = argument_name_ptr (imp, argno); + if (argc == NULL) + break; + if (argno > 0) + printf (", "); + printf ("@var{%s}", argc); + argi = argument_info_string (imp, argno); + if ((argi[0] == '*') + || (argi[0] == 'n') + || (argi[0] == '+') + || (argi[0] == 'p')) + printf ("-1, @var{%s}-2, @dots{}, @var{%s}-n", + argc, argc); + } + + printf (") +@end example\n +"); + + if (!subr) + { + int other_arg; + char *arg_string; + char *arg_info; + + if ((c[colon + 1] >= '0') + && (c[colon + 1] <= '9')) + { + other_arg = c[colon + 1] - '0'; + arg_string = argument_name_string (imp, other_arg); + arg_info = argument_info_string (imp, other_arg); + } + else + { + other_arg = -1; + arg_string = NULL; + arg_info = NULL; + } + + printf ("\ +@noindent +%s: ", name); + print_type_string (c); + printf (" function"); + + if ((c[0] == 'R') + && (c[1] == 'C')) + { + assert (other_arg >= 0); + + if ((arg_info[0] == '?') || (arg_info[0] == '!') || (arg_info[0] == '+') + || (arg_info[0] == '*') || (arg_info[0] == 'n') || (arg_info[0] == 'p')) + ++arg_info; + if ((arg_info[0] == 'F') || (arg_info[0] == 'N')) + printf (". +The exact type is @samp{REAL(KIND=1)} when argument @var{%s} is +any type other than @code{COMPLEX}, or when it is @code{COMPLEX(KIND=1)}. +When @var{%s} is any @code{COMPLEX} type other than @code{COMPLEX(KIND=1)}, +this intrinsic is valid only when used as the argument to +@code{REAL()}, as explained below.\n\n", + arg_string, + arg_string); + else + printf (". +This intrinsic is valid when argument @var{%s} is +@code{COMPLEX(KIND=1)}. +When @var{%s} is any other @code{COMPLEX} type, +this intrinsic is valid only when used as the argument to +@code{REAL()}, as explained below.\n\n", + arg_string, + arg_string); + } +#if 0 + else if ((c[0] == 'I') + && (c[1] == 'p')) + printf (", the exact type being wide enough to hold a pointer +on the target system (typically @code{INTEGER(KIND=1)} or @code{INTEGER(KIND=4)}).\n\n"); +#endif + else if ((c[1] == '=') + && (c[colon + 1] >= '0') + && (c[colon + 1] <= '9')) + { + assert (other_arg >= 0); + + if ((arg_info[0] == '?') || (arg_info[0] == '!') || (arg_info[0] == '+') + || (arg_info[0] == '*') || (arg_info[0] == 'n') || (arg_info[0] == 'p')) + ++arg_info; + + if (((c[0] == arg_info[0]) + && ((c[0] == 'A') || (c[0] == 'C') || (c[0] == 'I') + || (c[0] == 'L') || (c[0] == 'R'))) + || ((c[0] == 'R') + && (arg_info[0] == 'C')) + || ((c[0] == 'C') + && (arg_info[0] == 'R'))) + printf (", the @samp{KIND=} value of the type being that of argument @var{%s}.\n\n", + arg_string); + else if ((c[0] == 'S') + && ((arg_info[0] == 'C') + || (arg_info[0] == 'F') + || (arg_info[0] == 'N'))) + printf (". +The exact type depends on that of argument @var{%s}---if @var{%s} is +@code{COMPLEX}, this function's type is @code{REAL} +with the same @samp{KIND=} value as the type of @var{%s}. +Otherwise, this function's type is the same as that of @var{%s}.\n\n", + arg_string, arg_string, arg_string, arg_string); + else + printf (", the exact type being that of argument @var{%s}.\n\n", + arg_string); + } + else if ((c[1] == '=') + && (c[colon + 1] == '*')) + printf (", the exact type being the result of cross-promoting the +types of all the arguments.\n\n"); + else if (c[1] == '=') + assert ("?0:?:" == NULL); + else + printf (".\n\n"); + } + + for (argno = 0, argc = &c[colon + 3]; *argc != '\0'; ++argno) + { + char optionality = '\0'; + char extra = '\0'; + char basic; + char kind; + int length; + int elements; + + printf ("\ +@noindent +@var{"); + for (; ; ++argc) + { + if (argc[0] == '=') + break; + printf ("%c", *argc); + } + printf ("}: "); + + ++argc; + if ((*argc == '?') + || (*argc == '!') + || (*argc == '*') + || (*argc == '+') + || (*argc == 'n') + || (*argc == 'p')) + optionality = *(argc++); + basic = *(argc++); + kind = *(argc++); + if (*argc == '[') + { + length = *++argc - '0'; + if (*++argc != ']') + length = 10 * length + (*(argc++) - '0'); + ++argc; + } + else + length = -1; + if (*argc == '(') + { + elements = *++argc - '0'; + if (*++argc != ')') + elements = 10 * elements + (*(argc++) - '0'); + ++argc; + } + else if (*argc == '&') + { + elements = -1; + ++argc; + } + else + elements = 0; + if ((*argc == '&') + || (*argc == 'i') + || (*argc == 'w') + || (*argc == 'x')) + extra = *(argc++); + if (*argc == ',') + ++argc; + + switch (basic) + { + case '-': + switch (kind) + { + case '*': + printf ("Any type"); + break; + + default: + assert ("kind arg" == NULL); + break; + } + break; + + case 'A': + assert ((kind == '1') || (kind == '*')); + printf ("@code{CHARACTER"); + if (length != -1) + printf ("*%d", length); + printf ("}"); + break; + + case 'C': + switch (kind) + { + case '*': + printf ("@code{COMPLEX}"); + break; + + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + printf ("@code{COMPLEX(KIND=%d)}", (kind - '0')); + break; + + case 'A': + printf ("Same @samp{KIND=} value as for @var{%s}", + argument_name_string (imp, 0)); + break; + + default: + assert ("Ca" == NULL); + break; + } + break; + + case 'I': + switch (kind) + { + case '*': + printf ("@code{INTEGER}"); + break; + + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + printf ("@code{INTEGER(KIND=%d)}", (kind - '0')); + break; + + case 'A': + printf ("@code{INTEGER} with same @samp{KIND=} value as for @var{%s}", + argument_name_string (imp, 0)); + break; + + case 'p': + printf ("@code{INTEGER} wide enough to hold a pointer"); + break; + + default: + assert ("Ia" == NULL); + break; + } + break; + + case 'L': + switch (kind) + { + case '*': + printf ("@code{LOGICAL}"); + break; + + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + printf ("@code{LOGICAL(KIND=%d)}", (kind - '0')); + break; + + case 'A': + printf ("@code{LOGICAL} with same @samp{KIND=} value as for @var{%s}", + argument_name_string (imp, 0)); + break; + + default: + assert ("La" == NULL); + break; + } + break; + + case 'R': + switch (kind) + { + case '*': + printf ("@code{REAL}"); + break; + + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + printf ("@code{REAL(KIND=%d)}", (kind - '0')); + break; + + case 'A': + printf ("@code{REAL} with same @samp{KIND=} value as for @var{%s}", + argument_name_string (imp, 0)); + break; + + default: + assert ("Ra" == NULL); + break; + } + break; + + case 'B': + switch (kind) + { + case '*': + printf ("@code{INTEGER} or @code{LOGICAL}"); + break; + + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + printf ("@code{INTEGER(KIND=%d)} or @code{LOGICAL(KIND=%d)}", + (kind - '0'), (kind - '0')); + break; + + case 'A': + printf ("Same type and @samp{KIND=} value as for @var{%s}", + argument_name_string (imp, 0)); + break; + + default: + assert ("Ba" == NULL); + break; + } + break; + + case 'F': + switch (kind) + { + case '*': + printf ("@code{REAL} or @code{COMPLEX}"); + break; + + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + printf ("@code{REAL(KIND=%d)} or @code{COMPLEX(KIND=%d)}", + (kind - '0'), (kind - '0')); + break; + + case 'A': + printf ("Same type as @var{%s}", + argument_name_string (imp, 0)); + break; + + default: + assert ("Fa" == NULL); + break; + } + break; + + case 'N': + switch (kind) + { + case '*': + printf ("@code{INTEGER}, @code{REAL}, or @code{COMPLEX}"); + break; + + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + printf ("@code{INTEGER(KIND=%d)}, @code{REAL(KIND=%d)}, or @code{COMPLEX(KIND=%d)}", + (kind - '0'), (kind - '0'), (kind - '0')); + break; + + default: + assert ("N1" == NULL); + break; + } + break; + + case 'S': + switch (kind) + { + case '*': + printf ("@code{INTEGER} or @code{REAL}"); + break; + + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + printf ("@code{INTEGER(KIND=%d)} or @code{REAL(KIND=%d)}", + (kind - '0'), (kind - '0')); + break; + + case 'A': + printf ("@code{INTEGER} or @code{REAL} with same @samp{KIND=} value as for @var{%s}", + argument_name_string (imp, 0)); + break; + + default: + assert ("Sa" == NULL); + break; + } + break; + + case 'g': + printf ("@samp{*@var{label}}, where @var{label} is the label +of an executable statement"); + break; + + case 's': + printf ("Signal handler (@code{INTEGER FUNCTION} or @code{SUBROUTINE}) +or dummy/global @code{INTEGER(KIND=1)} scalar"); + break; + + default: + assert ("arg type?" == NULL); + break; + } + + switch (optionality) + { + case '\0': + break; + + case '!': + printf ("; OPTIONAL (must be omitted if @var{%s} is @code{COMPLEX})", + argument_name_string (imp, argno-1)); + break; + + case '?': + printf ("; OPTIONAL"); + break; + + case '*': + printf ("; OPTIONAL"); + break; + + case 'n': + case '+': + break; + + case 'p': + printf ("; at least two such arguments must be provided"); + break; + + default: + assert ("optionality!" == NULL); + break; + } + + switch (elements) + { + case -1: + break; + + case 0: + if ((basic != 'g') + && (basic != 's')) + printf ("; scalar"); + break; + + default: + assert (extra != '\0'); + printf ("; DIMENSION(%d)", elements); + break; + } + + switch (extra) + { + case '\0': + if ((basic != 'g') + && (basic != 's')) + printf ("; INTENT(IN)"); + break; + + case 'i': + break; + + case '&': + printf ("; cannot be a constant or expression"); + break; + + case 'w': + printf ("; INTENT(OUT)"); + break; + + case 'x': + printf ("; INTENT(INOUT)"); + break; + } + + printf (".\n\n"); + } + + printf ("\ +@noindent +Intrinsic groups: "); + switch (family) + { + case FFEINTRIN_familyF77: + printf ("(standard FORTRAN 77)."); + break; + + case FFEINTRIN_familyGNU: + printf ("@code{gnu}."); + break; + + case FFEINTRIN_familyASC: + printf ("@code{f2c}, @code{f90}."); + break; + + case FFEINTRIN_familyMIL: + printf ("@code{mil}, @code{f90}, @code{vxt}."); + break; + + case FFEINTRIN_familyF90: + printf ("@code{f90}."); + break; + + case FFEINTRIN_familyVXT: + printf ("@code{vxt}."); + break; + + case FFEINTRIN_familyFVZ: + printf ("@code{f2c}, @code{vxt}."); + break; + + case FFEINTRIN_familyF2C: + printf ("@code{f2c}."); + break; + + case FFEINTRIN_familyF2U: + printf ("@code{unix}."); + break; + + default: + assert ("bad family" == NULL); + printf ("@code{???}."); + break; + } + printf ("\n\n"); + + if (descriptions[imp] != NULL) + { + char *c = descriptions[imp]; + + printf ("\ +@noindent +Description: +\n"); + + while (c[0] != '\0') + { + if ((c[0] == '@') + && (c[1] >= '0') + && (c[1] <= '9')) + { + int argno = c[1] - '0'; + + c += 2; + while ((c[0] >= '0') + && (c[0] <= '9')) + { + argno = 10 * argno + (c[0] - '0'); + ++c; + } + assert (c[0] == '@'); + if (argno == 0) + printf ("%s", name_uc); + else + printf ("%s", argument_name_string (imp, argno - 1)); + } + else + fputc (c[0], stdout); + ++c; + } + + printf ("\n"); + } +} + +static char * +argument_info_ptr (ffeintrinImp imp, int argno) +{ + char *c = imps[imp].control; + static char arginfos[8][32]; + static int argx = 0; + int i; + + if (c[2] == ':') + c += 5; + else + c += 6; + + while (argno--) + { + while ((c[0] != ',') && (c[0] != '\0')) + ++c; + if (c[0] != ',') + break; + ++c; + } + + if (c[0] == '\0') + return NULL; + + for (; (c[0] != '=') && (c[0] != '\0'); ++c) + ; + + assert (c[0] == '='); + + for (i = 0, ++c; (c[0] != ',') && (c[0] != '\0'); ++c, ++i) + arginfos[argx][i] = c[0]; + + arginfos[argx][i] = '\0'; + + c = &arginfos[argx][0]; + ++argx; + if (((size_t) argx) >= ARRAY_SIZE (arginfos)) + argx = 0; + + return c; +} + +static char * +argument_info_string (ffeintrinImp imp, int argno) +{ + char *p; + + p = argument_info_ptr (imp, argno); + assert (p != NULL); + return p; +} + +static char * +argument_name_ptr (ffeintrinImp imp, int argno) +{ + char *c = imps[imp].control; + static char argnames[8][32]; + static int argx = 0; + int i; + + if (c[2] == ':') + c += 5; + else + c += 6; + + while (argno--) + { + while ((c[0] != ',') && (c[0] != '\0')) + ++c; + if (c[0] != ',') + break; + ++c; + } + + if (c[0] == '\0') + return NULL; + + for (i = 0; (c[0] != '=') && (c[0] != '\0'); ++c, ++i) + argnames[argx][i] = c[0]; + + assert (c[0] == '='); + argnames[argx][i] = '\0'; + + c = &argnames[argx][0]; + ++argx; + if (((size_t) argx) >= ARRAY_SIZE (argnames)) + argx = 0; + + return c; +} + +static char * +argument_name_string (ffeintrinImp imp, int argno) +{ + char *p; + + p = argument_name_ptr (imp, argno); + assert (p != NULL); + return p; +} + +static void +print_type_string (char *c) +{ + char basic = c[0]; + char kind = c[1]; + + switch (basic) + { + case 'A': + assert ((kind == '1') || (kind == '=')); + if (c[2] == ':') + printf ("@code{CHARACTER*1}"); + else + { + assert (c[2] == '*'); + printf ("@code{CHARACTER*(*)}"); + } + break; + + case 'C': + switch (kind) + { + case '=': + printf ("@code{COMPLEX}"); + break; + + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + printf ("@code{COMPLEX(KIND=%d)}", (kind - '0')); + break; + + default: + assert ("Ca" == NULL); + break; + } + break; + + case 'I': + switch (kind) + { + case '=': + printf ("@code{INTEGER}"); + break; + + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + printf ("@code{INTEGER(KIND=%d)}", (kind - '0')); + break; + + case 'p': + printf ("@code{INTEGER(KIND=0)}"); + break; + + default: + assert ("Ia" == NULL); + break; + } + break; + + case 'L': + switch (kind) + { + case '=': + printf ("@code{LOGICAL}"); + break; + + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + printf ("@code{LOGICAL(KIND=%d)}", (kind - '0')); + break; + + default: + assert ("La" == NULL); + break; + } + break; + + case 'R': + switch (kind) + { + case '=': + printf ("@code{REAL}"); + break; + + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + printf ("@code{REAL(KIND=%d)}", (kind - '0')); + break; + + case 'C': + printf ("@code{REAL}"); + break; + + default: + assert ("Ra" == NULL); + break; + } + break; + + case 'B': + switch (kind) + { + case '=': + printf ("@code{INTEGER} or @code{LOGICAL}"); + break; + + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + printf ("@code{INTEGER(KIND=%d)} or @code{LOGICAL(KIND=%d)}", + (kind - '0'), (kind - '0')); + break; + + default: + assert ("Ba" == NULL); + break; + } + break; + + case 'F': + switch (kind) + { + case '=': + printf ("@code{REAL} or @code{COMPLEX}"); + break; + + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + printf ("@code{REAL(KIND=%d)} or @code{COMPLEX(KIND=%d)}", + (kind - '0'), (kind - '0')); + break; + + default: + assert ("Fa" == NULL); + break; + } + break; + + case 'N': + switch (kind) + { + case '=': + printf ("@code{INTEGER}, @code{REAL}, or @code{COMPLEX}"); + break; + + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + printf ("@code{INTEGER(KIND=%d)}, @code{REAL(KIND=%d)}, or @code{COMPLEX(KIND=%d)}", + (kind - '0'), (kind - '0'), (kind - '0')); + break; + + default: + assert ("N1" == NULL); + break; + } + break; + + case 'S': + switch (kind) + { + case '=': + printf ("@code{INTEGER} or @code{REAL}"); + break; + + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + printf ("@code{INTEGER(KIND=%d)} or @code{REAL(KIND=%d)}", + (kind - '0'), (kind - '0')); + break; + + default: + assert ("Sa" == NULL); + break; + } + break; + + default: + assert ("arg type?" == NULL); + break; + } +} diff --git a/gnu/usr.bin/gcc/f/intdoc.h b/gnu/usr.bin/gcc/f/intdoc.h new file mode 100644 index 00000000000..aa14419ab62 --- /dev/null +++ b/gnu/usr.bin/gcc/f/intdoc.h @@ -0,0 +1,1297 @@ +/* Copyright (C) 1997 Free Software Foundation, Inc. + * This is part of the G77 manual. + * For copying conditions, see the file g77.texi. */ + +/* This is the file containing the verbage for the + intrinsics. It consists of a data base built up + via DEFDOC macros of the form: + + DEFDOC (IMP, SUMMARY, DESCRIPTION) + + IMP is the implementation keyword used in the intrin module. + SUMMARY is the short summary to go in the "* Menu:" section + of the Info document. DESCRIPTION is the longer description + to go in the documentation itself. + + Note that IMP is leveraged across multiple intrinsic names. + + To make for more accurate and consistent documentation, + the translation made by intdoc.c of the text in SUMMARY + and DESCRIPTION includes the special sequence + + @ARGNO@ + + where ARGNO is a series of digits forming a number that + is substituted by intdoc.c as follows: + + 0 The initial-caps form of the intrinsic name (e.g. Float). + 1-98 The initial-caps form of the ARGNO'th argument. + 99 (SUMMARY only) a newline plus the appropriate # of spaces. + + Hope this info is enough to encourage people to feel free to + add documentation to this file! + +*/ + +DEFDOC (ABS, "Absolute value.", "\ +Returns the absolute value of @var{@1@}. + +If @var{@1@} is type @code{COMPLEX}, the absolute +value is computed as: + +@example +SQRT(REALPART(@var{@1@})**2, IMAGPART(@var{@1@})**2) +@end example + +@noindent +Otherwise, it is computed by negating the @var{@1@} if +it is negative, or returning @var{@1@}. + +@xref{Sign Intrinsic}, for how to explicitly +compute the positive or negative form of the absolute +value of an expression. +") + +DEFDOC (CABS, "Absolute value (archaic).", "\ +Archaic form of @code{ABS()} that is specific +to one type for @var{@1@}. +@xref{Abs Intrinsic}. +") + +DEFDOC (DABS, "Absolute value (archaic).", "\ +Archaic form of @code{ABS()} that is specific +to one type for @var{@1@}. +@xref{Abs Intrinsic}. +") + +DEFDOC (IABS, "Absolute value (archaic).", "\ +Archaic form of @code{ABS()} that is specific +to one type for @var{@1@}. +@xref{Abs Intrinsic}. +") + +DEFDOC (CDABS, "Absolute value (archaic).", "\ +Archaic form of @code{ABS()} that is specific +to one type for @var{@1@}. +@xref{Abs Intrinsic}. +") + +DEFDOC (ACHAR, "ASCII character from code.", "\ +Returns the ASCII character corresponding to the +code specified by @var{@1@}. + +@xref{IAChar Intrinsic}, for the inverse function. + +@xref{Char Intrinsic}, for the function corresponding +to the system's native character set. +") + +DEFDOC (IACHAR, "ASCII code for character.", "\ +Returns the code for the ASCII character in the +first character position of @var{@1@}. + +@xref{AChar Intrinsic}, for the inverse function. + +@xref{IChar Intrinsic}, for the function corresponding +to the system's native character set. +") + +DEFDOC (CHAR, "Character from code.", "\ +Returns the character corresponding to the +code specified by @var{@1@}, using the system's +native character set. + +Because the system's native character set is used, +the correspondence between character and their codes +is not necessarily the same between GNU Fortran +implementations. + +@xref{IChar Intrinsic}, for the inverse function. + +@xref{AChar Intrinsic}, for the function corresponding +to the ASCII character set. +") + +DEFDOC (ICHAR, "Code for character.", "\ +Returns the code for the character in the +first character position of @var{@1@}. + +Because the system's native character set is used, +the correspondence between character and their codes +is not necessarily the same between GNU Fortran +implementations. + +@xref{Char Intrinsic}, for the inverse function. + +@xref{IAChar Intrinsic}, for the function corresponding +to the ASCII character set. +") + +DEFDOC (ACOS, "Arc cosine.", "\ +Returns the arc-cosine (inverse cosine) of @var{@1@} +in radians. + +@xref{Cos Intrinsic}, for the inverse function. +") + +DEFDOC (DACOS, "Arc cosine (archaic).", "\ +Archaic form of @code{ACOS()} that is specific +to one type for @var{@1@}. +@xref{ACos Intrinsic}. +") + +DEFDOC (AIMAG, "Convert/extract imaginary part of complex.", "\ +Returns the (possibly converted) imaginary part of @var{@1@}. + +Use of @code{@0@()} with an argument of a type +other than @code{COMPLEX(KIND=1)} is restricted to the following case: + +@example +REAL(AIMAG(@1@)) +@end example + +@noindent +This expression converts the imaginary part of @1@ to +@code{REAL(KIND=1)}. + +@xref{REAL() and AIMAG() of Complex}, for more information. +") + +DEFDOC (AINT, "Truncate to whole number.", "\ +Returns @var{@1@} with the fractional portion of its +magnitude truncated and its sign preserved. +(Also called ``truncation towards zero''.) + +@xref{ANInt Intrinsic}, for how to round to nearest +whole number. + +@xref{Int Intrinsic}, for how to truncate and then convert +number to @code{INTEGER}. +") + +DEFDOC (DINT, "Truncate to whole number (archaic).", "\ +Archaic form of @code{AINT()} that is specific +to one type for @var{@1@}. +@xref{AInt Intrinsic}. +") + +DEFDOC (INT, "Convert to @code{INTEGER} value truncated@99@to whole number.", "\ +Returns @var{@1@} with the fractional portion of its +magnitude truncated and its sign preserved, converted +to type @code{INTEGER(KIND=1)}. + +If @var{@1@} is type @code{COMPLEX}, its real part is +truncated and converted. + +@xref{NInt Intrinsic}, for how to convert, rounded to nearest +whole number. + +@xref{AInt Intrinsic}, for how to truncate to whole number +without converting. +") + +DEFDOC (IDINT, "Convert to @code{INTEGER} value truncated@99@to whole number (archaic).", "\ +Archaic form of @code{INT()} that is specific +to one type for @var{@1@}. +@xref{Int Intrinsic}. +") + +DEFDOC (ANINT, "Round to nearest whole number.", "\ +Returns @var{@1@} with the fractional portion of its +magnitude eliminated by rounding to the nearest whole +number and with its sign preserved. + +A fractional portion exactly equal to +@samp{.5} is rounded to the whole number that +is larger in magnitude. +(Also called ``Fortran round''.) + +@xref{AInt Intrinsic}, for how to truncate to +whole number. + +@xref{NInt Intrinsic}, for how to round and then convert +number to @code{INTEGER}. +") + +DEFDOC (DNINT, "Round to nearest whole number (archaic).", "\ +Archaic form of @code{ANINT()} that is specific +to one type for @var{@1@}. +@xref{ANInt Intrinsic}. +") + +DEFDOC (NINT, "Convert to @code{INTEGER} value rounded@99@to nearest whole number.", "\ +Returns @var{@1@} with the fractional portion of its +magnitude eliminated by rounding to the nearest whole +number and with its sign preserved, converted +to type @code{INTEGER(KIND=1)}. + +If @var{@1@} is type @code{COMPLEX}, its real part is +rounded and converted. + +A fractional portion exactly equal to +@samp{.5} is rounded to the whole number that +is larger in magnitude. +(Also called ``Fortran round''.) + +@xref{Int Intrinsic}, for how to convert, truncate to +whole number. + +@xref{ANInt Intrinsic}, for how to round to nearest whole number +without converting. +") + +DEFDOC (IDNINT, "Convert to @code{INTEGER} value rounded@99@to nearest whole number (archaic).", "\ +Archaic form of @code{NINT()} that is specific +to one type for @var{@1@}. +@xref{NInt Intrinsic}. +") + +DEFDOC (LOG, "Natural logarithm.", "\ +Returns the natural logarithm of @var{@1@}, which must +be greater than zero or, if type @code{COMPLEX}, must not +be zero. + +@xref{Exp Intrinsic}, for the inverse function. + +@xref{Log10 Intrinsic}, for the base-10 logarithm function. +") + +DEFDOC (ALOG, "Natural logarithm (archaic).", "\ +Archaic form of @code{LOG()} that is specific +to one type for @var{@1@}. +@xref{Log Intrinsic}. +") + +DEFDOC (CLOG, "Natural logarithm (archaic).", "\ +Archaic form of @code{LOG()} that is specific +to one type for @var{@1@}. +@xref{Log Intrinsic}. +") + +DEFDOC (DLOG, "Natural logarithm (archaic).", "\ +Archaic form of @code{LOG()} that is specific +to one type for @var{@1@}. +@xref{Log Intrinsic}. +") + +DEFDOC (CDLOG, "Natural logarithm (archaic).", "\ +Archaic form of @code{LOG()} that is specific +to one type for @var{@1@}. +@xref{Log Intrinsic}. +") + +DEFDOC (LOG10, "Natural logarithm.", "\ +Returns the natural logarithm of @var{@1@}, which must +be greater than zero or, if type @code{COMPLEX}, must not +be zero. + +The inverse function is @samp{10. ** LOG10(@var{@1@})}. + +@xref{Log Intrinsic}, for the natural logarithm function. +") + +DEFDOC (ALOG10, "Natural logarithm (archaic).", "\ +Archaic form of @code{LOG10()} that is specific +to one type for @var{@1@}. +@xref{Log10 Intrinsic}. +") + +DEFDOC (DLOG10, "Natural logarithm (archaic).", "\ +Archaic form of @code{LOG10()} that is specific +to one type for @var{@1@}. +@xref{Log10 Intrinsic}. +") + +DEFDOC (MAX, "Maximum value.", "\ +Returns the argument with the largest value. + +@xref{Min Intrinsic}, for the opposite function. +") + +DEFDOC (AMAX0, "Maximum value (archaic).", "\ +Archaic form of @code{MAX()} that is specific +to one type for @var{@1@} and a different return type. +@xref{Max Intrinsic}. +") + +DEFDOC (AMAX1, "Maximum value (archaic).", "\ +Archaic form of @code{MAX()} that is specific +to one type for @var{@1@}. +@xref{Max Intrinsic}. +") + +DEFDOC (DMAX1, "Maximum value (archaic).", "\ +Archaic form of @code{MAX()} that is specific +to one type for @var{@1@}. +@xref{Max Intrinsic}. +") + +DEFDOC (MAX0, "Maximum value (archaic).", "\ +Archaic form of @code{MAX()} that is specific +to one type for @var{@1@}. +@xref{Max Intrinsic}. +") + +DEFDOC (MAX1, "Maximum value (archaic).", "\ +Archaic form of @code{MAX()} that is specific +to one type for @var{@1@} and a different return type. +@xref{Max Intrinsic}. +") + +DEFDOC (MIN, "Minimum value.", "\ +Returns the argument with the smallest value. + +@xref{Max Intrinsic}, for the opposite function. +") + +DEFDOC (AMIN0, "Minimum value (archaic).", "\ +Archaic form of @code{MIN()} that is specific +to one type for @var{@1@} and a different return type. +@xref{Min Intrinsic}. +") + +DEFDOC (AMIN1, "Minimum value (archaic).", "\ +Archaic form of @code{MIN()} that is specific +to one type for @var{@1@}. +@xref{Min Intrinsic}. +") + +DEFDOC (DMIN1, "Minimum value (archaic).", "\ +Archaic form of @code{MIN()} that is specific +to one type for @var{@1@}. +@xref{Min Intrinsic}. +") + +DEFDOC (MIN0, "Minimum value (archaic).", "\ +Archaic form of @code{MIN()} that is specific +to one type for @var{@1@}. +@xref{Min Intrinsic}. +") + +DEFDOC (MIN1, "Minimum value (archaic).", "\ +Archaic form of @code{MIN()} that is specific +to one type for @var{@1@} and a different return type. +@xref{Min Intrinsic}. +") + +DEFDOC (MOD, "Remainder.", "\ +Returns remainder calculated as: + +@smallexample +@var{@1@} - (INT(@var{@1@} / @var{@2@}) * @var{@2@}) +@end smallexample + +@var{@2@} must not be zero. +") + +DEFDOC (AMOD, "Remainder (archaic).", "\ +Archaic form of @code{MOD()} that is specific +to one type for @var{@1@}. +@xref{Mod Intrinsic}. +") + +DEFDOC (DMOD, "Remainder (archaic).", "\ +Archaic form of @code{MOD()} that is specific +to one type for @var{@1@}. +@xref{Mod Intrinsic}. +") + +DEFDOC (AND, "Boolean AND.", "\ +Returns value resulting from boolean AND of +pair of bits in each of @var{@1@} and @var{@2@}. +") + +DEFDOC (IAND, "Boolean AND.", "\ +Returns value resulting from boolean AND of +pair of bits in each of @var{@1@} and @var{@2@}. +") + +DEFDOC (OR, "Boolean OR.", "\ +Returns value resulting from boolean OR of +pair of bits in each of @var{@1@} and @var{@2@}. +") + +DEFDOC (IOR, "Boolean OR.", "\ +Returns value resulting from boolean OR of +pair of bits in each of @var{@1@} and @var{@2@}. +") + +DEFDOC (XOR, "Boolean XOR.", "\ +Returns value resulting from boolean exclusive-OR of +pair of bits in each of @var{@1@} and @var{@2@}. +") + +DEFDOC (IEOR, "Boolean XOR.", "\ +Returns value resulting from boolean exclusive-OR of +pair of bits in each of @var{@1@} and @var{@2@}. +") + +DEFDOC (NOT, "Boolean NOT.", "\ +Returns value resulting from boolean NOT of each bit +in @var{@1@}. +") + +DEFDOC (ASIN, "Arc sine.", "\ +Returns the arc-sine (inverse sine) of @var{@1@} +in radians. + +@xref{Sin Intrinsic}, for the inverse function. +") + +DEFDOC (DASIN, "Arc sine (archaic).", "\ +Archaic form of @code{ASIN()} that is specific +to one type for @var{@1@}. +@xref{ASin Intrinsic}. +") + +DEFDOC (ATAN, "Arc tangent.", "\ +Returns the arc-tangent (inverse tangent) of @var{@1@} +in radians. + +@xref{Tan Intrinsic}, for the inverse function. +") + +DEFDOC (DATAN, "Arc tangent (archaic).", "\ +Archaic form of @code{ATAN()} that is specific +to one type for @var{@1@}. +@xref{ATan Intrinsic}. +") + +DEFDOC (ATAN2, "Arc tangent.", "\ +Returns the arc-tangent (inverse tangent) of the complex +number (@var{@1@}, @var{@2@}) in radians. + +@xref{Tan Intrinsic}, for the inverse function. +") + +DEFDOC (DATAN2, "Arc tangent (archaic).", "\ +Archaic form of @code{ATAN2()} that is specific +to one type for @var{@1@} and @var{@2@}. +@xref{ATan2 Intrinsic}. +") + +DEFDOC (BIT_SIZE, "Number of bits in argument's type.", "\ +Returns the number of bits (integer precision plus sign bit) +represented by the type for @var{@1@}. + +@xref{BTest Intrinsic}, for how to test the value of a +bit in a variable or array. + +@xref{IBSet Intrinsic}, for how to set a bit in a +variable or array to 1. +") + +DEFDOC (BTEST, "Test bit.", "\ +Returns @code{.TRUE.} if bit @var{@2@} in @var{@1@} is +1, @code{.FALSE.} otherwise. + +(Bit 0 is the low-order bit, adding the value 2**0, or 1, +to the number if set to 1; +bit 1 is the next-higher-order bit, adding 2**1, or 2; +bit 2 adds 2**2, or 4; and so on.) + +@xref{Bit_Size Intrinsic}, for how to obtain the number of bits +in a type. +") + +DEFDOC (CMPLX, "Construct @code{COMPLEX(KIND=1)} value.", "\ +If @var{@1@} is not type @code{COMPLEX}, +constructs a value of type @code{COMPLEX(KIND=1)} from the +real and imaginary values specified by @var{@1@} and +@var{@2@}, respectively. +If @var{@2@} is omitted, @samp{0.} is assumed. + +If @var{@1@} is type @code{COMPLEX}, +converts it to type @code{COMPLEX(KIND=1)}. + +@xref{Complex Intrinsic}, for information on easily constructing +a @code{COMPLEX} value of arbitrary precision from @code{REAL} +arguments. +") + +DEFDOC (CONJG, "Complex conjugate.", "\ +Returns the complex conjugate: + +@example +COMPLEX(REALPART(@var{@1@}), -IMAGPART(@var{@1@})) +@end example +") + +DEFDOC (DCONJG, "Complex conjugate (archaic).", "\ +Archaic form of @code{CONJG()} that is specific +to one type for @var{@1@}. +@xref{ATan2 Intrinsic}. +") + +/* ~~~~~ to do: + COS + COSH + SQRT + DBLE + DIM + ERF + DPROD + SIGN + EXP + FLOAT + IBCLR + IBITS + IBSET + IFIX + INDEX + ISHFT + ISHFTC + LEN + LGE + LONG + SHORT + LSHIFT + RSHIFT + MVBITS + SIN + SINH + SNGL + TAN + TANH +*/ + +DEFDOC (REAL, "Convert value to type @code{REAL(KIND=1)}.", "\ +Converts @var{@1@} to @code{REAL(KIND=1)}. + +Use of @code{@0@()} with a @code{COMPLEX} argument +(other than @code{COMPLEX(KIND=1)}) is restricted to the following case: + +@example +REAL(REAL(@1@)) +@end example + +@noindent +This expression converts the real part of @1@ to +@code{REAL(KIND=1)}. + +@xref{REAL() and AIMAG() of Complex}, for more information. +") + +DEFDOC (IMAGPART, "Extract imaginary part of complex.", "\ +The imaginary part of @var{@1@} is returned, without conversion. + +@emph{Note:} The way to do this in standard Fortran 90 +is @samp{AIMAG(@var{@1@})}. +However, when, for example, @var{@1@} is @code{DOUBLE COMPLEX}, +@samp{AIMAG(@var{@1@})} means something different for some compilers +that are not true Fortran 90 compilers but offer some +extensions standardized by Fortran 90 (such as the +@code{DOUBLE COMPLEX} type, also known as @code{COMPLEX(KIND=2)}). + +The advantage of @code{@0@()} is that, while not necessarily +more or less portable than @code{AIMAG()}, it is more likely to +cause a compiler that doesn't support it to produce a diagnostic +than generate incorrect code. + +@xref{REAL() and AIMAG() of Complex}, for more information. +") + +DEFDOC (COMPLEX, "Build complex value from real and@99@imaginary parts.", "\ +Returns a @code{COMPLEX} value that has @samp{@1@} and @samp{@2@} as its +real and imaginary parts, respectively. + +If @var{@1@} and @var{@2@} are the same type, and that type is not +@code{INTEGER}, no data conversion is performed, and the type of +the resulting value has the same kind value as the types +of @var{@1@} and @var{@2@}. + +If @var{@1@} and @var{@2@} are not the same type, the usual type-promotion +rules are applied to both, converting either or both to the +appropriate @code{REAL} type. +The type of the resulting value has the same kind value as the +type to which both @var{@1@} and @var{@2@} were converted, in this case. + +If @var{@1@} and @var{@2@} are both @code{INTEGER}, they are both converted +to @code{REAL(KIND=1)}, and the result of the @code{@0@()} +invocation is type @code{COMPLEX(KIND=1)}. + +@emph{Note:} The way to do this in standard Fortran 90 +is too hairy to describe here, but it is important to +note that @samp{CMPLX(D1,D2)} returns a @code{COMPLEX(KIND=1)} +result even if @samp{D1} and @samp{D2} are type @code{REAL(KIND=2)}. +Hence the availability of @code{COMPLEX()} in GNU Fortran. +") + +DEFDOC (LOC, "Address of entity in core.", "\ +The @code{LOC()} intrinsic works the +same way as the @code{%LOC()} construct. +@xref{%LOC(),,The @code{%LOC()} Construct}, for +more information. +") + +DEFDOC (REALPART, "Extract real part of complex.", "\ +The real part of @var{@1@} is returned, without conversion. + +@emph{Note:} The way to do this in standard Fortran 90 +is @samp{REAL(@var{@1@})}. +However, when, for example, @var{@1@} is @code{COMPLEX(KIND=2)}, +@samp{REAL(@var{@1@})} means something different for some compilers +that are not true Fortran 90 compilers but offer some +extensions standardized by Fortran 90 (such as the +@code{DOUBLE COMPLEX} type, also known as @code{COMPLEX(KIND=2)}). + +The advantage of @code{@0@()} is that, while not necessarily +more or less portable than @code{REAL()}, it is more likely to +cause a compiler that doesn't support it to produce a diagnostic +than generate incorrect code. + +@xref{REAL() and AIMAG() of Complex}, for more information. +") + +DEFDOC (GETARG, "Obtain command-line argument.", "\ +Sets @var{@2@} to the @var{@1@}-th command-line argument (or to all +blanks if there are fewer than @var{@2@} command-line arguments); +@code{CALL @0@(0, @var{value})} sets @var{value} to the name of the +program (on systems that support this feature). + +@xref{IArgC Intrinsic}, for information on how to get the number +of arguments. +") + +DEFDOC (ABORT, "Abort the program.", "\ +Prints a message and potentially causes a core dump via @code{abort(3)}. +") + +DEFDOC (EXIT, "Terminate the program.", "\ +Exit the program with status @var{@1@} after closing open Fortran +i/o units and otherwise behaving as @code{exit(2)}. If @var{@1@} +is omitted the canonical `success' value will be returned to the +system. +") + +DEFDOC (IARGC, "Obtain count of command-line arguments.", "\ +Returns the number of command-line arguments. + +This count does not include the specification of the program +name itself. +") + +DEFDOC (CTIME, "Convert time to Day Mon dd hh:mm:ss yyyy.", "\ +Converts @var{@1@}, a system time value, such as returned by +@code{TIME()}, to a string of the form @samp{Sat Aug 19 18:13:14 1995}. + +@xref{Time Intrinsic}. +") + +DEFDOC (DATE, "Get current date as dd-Mon-yy.", "\ +Returns @var{@1@} in the form @samp{@var{dd}-@var{mmm}-@var{yy}}, +representing the numeric day of the month @var{dd}, a three-character +abbreviation of the month name @var{mmm} and the last two digits of +the year @var{yy}, e.g.@ @samp{25-Nov-96}. + +This intrinsic is not recommended, due to the year 2000 approaching. +@xref{CTime Intrinsic}, for information on obtaining more digits +for the current (or any) date. +") + +DEFDOC (DTIME, "Get elapsed time since last time.", "\ +Initially, return in seconds the runtime (since the start of the +process' execution) as the function value and the user and system +components of this in @samp{@var{@1@}(1)} and @samp{@var{@1@}(2)} +respectively. +The functions' value is equal to @samp{@var{@1@}(1) + @samp{@1@}(2)}. + +Subsequent invocations of @samp{@0@()} return values accumulated since the +previous invocation. +") + +DEFDOC (ETIME, "Get elapsed time for process.", "\ +Return in seconds the runtime (since the start of the process' +execution) as the function value and the user and system components of +this in @samp{@var{@1@}(1)} and @samp{@var{@1@}(2)} respectively. +The functions' value is equal to @samp{@var{@1@}(1) + @var{@1@}(2)}. +") + +DEFDOC (FDATE, "Get current time as Day Mon dd hh:mm:ss yyyy.", "\ +Returns the current date in the same format as @code{CTIME()}. + +Equivalent to: + +@example +CTIME(TIME()) +@end example + +@xref{CTime Intrinsic}. +") + +DEFDOC (GMTIME, "Convert time to GMT time info.", "\ +Given a system time value @var{@1@}, fills @var{@2@} with values +extracted from it appropriate to the GMT time zone using +@code{gmtime(3)}. + +The array elements are as follows: + +@enumerate +@item +Seconds after the minute, range 0--59 or 0--61 to allow for leap +seconds + +@item +Minutes after the hour, range 0--59 + +@item +Hours past midnight, range 0--23 + +@item +Day of month, range 0--31 + +@item +Number of months since January, range 0--12 + +@item +Number of days since Sunday, range 0--6 + +@item +Years since 1900 + +@item +Days since January 1 + +@item +Daylight savings indicator: positive if daylight savings is in effect, +zero if not, and negative if the information isn't available. +@end enumerate +") + +DEFDOC (LTIME, "Convert time to local time info.", "\ +Given a system time value @var{@1@}, fills @var{@2@} with values +extracted from it appropriate to the GMT time zone using +@code{localtime(3)}. + +The array elements are as follows: + +@enumerate +@item +Seconds after the minute, range 0--59 or 0--61 to allow for leap +seconds + +@item +Minutes after the hour, range 0--59 + +@item +Hours past midnight, range 0--23 + +@item +Day of month, range 0--31 + +@item +Number of months since January, range 0--12 + +@item +Number of days since Sunday, range 0--6 + +@item +Years since 1900 + +@item +Days since January 1 + +@item +Daylight savings indicator: positive if daylight savings is in effect, +zero if not, and negative if the information isn't available. +@end enumerate +") + +DEFDOC (IDATE, "Get local time info.", "\ +Fills @var{@1@} with the numerical values at the current local time +of day, month (in the range 1--12), and year in elements 1, 2, and 3, +respectively. +The year has four significant digits. +") + +DEFDOC (IDATEVXT, "Get local time info (VAX/VMS).", "\ +Returns the numerical values of the current local time. +The date is returned in @var{@1@}, +the month in @var{@2@} (in the range 1--12), +and the year in @var{@3@} (in the range 0--99). + +This intrinsic is not recommended, due to the year 2000 approaching. +@xref{IDate Intrinsic}, for information on obtaining more digits +for the current local date. +") + +DEFDOC (ITIME, "Get local time of day.", "\ +Returns the current local time hour, minutes, and seconds in elements +1, 2, and 3 of @var{@1@}, respectively. +") + +DEFDOC (MCLOCK, "Get number of clock ticks for process.", "\ +Returns the number of clock ticks since the start of the process. +Only defined on systems with @code{clock(3)} (q.v.). +") + +DEFDOC (SECNDS, "Get local time offset since midnight.", "\ +Returns the local time in seconds since midnight minus the value +@var{@1@}. +") + +DEFDOC (SECONDFUNC, "Get CPU time for process in seconds.", "\ +Returns the process' runtime in seconds---the same value as the +UNIX function @code{etime} returns. + +This routine is known from Cray Fortran. +") + +DEFDOC (SECONDSUBR, "Get CPU time for process@99@in seconds.", "\ +Returns the process' runtime in seconds in @var{@1@}---the same value +as the UNIX function @code{etime} returns. + +This routine is known from Cray Fortran. +") + +DEFDOC (SYSTEM_CLOCK, "Get current system clock value.", "\ +Returns in @var{@1@} the current value of the system clock; this is +the value returned by the UNIX function @code{times(2)} +in this implementation, but +isn't in general. +@var{@2@} is the number of clock ticks per second and +@var{@3@} is the maximum value this can take, which isn't very useful +in this implementation since it's just the maximum C @code{unsigned +int} value. +") + +DEFDOC (TIME, "Get current time as time value.", "\ +Returns the current time encoded as an integer in the manner of +the UNIX function @code{time(3)}. +This value is suitable for passing to @code{CTIME}, +@code{GMTIME}, and @code{LTIME}. +") + +#define BES(num,n) "\ +Calculates the Bessel function of the " #num " kind of \ +order " #n ".\n\ +See @code{bessel(3m)}, on whose implementation the \ +function depends.\ +" + +DEFDOC (BESJ0, "Bessel function.", BES (first, 0)) +DEFDOC (BESJ1, "Bessel function.", BES (first, 1)) +DEFDOC (BESJN, "Bessel function.", BES (first, @var{N})) +DEFDOC (BESY0, "Bessel function.", BES (second, 0)) +DEFDOC (BESY1, "Bessel function.", BES (second, 1)) +DEFDOC (BESYN, "Bessel function.", BES (second, @var{N})) + +DEFDOC (ERF, "Error function.", "\ +Returns the error function of @var{@1@}. +See @code{erf(3m)}, which provides the implementation. +") + +DEFDOC (ERFC, "Complementary error function.", "\ +Returns the complementary error function of @var{@1@}: +@code{ERFC(R) = 1 - ERF(R)} (except that the result may be more +accurate than explicitly evaluating that formulae would give). +See @code{erfc(3m)}, which provides the implementation. +") + +DEFDOC (IRAND, "Random number.", "\ +Returns a uniform quasi-random number up to a system-dependent limit. +If @var{@1@} is 0, the next number in sequence is returned; if +@var{@1@} is 1, the generator is restarted by calling the UNIX function +@samp{srand(0)}; if @var{@1@} has any other value, +it is used as a new seed with @code{srand()}. + +@xref{SRand Intrinsic}. + +@emph{Note:} As typically implemented (by the routine of the same +name in the C library), this random number generator is a very poor +one, though the BSD and GNU libraries provide a much better +implementation than the `traditional' one. +On a different system you almost certainly want to use something better. +") + +DEFDOC (RAND, "Random number.", "\ +Returns a uniform quasi-random number between 0 and 1. +If @var{@1@} is 0, the next number in sequence is returned; if +@var{@1@} is 1, the generator is restarted by calling @samp{srand(0)}; +if @var{@1@} has any other value, it is used as a new seed with +@code{srand}. + +@xref{SRand Intrinsic}. + +@emph{Note:} As typically implemented (by the routine of the same +name in the C library), this random number generator is a very poor +one, though the BSD and GNU libraries provide a much better +implementation than the `traditional' one. +On a different system you +almost certainly want to use something better. +") + +DEFDOC (SRAND, "Random seed.", "\ +Reinitialises the generator with the seed in @var{@1@}. +@xref{IRand Intrinsic}. @xref{Rand Intrinsic}. +") + +DEFDOC (ACCESS, "Check file accessibility.", "\ +Checks file @var{@1@} for accessibility in the mode specified by @var{@2@} and +returns 0 if the file is accessible in that mode, otherwise an error +code if the file is inaccessible or @var{@2@} is invalid. See +@code{access(2)}. @var{@2@} may be a concatenation of any of the +following characters: + +@table @samp +@item r +Read permission + +@item w +Write permission + +@item x +Execute permission + +@item @kbd{SPC} +Existence +@end table +") + +DEFDOC (CHDIR, "Change directory.", "\ +Sets the current working directory to be @var{@1@}. +If the @var{@2@} argument is supplied, it contains 0 +on success or an error code otherwise upon return. +See @code{chdir(3)}. +") + +DEFDOC (CHMOD, "Change file modes.", "\ +Changes the access mode of file @var{@1@} according to the +specification @var{@2@}, which is given in the format of +@code{chmod(1)}. +If the @var{Status} argument is supplied, it contains 0 +on success or an error code otherwise upon return. +Note that this currently works +by actually invoking @code{/bin/chmod} (or the @code{chmod} found when +the library was configured) and so may fail in some circumstances and +will, anyway, be slow. +") + +DEFDOC (GETCWD, "Get current working directory.", "\ +Places the current working directory in @var{@1@}. +Returns 0 on +success, otherwise an error code. +") + +DEFDOC (FSTAT, "Get file information.", "\ +Obtains data about the file open on Fortran I/O unit @var{@1@} and +places them in the array @var{@2@}. +The values in this array are +extracted from the @code{stat} structure as returned by +@code{fstat(2)} q.v., as follows: + +@enumerate +@item +File mode + +@item +Inode number + +@item +ID of device containing directory entry for file + +@item +Device id (if relevant) + +@item +Number of links + +@item +Owner's uid + +@item +Owner's gid + +@item +File size (bytes) + +@item +Last access time + +@item +Last modification time + +@item +Last file status change time + +@item +Preferred i/o block size + +@item +Number of blocks allocated +@end enumerate + +Not all these elements are relevant on all systems. +If an element is not relevant, it is returned as 0. + +Returns 0 on success, otherwise an error number. +") + +DEFDOC (LSTAT, "Get file information.", "\ +Obtains data about the given @var{@1@} and places them in the array +@var{@2@}. +If @var{@1@} is a symbolic link it returns data on the +link itself, so the routine is available only on systems that support +symbolic links. +The values in this array are extracted from the +@code{stat} structure as returned by @code{fstat(2)} q.v., as follows: + +@enumerate +@item +File mode + +@item +Inode number + +@item +ID of device containing directory entry for file + +@item +Device id (if relevant) + +@item +Number of links + +@item +Owner's uid + +@item +Owner's gid + +@item +File size (bytes) + +@item +Last access time + +@item +Last modification time + +@item +Last file status change time + +@item +Preferred i/o block size + +@item +Number of blocks allocated +@end enumerate + +Not all these elements are relevant on all systems. +If an element is not relevant, it is returned as 0. + +Returns 0 on success, otherwise an error number. +") + +DEFDOC (STAT, "Get file information.", "\ +Obtains data about the given @var{@1@} and places them in the array +@var{@2@}. +The values in this array are extracted from the +@code{stat} structure as returned by @code{fstat(2)} q.v., as follows: + +@enumerate +@item +File mode + +@item +Inode number + +@item +ID of device containing directory entry for file + +@item +Device id (if relevant) + +@item +Number of links + +@item +Owner's uid + +@item +Owner's gid + +@item +File size (bytes) + +@item +Last access time + +@item +Last modification time + +@item +Last file status change time + +@item +Preferred i/o block size + +@item +Number of blocks allocated +@end enumerate + +Not all these elements are relevant on all systems. +If an element is not relevant, it is returned as 0. + +Returns 0 on success, otherwise an error number. +") + +DEFDOC (LINK, "Make hard link in file system.", "\ +Makes a (hard) link from @var{@1@} to @var{@2@}. +If the +@var{@3@} argument is supplied, it contains 0 on success or an error +code otherwise. +See @code{link(2)}. +") + +DEFDOC (SYMLNK, "Make symbolic link in file system.", "\ +Makes a symbolic link from @var{@1@} to @var{@2@}. +If the +@var{@3@} argument is supplied, it contains 0 on success or an error +code otherwise. +Available only on systems that support symbolic +links (see @code{symlink(2)}). +") + +DEFDOC (RENAME, "Rename file.", "\ +Renames the file @var{@1@} to @var{@2@}. +See @code{rename(2)}. +If the @var{@3@} argument is supplied, it contains 0 on success or an +error code otherwise upon return. +") + +DEFDOC (UMASK, "Set file creation permissions mask.", "\ +Sets the file creation mask to @var{@2@} and returns the old value in +argument @var{@2@} if it is supplied. +See @code{umask(2)}. +") + +DEFDOC (UNLINK, "Unlink file.", "\ +Unlink the file @var{@1@}. +If the @var{@2@} argument is supplied, it +contains 0 on success or an error code otherwise. +See @code{unlink(2)}. +") + +DEFDOC (GERROR, "Get error message for last error.", "\ +Returns the system error message corresponding to the last system +error (C @code{errno}). +") + +DEFDOC (IERRNO, "Get error number for last error.", "\ +Returns the last system error number (corresponding to the C +@code{errno}). +") + +DEFDOC (PERROR, "Print error message for last error.", "\ +Prints (on the C @code{stderr} stream) a newline-terminated error +message corresponding to the last system error. +This is prefixed by @var{@1@}, a colon and a space. +See @code{perror(3)}. +") + +DEFDOC (GETGID, "Get process group id.", "\ +Returns the group id for the current process. +") + +DEFDOC (GETUID, "Get process user id.", "\ +Returns the user id for the current process. +") + +DEFDOC (GETPID, "Get process id.", "\ +Returns the process id for the current process. +") + +DEFDOC (GETENV, "Get environment variable.", "\ +Sets @var{@2@} to the value of environment variable given by the +value of @var{@1@} (@code{$name} in shell terms) or to blanks if +@code{$name} has not been set. +") + +DEFDOC (GETLOG, "Get login name.", "\ +Returns the login name for the process in @var{@1@}. +") + +DEFDOC (HOSTNM, "Get host name.", "\ +Fills @var{@1@} with the system's host name returned by +@code{gethostname(2)}, returning 0 on success or an error code. +This function is not available on all systems. +") + +/* Fixme: stream i/o */ + +DEFDOC (FLUSH, "Flush buffered output.", "\ +Flushes Fortran unit(s) currently open for output. +Without the optional argument, all such units are flushed, +otherwise just the unit specified by @var{@1@}. +") + +DEFDOC (FNUM, "Get file descriptor from Fortran unit number.", "\ +Returns the Unix file descriptor number corresponding to the open +Fortran I/O unit @var{@1@}. +This could be passed to an interface to C I/O routines. +") + +DEFDOC (FSEEK, "Position file (low-level).", "\ +Attempts to move Fortran unit @var{@1@} to the specified +@var{Offset}: absolute offset if @var{@2@}=0; relative to the +current offset if @var{@2@}=1; relative to the end of the file if +@var{@2@}=2. +It branches to label @var{@3@} if @var{@1@} is +not open or if the call otherwise fails. +") + +DEFDOC (FTELL, "Get file position (low-level).", "\ +Returns the current offset of Fortran unit @var{@1@} (or @minus{}1 if +@var{@1@} is not open). +") + +DEFDOC (ISATTY, "Is unit connected to a terminal?", "\ +Returns @code{.TRUE.} if and only if the Fortran I/O unit +specified by @var{@1@} is connected +to a terminal device. +See @code{isatty(3)}. +") + +DEFDOC (TTYNAM, "Get name of terminal device for unit.", "\ +Returns the name of the terminal device open on logical unit +@var{@1@} or a blank string if @var{@1@} is not connected to a +terminal. +") + +DEFDOC (SIGNAL, "Muck with signal handling.", "\ +If @var{@2@} is a an @code{EXTERNAL} routine, arranges for it to be +invoked with a single integer argument (of system-dependent length) +when signal @var{@1@} occurs. +If @var{@1@} is an integer it can be +used to turn off handling of signal @var{@2@} or revert to its default +action. +See @code{signal(2)}. + +Note that @var{@2@} will be called with C conventions, so its value in +Fortran terms is obtained by applying @code{%loc} (or @var{loc}) to it. +") + +DEFDOC (KILL, "Signal a process.", "\ +Sends the signal specified by @var{@2@} to the process @var{@1@}. Returns zero +on success, otherwise an error number. +See @code{kill(2)}. +") + +DEFDOC (LNBLNK, "Get last non-blank character in string.", "\ +Returns the index of the last non-blank character in @var{@1@}. +@code{LNBLNK} and @code{LEN_TRIM} are equivalent. +") + +DEFDOC (SLEEP, "Sleep for a specified time.", "\ +Causes the process to pause for @var{@1@} seconds. +See @code{sleep(2)}. +") + +DEFDOC (SYSTEM, "Invoke shell (system) command.", "\ +Passes the command @var{@1@} to a shell (see @code{system(3)}). +If argument @var{@2@} is present, it contains the value returned by +@code{system(3)}, presumably 0 if the shell command succeeded. +Note that which shell is used to invoke the command is system-dependent +and environment-dependent. +") diff --git a/gnu/usr.bin/gcc/f/intdoc.texi b/gnu/usr.bin/gcc/f/intdoc.texi new file mode 100644 index 00000000000..144a9f5ded5 --- /dev/null +++ b/gnu/usr.bin/gcc/f/intdoc.texi @@ -0,0 +1,6000 @@ +@menu +@ifset familyF2U +* Abort Intrinsic:: Abort the program. +@end ifset +@ifset familyF77 +* Abs Intrinsic:: Absolute value. +@end ifset +@ifset familyF2U +* Access Intrinsic:: Check file accessibility. +@end ifset +@ifset familyASC +* AChar Intrinsic:: ASCII character from code. +@end ifset +@ifset familyF77 +* ACos Intrinsic:: Arc cosine. +* AImag Intrinsic:: Convert/extract imaginary part of complex. +* AInt Intrinsic:: Truncate to whole number. +* ALog Intrinsic:: Natural logarithm (archaic). +* ALog10 Intrinsic:: Natural logarithm (archaic). +* AMax0 Intrinsic:: Maximum value (archaic). +* AMax1 Intrinsic:: Maximum value (archaic). +* AMin0 Intrinsic:: Minimum value (archaic). +* AMin1 Intrinsic:: Minimum value (archaic). +* AMod Intrinsic:: Remainder (archaic). +@end ifset +@ifset familyF2C +* And Intrinsic:: Boolean AND. +@end ifset +@ifset familyF77 +* ANInt Intrinsic:: Round to nearest whole number. +* ASin Intrinsic:: Arc sine. +* ATan Intrinsic:: Arc tangent. +* ATan2 Intrinsic:: Arc tangent. +@end ifset +@ifset familyF2U +* BesJ0 Intrinsic:: Bessel function. +* BesJ1 Intrinsic:: Bessel function. +* BesJN Intrinsic:: Bessel function. +* BesY0 Intrinsic:: Bessel function. +* BesY1 Intrinsic:: Bessel function. +* BesYN Intrinsic:: Bessel function. +@end ifset +@ifset familyF90 +* Bit_Size Intrinsic:: Number of bits in argument's type. +@end ifset +@ifset familyMIL +* BTest Intrinsic:: Test bit. +@end ifset +@ifset familyF77 +* CAbs Intrinsic:: Absolute value (archaic). +* CCos Intrinsic:: +@end ifset +@ifset familyFVZ +* CDAbs Intrinsic:: Absolute value (archaic). +* CDCos Intrinsic:: +* CDExp Intrinsic:: +* CDLog Intrinsic:: Natural logarithm (archaic). +* CDSin Intrinsic:: +* CDSqRt Intrinsic:: +@end ifset +@ifset familyF77 +* CExp Intrinsic:: +* Char Intrinsic:: Character from code. +@end ifset +@ifset familyF2U +* ChDir Intrinsic:: Change directory. +* ChMod Intrinsic:: Change file modes. +@end ifset +@ifset familyF77 +* CLog Intrinsic:: Natural logarithm (archaic). +* Cmplx Intrinsic:: Construct @code{COMPLEX(KIND=1)} value. +@end ifset +@ifset familyGNU +* Complex Intrinsic:: Build complex value from real and + imaginary parts. +@end ifset +@ifset familyF77 +* Conjg Intrinsic:: Complex conjugate. +* Cos Intrinsic:: +* CosH Intrinsic:: +* CSin Intrinsic:: +* CSqRt Intrinsic:: +@end ifset +@ifset familyF2U +* CTime Intrinsic:: Convert time to Day Mon dd hh:mm:ss yyyy. +@end ifset +@ifset familyF77 +* DAbs Intrinsic:: Absolute value (archaic). +* DACos Intrinsic:: Arc cosine (archaic). +* DASin Intrinsic:: Arc sine (archaic). +* DATan Intrinsic:: Arc tangent (archaic). +* DATan2 Intrinsic:: Arc tangent (archaic). +@end ifset +@ifset familyVXT +* Date Intrinsic:: Get current date as dd-Mon-yy. +@end ifset +@ifset familyF2U +* DbesJ0 Intrinsic:: +* DbesJ1 Intrinsic:: +* DbesJN Intrinsic:: +* DbesY0 Intrinsic:: +* DbesY1 Intrinsic:: +* DbesYN Intrinsic:: +@end ifset +@ifset familyF77 +* Dble Intrinsic:: +@end ifset +@ifset familyFVZ +* DCmplx Intrinsic:: +* DConjg Intrinsic:: Complex conjugate (archaic). +@end ifset +@ifset familyF77 +* DCos Intrinsic:: +* DCosH Intrinsic:: +* DDiM Intrinsic:: +@end ifset +@ifset familyF2U +* DErF Intrinsic:: +* DErFC Intrinsic:: +@end ifset +@ifset familyF77 +* DExp Intrinsic:: +@end ifset +@ifset familyFVZ +* DFloat Intrinsic:: +@end ifset +@ifset familyF77 +* DiM Intrinsic:: +@end ifset +@ifset familyFVZ +* DImag Intrinsic:: +@end ifset +@ifset familyF77 +* DInt Intrinsic:: Truncate to whole number (archaic). +* DLog Intrinsic:: Natural logarithm (archaic). +* DLog10 Intrinsic:: Natural logarithm (archaic). +* DMax1 Intrinsic:: Maximum value (archaic). +* DMin1 Intrinsic:: Minimum value (archaic). +* DMod Intrinsic:: Remainder (archaic). +* DNInt Intrinsic:: Round to nearest whole number (archaic). +* DProd Intrinsic:: +@end ifset +@ifset familyVXT +* DReal Intrinsic:: +@end ifset +@ifset familyF77 +* DSign Intrinsic:: +* DSin Intrinsic:: +* DSinH Intrinsic:: +* DSqRt Intrinsic:: +* DTan Intrinsic:: +* DTanH Intrinsic:: +@end ifset +@ifset familyF2U +* Dtime Intrinsic:: Get elapsed time since last time. +* ErF Intrinsic:: Error function. +* ErFC Intrinsic:: Complementary error function. +* ETime Intrinsic:: Get elapsed time for process. +* Exit Intrinsic:: Terminate the program. +@end ifset +@ifset familyF77 +* Exp Intrinsic:: +@end ifset +@ifset familyF2U +* Fdate Intrinsic:: Get current time as Day Mon dd hh:mm:ss yyyy. +* FGetC Intrinsic:: +@end ifset +@ifset familyF77 +* Float Intrinsic:: +@end ifset +@ifset familyF2U +* Flush Intrinsic:: Flush buffered output. +* FNum Intrinsic:: Get file descriptor from Fortran unit number. +* FPutC Intrinsic:: +* FSeek Intrinsic:: Position file (low-level). +* FStat Intrinsic:: Get file information. +* FTell Intrinsic:: Get file position (low-level). +* GError Intrinsic:: Get error message for last error. +* GetArg Intrinsic:: Obtain command-line argument. +* GetCWD Intrinsic:: Get current working directory. +* GetEnv Intrinsic:: Get environment variable. +* GetGId Intrinsic:: Get process group id. +* GetLog Intrinsic:: Get login name. +* GetPId Intrinsic:: Get process id. +* GetUId Intrinsic:: Get process user id. +* GMTime Intrinsic:: Convert time to GMT time info. +* HostNm Intrinsic:: Get host name. +@end ifset +@ifset familyF77 +* IAbs Intrinsic:: Absolute value (archaic). +@end ifset +@ifset familyASC +* IAChar Intrinsic:: ASCII code for character. +@end ifset +@ifset familyMIL +* IAnd Intrinsic:: Boolean AND. +@end ifset +@ifset familyF2U +* IArgC Intrinsic:: Obtain count of command-line arguments. +@end ifset +@ifset familyMIL +* IBClr Intrinsic:: +* IBits Intrinsic:: +* IBSet Intrinsic:: +@end ifset +@ifset familyF77 +* IChar Intrinsic:: Code for character. +@end ifset +@ifset familyF2U +* IDate Intrinsic:: Get local time info. +@end ifset +@ifset familyVXT +* IDate Intrinsic (Form IDATE (VXT)):: Get local time info (VAX/VMS). +@end ifset +@ifset familyF77 +* IDiM Intrinsic:: +* IDInt Intrinsic:: Convert to @code{INTEGER} value truncated + to whole number (archaic). +* IDNInt Intrinsic:: Convert to @code{INTEGER} value rounded + to nearest whole number (archaic). +@end ifset +@ifset familyMIL +* IEOr Intrinsic:: Boolean XOR. +@end ifset +@ifset familyF2U +* IErrNo Intrinsic:: Get error number for last error. +@end ifset +@ifset familyF77 +* IFix Intrinsic:: Convert to @code{INTEGER} value truncated + to whole number. +@end ifset +@ifset familyF2C +* Imag Intrinsic:: Extract imaginary part of complex. +@end ifset +@ifset familyGNU +* ImagPart Intrinsic:: Extract imaginary part of complex. +@end ifset +@ifset familyF77 +* Index Intrinsic:: +* Int Intrinsic:: Convert to @code{INTEGER} value truncated + to whole number. +@end ifset +@ifset familyMIL +* IOr Intrinsic:: Boolean OR. +@end ifset +@ifset familyF2U +* IRand Intrinsic:: Random number. +* IsaTty Intrinsic:: Is unit connected to a terminal? +@end ifset +@ifset familyMIL +* IShft Intrinsic:: +* IShftC Intrinsic:: +@end ifset +@ifset familyF77 +* ISign Intrinsic:: +@end ifset +@ifset familyF2U +* ITime Intrinsic:: Get local time of day. +* Kill Intrinsic:: Signal a process. +@end ifset +@ifset familyF77 +* Len Intrinsic:: +@end ifset +@ifset familyF90 +* Len_Trim Intrinsic:: Get last non-blank character in string. +@end ifset +@ifset familyF77 +* LGe Intrinsic:: +* LGt Intrinsic:: +@end ifset +@ifset familyF2U +* Link Intrinsic:: Make hard link in file system. +@end ifset +@ifset familyF77 +* LLe Intrinsic:: +* LLt Intrinsic:: +@end ifset +@ifset familyF2U +* LnBlnk Intrinsic:: Get last non-blank character in string. +* Loc Intrinsic:: Address of entity in core. +@end ifset +@ifset familyF77 +* Log Intrinsic:: Natural logarithm. +* Log10 Intrinsic:: Natural logarithm. +@end ifset +@ifset familyF2U +* Long Intrinsic:: +@end ifset +@ifset familyF2C +* LShift Intrinsic:: +@end ifset +@ifset familyF2U +* LStat Intrinsic:: Get file information. +* LTime Intrinsic:: Convert time to local time info. +@end ifset +@ifset familyF77 +* Max Intrinsic:: Maximum value. +* Max0 Intrinsic:: Maximum value (archaic). +* Max1 Intrinsic:: Maximum value (archaic). +@end ifset +@ifset familyF2U +* MClock Intrinsic:: Get number of clock ticks for process. +@end ifset +@ifset familyF77 +* Min Intrinsic:: Minimum value. +* Min0 Intrinsic:: Minimum value (archaic). +* Min1 Intrinsic:: Minimum value (archaic). +* Mod Intrinsic:: Remainder. +@end ifset +@ifset familyMIL +* MvBits Intrinsic:: +@end ifset +@ifset familyF77 +* NInt Intrinsic:: Convert to @code{INTEGER} value rounded + to nearest whole number. +@end ifset +@ifset familyMIL +* Not Intrinsic:: Boolean NOT. +@end ifset +@ifset familyF2C +* Or Intrinsic:: Boolean OR. +@end ifset +@ifset familyF2U +* PError Intrinsic:: Print error message for last error. +* Rand Intrinsic:: Random number. +@end ifset +@ifset familyF77 +* Real Intrinsic:: Convert value to type @code{REAL(KIND=1)}. +@end ifset +@ifset familyGNU +* RealPart Intrinsic:: Extract real part of complex. +@end ifset +@ifset familyF2U +* Rename Intrinsic:: Rename file. +@end ifset +@ifset familyF2C +* RShift Intrinsic:: +@end ifset +@ifset familyVXT +* Secnds Intrinsic:: Get local time offset since midnight. +@end ifset +@ifset familyF2U +* Second Intrinsic:: Get CPU time for process in seconds. +* Second Intrinsic (Form SECOND (subroutine)):: Get CPU time for process + in seconds. +* Short Intrinsic:: +@end ifset +@ifset familyF77 +* Sign Intrinsic:: +@end ifset +@ifset familyF2U +* Signal Intrinsic:: Muck with signal handling. +@end ifset +@ifset familyF77 +* Sin Intrinsic:: +* SinH Intrinsic:: +@end ifset +@ifset familyF2U +* Sleep Intrinsic:: Sleep for a specified time. +@end ifset +@ifset familyF77 +* Sngl Intrinsic:: +* SqRt Intrinsic:: +@end ifset +@ifset familyF2U +* SRand Intrinsic:: Random seed. +* Stat Intrinsic:: Get file information. +* SymLnk Intrinsic:: Make symbolic link in file system. +* System Intrinsic:: Invoke shell (system) command. +@end ifset +@ifset familyF90 +* System_Clock Intrinsic:: Get current system clock value. +@end ifset +@ifset familyF77 +* Tan Intrinsic:: +* TanH Intrinsic:: +@end ifset +@ifset familyF2U +* Time Intrinsic:: Get current time as time value. +@end ifset +@ifset familyVXT +* Time Intrinsic (Form TIME (VXT)):: +@end ifset +@ifset familyF2U +* TtyNam Intrinsic:: Get name of terminal device for unit. +* UMask Intrinsic:: Set file creation permissions mask. +* Unlink Intrinsic:: Unlink file. +@end ifset +@ifset familyF2C +* XOr Intrinsic:: Boolean XOR. +* ZAbs Intrinsic:: Absolute value (archaic). +* ZCos Intrinsic:: +* ZExp Intrinsic:: +* ZLog Intrinsic:: Natural logarithm (archaic). +* ZSin Intrinsic:: +* ZSqRt Intrinsic:: +@end ifset +@end menu + +@ifset familyF2U +@node Abort Intrinsic +@subsubsection Abort Intrinsic +@cindex Abort intrinsic +@cindex intrinsics, Abort + +@noindent +@example +CALL Abort() +@end example + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Prints a message and potentially causes a core dump via @code{abort(3)}. + +@end ifset +@ifset familyF77 +@node Abs Intrinsic +@subsubsection Abs Intrinsic +@cindex Abs intrinsic +@cindex intrinsics, Abs + +@noindent +@example +Abs(@var{A}) +@end example + +@noindent +Abs: @code{INTEGER} or @code{REAL} function. +The exact type depends on that of argument @var{A}---if @var{A} is +@code{COMPLEX}, this function's type is @code{REAL} +with the same @samp{KIND=} value as the type of @var{A}. +Otherwise, this function's type is the same as that of @var{A}. + +@noindent +@var{A}: @code{INTEGER}, @code{REAL}, or @code{COMPLEX}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Returns the absolute value of @var{A}. + +If @var{A} is type @code{COMPLEX}, the absolute +value is computed as: + +@example +SQRT(REALPART(@var{A})**2, IMAGPART(@var{A})**2) +@end example + +@noindent +Otherwise, it is computed by negating the @var{A} if +it is negative, or returning @var{A}. + +@xref{Sign Intrinsic}, for how to explicitly +compute the positive or negative form of the absolute +value of an expression. + +@end ifset +@ifset familyF2U +@node Access Intrinsic +@subsubsection Access Intrinsic +@cindex Access intrinsic +@cindex intrinsics, Access + +@noindent +@example +Access(@var{Name}, @var{Mode}) +@end example + +@noindent +Access: @code{INTEGER(KIND=1)} function. + +@noindent +@var{Name}: @code{CHARACTER}; scalar; INTENT(IN). + +@noindent +@var{Mode}: @code{CHARACTER}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Checks file @var{Name} for accessibility in the mode specified by @var{Mode} and +returns 0 if the file is accessible in that mode, otherwise an error +code if the file is inaccessible or @var{Mode} is invalid. See +@code{access(2)}. @var{Mode} may be a concatenation of any of the +following characters: + +@table @samp +@item r +Read permission + +@item w +Write permission + +@item x +Execute permission + +@item @kbd{SPC} +Existence +@end table + +@end ifset +@ifset familyASC +@node AChar Intrinsic +@subsubsection AChar Intrinsic +@cindex AChar intrinsic +@cindex intrinsics, AChar + +@noindent +@example +AChar(@var{I}) +@end example + +@noindent +AChar: @code{CHARACTER*1} function. + +@noindent +@var{I}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{f2c}, @code{f90}. + +@noindent +Description: + +Returns the ASCII character corresponding to the +code specified by @var{I}. + +@xref{IAChar Intrinsic}, for the inverse function. + +@xref{Char Intrinsic}, for the function corresponding +to the system's native character set. + +@end ifset +@ifset familyF77 +@node ACos Intrinsic +@subsubsection ACos Intrinsic +@cindex ACos intrinsic +@cindex intrinsics, ACos + +@noindent +@example +ACos(@var{X}) +@end example + +@noindent +ACos: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{X}. + +@noindent +@var{X}: @code{REAL}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Returns the arc-cosine (inverse cosine) of @var{X} +in radians. + +@xref{Cos Intrinsic}, for the inverse function. + +@node AImag Intrinsic +@subsubsection AImag Intrinsic +@cindex AImag intrinsic +@cindex intrinsics, AImag + +@noindent +@example +AImag(@var{Z}) +@end example + +@noindent +AImag: @code{REAL} function. +This intrinsic is valid when argument @var{Z} is +@code{COMPLEX(KIND=1)}. +When @var{Z} is any other @code{COMPLEX} type, +this intrinsic is valid only when used as the argument to +@code{REAL()}, as explained below. + +@noindent +@var{Z}: @code{COMPLEX}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Returns the (possibly converted) imaginary part of @var{Z}. + +Use of @code{AIMAG()} with an argument of a type +other than @code{COMPLEX(KIND=1)} is restricted to the following case: + +@example +REAL(AIMAG(Z)) +@end example + +@noindent +This expression converts the imaginary part of Z to +@code{REAL(KIND=1)}. + +@xref{REAL() and AIMAG() of Complex}, for more information. + +@node AInt Intrinsic +@subsubsection AInt Intrinsic +@cindex AInt intrinsic +@cindex intrinsics, AInt + +@noindent +@example +AInt(@var{A}) +@end example + +@noindent +AInt: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{A}. + +@noindent +@var{A}: @code{REAL}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Returns @var{A} with the fractional portion of its +magnitude truncated and its sign preserved. +(Also called ``truncation towards zero''.) + +@xref{ANInt Intrinsic}, for how to round to nearest +whole number. + +@xref{Int Intrinsic}, for how to truncate and then convert +number to @code{INTEGER}. + +@node ALog Intrinsic +@subsubsection ALog Intrinsic +@cindex ALog intrinsic +@cindex intrinsics, ALog + +@noindent +@example +ALog(@var{X}) +@end example + +@noindent +ALog: @code{REAL(KIND=1)} function. + +@noindent +@var{X}: @code{REAL(KIND=1)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Archaic form of @code{LOG()} that is specific +to one type for @var{X}. +@xref{Log Intrinsic}. + +@node ALog10 Intrinsic +@subsubsection ALog10 Intrinsic +@cindex ALog10 intrinsic +@cindex intrinsics, ALog10 + +@noindent +@example +ALog10(@var{X}) +@end example + +@noindent +ALog10: @code{REAL(KIND=1)} function. + +@noindent +@var{X}: @code{REAL(KIND=1)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Archaic form of @code{LOG10()} that is specific +to one type for @var{X}. +@xref{Log10 Intrinsic}. + +@node AMax0 Intrinsic +@subsubsection AMax0 Intrinsic +@cindex AMax0 intrinsic +@cindex intrinsics, AMax0 + +@noindent +@example +AMax0(@var{A}-1, @var{A}-2, @dots{}, @var{A}-n) +@end example + +@noindent +AMax0: @code{REAL(KIND=1)} function. + +@noindent +@var{A}: @code{INTEGER(KIND=1)}; at least two such arguments must be provided; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Archaic form of @code{MAX()} that is specific +to one type for @var{A} and a different return type. +@xref{Max Intrinsic}. + +@node AMax1 Intrinsic +@subsubsection AMax1 Intrinsic +@cindex AMax1 intrinsic +@cindex intrinsics, AMax1 + +@noindent +@example +AMax1(@var{A}-1, @var{A}-2, @dots{}, @var{A}-n) +@end example + +@noindent +AMax1: @code{REAL(KIND=1)} function. + +@noindent +@var{A}: @code{REAL(KIND=1)}; at least two such arguments must be provided; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Archaic form of @code{MAX()} that is specific +to one type for @var{A}. +@xref{Max Intrinsic}. + +@node AMin0 Intrinsic +@subsubsection AMin0 Intrinsic +@cindex AMin0 intrinsic +@cindex intrinsics, AMin0 + +@noindent +@example +AMin0(@var{A}-1, @var{A}-2, @dots{}, @var{A}-n) +@end example + +@noindent +AMin0: @code{REAL(KIND=1)} function. + +@noindent +@var{A}: @code{INTEGER(KIND=1)}; at least two such arguments must be provided; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Archaic form of @code{MIN()} that is specific +to one type for @var{A} and a different return type. +@xref{Min Intrinsic}. + +@node AMin1 Intrinsic +@subsubsection AMin1 Intrinsic +@cindex AMin1 intrinsic +@cindex intrinsics, AMin1 + +@noindent +@example +AMin1(@var{A}-1, @var{A}-2, @dots{}, @var{A}-n) +@end example + +@noindent +AMin1: @code{REAL(KIND=1)} function. + +@noindent +@var{A}: @code{REAL(KIND=1)}; at least two such arguments must be provided; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Archaic form of @code{MIN()} that is specific +to one type for @var{A}. +@xref{Min Intrinsic}. + +@node AMod Intrinsic +@subsubsection AMod Intrinsic +@cindex AMod intrinsic +@cindex intrinsics, AMod + +@noindent +@example +AMod(@var{A}, @var{P}) +@end example + +@noindent +AMod: @code{REAL(KIND=1)} function. + +@noindent +@var{A}: @code{REAL(KIND=1)}; scalar; INTENT(IN). + +@noindent +@var{P}: @code{REAL(KIND=1)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Archaic form of @code{MOD()} that is specific +to one type for @var{A}. +@xref{Mod Intrinsic}. + +@end ifset +@ifset familyF2C +@node And Intrinsic +@subsubsection And Intrinsic +@cindex And intrinsic +@cindex intrinsics, And + +@noindent +@example +And(@var{I}, @var{J}) +@end example + +@noindent +And: @code{INTEGER} or @code{LOGICAL} function, the exact type being the result of cross-promoting the +types of all the arguments. + +@noindent +@var{I}: @code{INTEGER} or @code{LOGICAL}; scalar; INTENT(IN). + +@noindent +@var{J}: @code{INTEGER} or @code{LOGICAL}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{f2c}. + +@noindent +Description: + +Returns value resulting from boolean AND of +pair of bits in each of @var{I} and @var{J}. + +@end ifset +@ifset familyF77 +@node ANInt Intrinsic +@subsubsection ANInt Intrinsic +@cindex ANInt intrinsic +@cindex intrinsics, ANInt + +@noindent +@example +ANInt(@var{A}) +@end example + +@noindent +ANInt: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{A}. + +@noindent +@var{A}: @code{REAL}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Returns @var{A} with the fractional portion of its +magnitude eliminated by rounding to the nearest whole +number and with its sign preserved. + +A fractional portion exactly equal to +@samp{.5} is rounded to the whole number that +is larger in magnitude. +(Also called ``Fortran round''.) + +@xref{AInt Intrinsic}, for how to truncate to +whole number. + +@xref{NInt Intrinsic}, for how to round and then convert +number to @code{INTEGER}. + +@node ASin Intrinsic +@subsubsection ASin Intrinsic +@cindex ASin intrinsic +@cindex intrinsics, ASin + +@noindent +@example +ASin(@var{X}) +@end example + +@noindent +ASin: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{X}. + +@noindent +@var{X}: @code{REAL}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Returns the arc-sine (inverse sine) of @var{X} +in radians. + +@xref{Sin Intrinsic}, for the inverse function. + +@node ATan Intrinsic +@subsubsection ATan Intrinsic +@cindex ATan intrinsic +@cindex intrinsics, ATan + +@noindent +@example +ATan(@var{X}) +@end example + +@noindent +ATan: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{X}. + +@noindent +@var{X}: @code{REAL}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Returns the arc-tangent (inverse tangent) of @var{X} +in radians. + +@xref{Tan Intrinsic}, for the inverse function. + +@node ATan2 Intrinsic +@subsubsection ATan2 Intrinsic +@cindex ATan2 intrinsic +@cindex intrinsics, ATan2 + +@noindent +@example +ATan2(@var{Y}, @var{X}) +@end example + +@noindent +ATan2: @code{REAL} function, the exact type being the result of cross-promoting the +types of all the arguments. + +@noindent +@var{Y}: @code{REAL}; scalar; INTENT(IN). + +@noindent +@var{X}: @code{REAL}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Returns the arc-tangent (inverse tangent) of the complex +number (@var{Y}, @var{X}) in radians. + +@xref{Tan Intrinsic}, for the inverse function. + +@end ifset +@ifset familyF2U +@node BesJ0 Intrinsic +@subsubsection BesJ0 Intrinsic +@cindex BesJ0 intrinsic +@cindex intrinsics, BesJ0 + +@noindent +@example +BesJ0(@var{X}) +@end example + +@noindent +BesJ0: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{X}. + +@noindent +@var{X}: @code{REAL}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Calculates the Bessel function of the first kind of order 0. +See @code{bessel(3m)}, on whose implementation the function depends. +@node BesJ1 Intrinsic +@subsubsection BesJ1 Intrinsic +@cindex BesJ1 intrinsic +@cindex intrinsics, BesJ1 + +@noindent +@example +BesJ1(@var{X}) +@end example + +@noindent +BesJ1: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{X}. + +@noindent +@var{X}: @code{REAL}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Calculates the Bessel function of the first kind of order 1. +See @code{bessel(3m)}, on whose implementation the function depends. +@node BesJN Intrinsic +@subsubsection BesJN Intrinsic +@cindex BesJN intrinsic +@cindex intrinsics, BesJN + +@noindent +@example +BesJN(@var{N}, @var{X}) +@end example + +@noindent +BesJN: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{X}. + +@noindent +@var{N}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +@var{X}: @code{REAL}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Calculates the Bessel function of the first kind of order @var{N}. +See @code{bessel(3m)}, on whose implementation the function depends. +@node BesY0 Intrinsic +@subsubsection BesY0 Intrinsic +@cindex BesY0 intrinsic +@cindex intrinsics, BesY0 + +@noindent +@example +BesY0(@var{X}) +@end example + +@noindent +BesY0: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{X}. + +@noindent +@var{X}: @code{REAL}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Calculates the Bessel function of the second kind of order 0. +See @code{bessel(3m)}, on whose implementation the function depends. +@node BesY1 Intrinsic +@subsubsection BesY1 Intrinsic +@cindex BesY1 intrinsic +@cindex intrinsics, BesY1 + +@noindent +@example +BesY1(@var{X}) +@end example + +@noindent +BesY1: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{X}. + +@noindent +@var{X}: @code{REAL}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Calculates the Bessel function of the second kind of order 1. +See @code{bessel(3m)}, on whose implementation the function depends. +@node BesYN Intrinsic +@subsubsection BesYN Intrinsic +@cindex BesYN intrinsic +@cindex intrinsics, BesYN + +@noindent +@example +BesYN(@var{N}, @var{X}) +@end example + +@noindent +BesYN: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{X}. + +@noindent +@var{N}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +@var{X}: @code{REAL}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Calculates the Bessel function of the second kind of order @var{N}. +See @code{bessel(3m)}, on whose implementation the function depends. +@end ifset +@ifset familyF90 +@node Bit_Size Intrinsic +@subsubsection Bit_Size Intrinsic +@cindex Bit_Size intrinsic +@cindex intrinsics, Bit_Size + +@noindent +@example +Bit_Size(@var{I}) +@end example + +@noindent +Bit_Size: @code{INTEGER} function, the @samp{KIND=} value of the type being that of argument @var{I}. + +@noindent +@var{I}: @code{INTEGER}; scalar. + +@noindent +Intrinsic groups: @code{f90}. + +@noindent +Description: + +Returns the number of bits (integer precision plus sign bit) +represented by the type for @var{I}. + +@xref{BTest Intrinsic}, for how to test the value of a +bit in a variable or array. + +@xref{IBSet Intrinsic}, for how to set a bit in a +variable or array to 1. + +@end ifset +@ifset familyMIL +@node BTest Intrinsic +@subsubsection BTest Intrinsic +@cindex BTest intrinsic +@cindex intrinsics, BTest + +@noindent +@example +BTest(@var{I}, @var{Pos}) +@end example + +@noindent +BTest: @code{LOGICAL(KIND=1)} function. + +@noindent +@var{I}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +@var{Pos}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{mil}, @code{f90}, @code{vxt}. + +@noindent +Description: + +Returns @code{.TRUE.} if bit @var{Pos} in @var{I} is +1, @code{.FALSE.} otherwise. + +(Bit 0 is the low-order bit, adding the value 2**0, or 1, +to the number if set to 1; +bit 1 is the next-higher-order bit, adding 2**1, or 2; +bit 2 adds 2**2, or 4; and so on.) + +@xref{Bit_Size Intrinsic}, for how to obtain the number of bits +in a type. + +@end ifset +@ifset familyF77 +@node CAbs Intrinsic +@subsubsection CAbs Intrinsic +@cindex CAbs intrinsic +@cindex intrinsics, CAbs + +@noindent +@example +CAbs(@var{A}) +@end example + +@noindent +CAbs: @code{REAL(KIND=1)} function. + +@noindent +@var{A}: @code{COMPLEX(KIND=1)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Archaic form of @code{ABS()} that is specific +to one type for @var{A}. +@xref{Abs Intrinsic}. + +@node CCos Intrinsic +@subsubsection CCos Intrinsic +@cindex CCos intrinsic +@cindex intrinsics, CCos + +@noindent +@example +CCos(@var{X}) +@end example + +@noindent +CCos: @code{COMPLEX(KIND=1)} function. + +@noindent +@var{X}: @code{COMPLEX(KIND=1)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@end ifset +@ifset familyFVZ +@node CDAbs Intrinsic +@subsubsection CDAbs Intrinsic +@cindex CDAbs intrinsic +@cindex intrinsics, CDAbs + +@noindent +@example +CDAbs(@var{A}) +@end example + +@noindent +CDAbs: @code{REAL(KIND=2)} function. + +@noindent +@var{A}: @code{COMPLEX(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{f2c}, @code{vxt}. + +@noindent +Description: + +Archaic form of @code{ABS()} that is specific +to one type for @var{A}. +@xref{Abs Intrinsic}. + +@node CDCos Intrinsic +@subsubsection CDCos Intrinsic +@cindex CDCos intrinsic +@cindex intrinsics, CDCos + +@noindent +@example +CDCos(@var{X}) +@end example + +@noindent +CDCos: @code{COMPLEX(KIND=2)} function. + +@noindent +@var{X}: @code{COMPLEX(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{f2c}, @code{vxt}. + +@node CDExp Intrinsic +@subsubsection CDExp Intrinsic +@cindex CDExp intrinsic +@cindex intrinsics, CDExp + +@noindent +@example +CDExp(@var{X}) +@end example + +@noindent +CDExp: @code{COMPLEX(KIND=2)} function. + +@noindent +@var{X}: @code{COMPLEX(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{f2c}, @code{vxt}. + +@node CDLog Intrinsic +@subsubsection CDLog Intrinsic +@cindex CDLog intrinsic +@cindex intrinsics, CDLog + +@noindent +@example +CDLog(@var{X}) +@end example + +@noindent +CDLog: @code{COMPLEX(KIND=2)} function. + +@noindent +@var{X}: @code{COMPLEX(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{f2c}, @code{vxt}. + +@noindent +Description: + +Archaic form of @code{LOG()} that is specific +to one type for @var{X}. +@xref{Log Intrinsic}. + +@node CDSin Intrinsic +@subsubsection CDSin Intrinsic +@cindex CDSin intrinsic +@cindex intrinsics, CDSin + +@noindent +@example +CDSin(@var{X}) +@end example + +@noindent +CDSin: @code{COMPLEX(KIND=2)} function. + +@noindent +@var{X}: @code{COMPLEX(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{f2c}, @code{vxt}. + +@node CDSqRt Intrinsic +@subsubsection CDSqRt Intrinsic +@cindex CDSqRt intrinsic +@cindex intrinsics, CDSqRt + +@noindent +@example +CDSqRt(@var{X}) +@end example + +@noindent +CDSqRt: @code{COMPLEX(KIND=2)} function. + +@noindent +@var{X}: @code{COMPLEX(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{f2c}, @code{vxt}. + +@end ifset +@ifset familyF77 +@node CExp Intrinsic +@subsubsection CExp Intrinsic +@cindex CExp intrinsic +@cindex intrinsics, CExp + +@noindent +@example +CExp(@var{X}) +@end example + +@noindent +CExp: @code{COMPLEX(KIND=1)} function. + +@noindent +@var{X}: @code{COMPLEX(KIND=1)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@node Char Intrinsic +@subsubsection Char Intrinsic +@cindex Char intrinsic +@cindex intrinsics, Char + +@noindent +@example +Char(@var{I}) +@end example + +@noindent +Char: @code{CHARACTER*1} function. + +@noindent +@var{I}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Returns the character corresponding to the +code specified by @var{I}, using the system's +native character set. + +Because the system's native character set is used, +the correspondence between character and their codes +is not necessarily the same between GNU Fortran +implementations. + +@xref{IChar Intrinsic}, for the inverse function. + +@xref{AChar Intrinsic}, for the function corresponding +to the ASCII character set. + +@end ifset +@ifset familyF2U +@node ChDir Intrinsic +@subsubsection ChDir Intrinsic +@cindex ChDir intrinsic +@cindex intrinsics, ChDir + +@noindent +@example +CALL ChDir(@var{Dir}, @var{Status}) +@end example + +@noindent +@var{Dir}: @code{CHARACTER}; scalar; INTENT(IN). + +@noindent +@var{Status}: @code{INTEGER(KIND=1)}; OPTIONAL; scalar; INTENT(OUT). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Sets the current working directory to be @var{Dir}. +If the @var{Status} argument is supplied, it contains 0 +on success or an error code otherwise upon return. +See @code{chdir(3)}. + +@node ChMod Intrinsic +@subsubsection ChMod Intrinsic +@cindex ChMod intrinsic +@cindex intrinsics, ChMod + +@noindent +@example +CALL ChMod(@var{Name}, @var{Mode}, @var{Status}) +@end example + +@noindent +@var{Name}: @code{CHARACTER}; scalar; INTENT(IN). + +@noindent +@var{Mode}: @code{CHARACTER}; scalar; INTENT(IN). + +@noindent +@var{Status}: @code{INTEGER}; OPTIONAL; scalar; INTENT(OUT). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Changes the access mode of file @var{Name} according to the +specification @var{Mode}, which is given in the format of +@code{chmod(1)}. +If the @var{Status} argument is supplied, it contains 0 +on success or an error code otherwise upon return. +Note that this currently works +by actually invoking @code{/bin/chmod} (or the @code{chmod} found when +the library was configured) and so may fail in some circumstances and +will, anyway, be slow. + +@end ifset +@ifset familyF77 +@node CLog Intrinsic +@subsubsection CLog Intrinsic +@cindex CLog intrinsic +@cindex intrinsics, CLog + +@noindent +@example +CLog(@var{X}) +@end example + +@noindent +CLog: @code{COMPLEX(KIND=1)} function. + +@noindent +@var{X}: @code{COMPLEX(KIND=1)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Archaic form of @code{LOG()} that is specific +to one type for @var{X}. +@xref{Log Intrinsic}. + +@node Cmplx Intrinsic +@subsubsection Cmplx Intrinsic +@cindex Cmplx intrinsic +@cindex intrinsics, Cmplx + +@noindent +@example +Cmplx(@var{X}, @var{Y}) +@end example + +@noindent +Cmplx: @code{COMPLEX(KIND=1)} function. + +@noindent +@var{X}: @code{INTEGER}, @code{REAL}, or @code{COMPLEX}; scalar; INTENT(IN). + +@noindent +@var{Y}: @code{INTEGER} or @code{REAL}; OPTIONAL (must be omitted if @var{X} is @code{COMPLEX}); scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +If @var{X} is not type @code{COMPLEX}, +constructs a value of type @code{COMPLEX(KIND=1)} from the +real and imaginary values specified by @var{X} and +@var{Y}, respectively. +If @var{Y} is omitted, @samp{0.} is assumed. + +If @var{X} is type @code{COMPLEX}, +converts it to type @code{COMPLEX(KIND=1)}. + +@xref{Complex Intrinsic}, for information on easily constructing +a @code{COMPLEX} value of arbitrary precision from @code{REAL} +arguments. + +@end ifset +@ifset familyGNU +@node Complex Intrinsic +@subsubsection Complex Intrinsic +@cindex Complex intrinsic +@cindex intrinsics, Complex + +@noindent +@example +Complex(@var{Real}, @var{Imag}) +@end example + +@noindent +Complex: @code{COMPLEX} function, the exact type being the result of cross-promoting the +types of all the arguments. + +@noindent +@var{Real}: @code{INTEGER} or @code{REAL}; scalar; INTENT(IN). + +@noindent +@var{Imag}: @code{INTEGER} or @code{REAL}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{gnu}. + +@noindent +Description: + +Returns a @code{COMPLEX} value that has @samp{Real} and @samp{Imag} as its +real and imaginary parts, respectively. + +If @var{Real} and @var{Imag} are the same type, and that type is not +@code{INTEGER}, no data conversion is performed, and the type of +the resulting value has the same kind value as the types +of @var{Real} and @var{Imag}. + +If @var{Real} and @var{Imag} are not the same type, the usual type-promotion +rules are applied to both, converting either or both to the +appropriate @code{REAL} type. +The type of the resulting value has the same kind value as the +type to which both @var{Real} and @var{Imag} were converted, in this case. + +If @var{Real} and @var{Imag} are both @code{INTEGER}, they are both converted +to @code{REAL(KIND=1)}, and the result of the @code{COMPLEX()} +invocation is type @code{COMPLEX(KIND=1)}. + +@emph{Note:} The way to do this in standard Fortran 90 +is too hairy to describe here, but it is important to +note that @samp{CMPLX(D1,D2)} returns a @code{COMPLEX(KIND=1)} +result even if @samp{D1} and @samp{D2} are type @code{REAL(KIND=2)}. +Hence the availability of @code{COMPLEX()} in GNU Fortran. + +@end ifset +@ifset familyF77 +@node Conjg Intrinsic +@subsubsection Conjg Intrinsic +@cindex Conjg intrinsic +@cindex intrinsics, Conjg + +@noindent +@example +Conjg(@var{Z}) +@end example + +@noindent +Conjg: @code{COMPLEX} function, the @samp{KIND=} value of the type being that of argument @var{Z}. + +@noindent +@var{Z}: @code{COMPLEX}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Returns the complex conjugate: + +@example +COMPLEX(REALPART(@var{Z}), -IMAGPART(@var{Z})) +@end example + +@node Cos Intrinsic +@subsubsection Cos Intrinsic +@cindex Cos intrinsic +@cindex intrinsics, Cos + +@noindent +@example +Cos(@var{X}) +@end example + +@noindent +Cos: @code{REAL} or @code{COMPLEX} function, the exact type being that of argument @var{X}. + +@noindent +@var{X}: @code{REAL} or @code{COMPLEX}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@node CosH Intrinsic +@subsubsection CosH Intrinsic +@cindex CosH intrinsic +@cindex intrinsics, CosH + +@noindent +@example +CosH(@var{X}) +@end example + +@noindent +CosH: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{X}. + +@noindent +@var{X}: @code{REAL}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@node CSin Intrinsic +@subsubsection CSin Intrinsic +@cindex CSin intrinsic +@cindex intrinsics, CSin + +@noindent +@example +CSin(@var{X}) +@end example + +@noindent +CSin: @code{COMPLEX(KIND=1)} function. + +@noindent +@var{X}: @code{COMPLEX(KIND=1)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@node CSqRt Intrinsic +@subsubsection CSqRt Intrinsic +@cindex CSqRt intrinsic +@cindex intrinsics, CSqRt + +@noindent +@example +CSqRt(@var{X}) +@end example + +@noindent +CSqRt: @code{COMPLEX(KIND=1)} function. + +@noindent +@var{X}: @code{COMPLEX(KIND=1)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@end ifset +@ifset familyF2U +@node CTime Intrinsic +@subsubsection CTime Intrinsic +@cindex CTime intrinsic +@cindex intrinsics, CTime + +@noindent +@example +CTime(@var{STime}) +@end example + +@noindent +CTime: @code{CHARACTER*(*)} function. + +@noindent +@var{STime}: @code{INTEGER(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Converts @var{STime}, a system time value, such as returned by +@code{TIME()}, to a string of the form @samp{Sat Aug 19 18:13:14 1995}. + +@xref{Time Intrinsic}. + +@end ifset +@ifset familyF77 +@node DAbs Intrinsic +@subsubsection DAbs Intrinsic +@cindex DAbs intrinsic +@cindex intrinsics, DAbs + +@noindent +@example +DAbs(@var{A}) +@end example + +@noindent +DAbs: @code{REAL(KIND=2)} function. + +@noindent +@var{A}: @code{REAL(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Archaic form of @code{ABS()} that is specific +to one type for @var{A}. +@xref{Abs Intrinsic}. + +@node DACos Intrinsic +@subsubsection DACos Intrinsic +@cindex DACos intrinsic +@cindex intrinsics, DACos + +@noindent +@example +DACos(@var{X}) +@end example + +@noindent +DACos: @code{REAL(KIND=2)} function. + +@noindent +@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Archaic form of @code{ACOS()} that is specific +to one type for @var{X}. +@xref{ACos Intrinsic}. + +@node DASin Intrinsic +@subsubsection DASin Intrinsic +@cindex DASin intrinsic +@cindex intrinsics, DASin + +@noindent +@example +DASin(@var{X}) +@end example + +@noindent +DASin: @code{REAL(KIND=2)} function. + +@noindent +@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Archaic form of @code{ASIN()} that is specific +to one type for @var{X}. +@xref{ASin Intrinsic}. + +@node DATan Intrinsic +@subsubsection DATan Intrinsic +@cindex DATan intrinsic +@cindex intrinsics, DATan + +@noindent +@example +DATan(@var{X}) +@end example + +@noindent +DATan: @code{REAL(KIND=2)} function. + +@noindent +@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Archaic form of @code{ATAN()} that is specific +to one type for @var{X}. +@xref{ATan Intrinsic}. + +@node DATan2 Intrinsic +@subsubsection DATan2 Intrinsic +@cindex DATan2 intrinsic +@cindex intrinsics, DATan2 + +@noindent +@example +DATan2(@var{Y}, @var{X}) +@end example + +@noindent +DATan2: @code{REAL(KIND=2)} function. + +@noindent +@var{Y}: @code{REAL(KIND=2)}; scalar; INTENT(IN). + +@noindent +@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Archaic form of @code{ATAN2()} that is specific +to one type for @var{Y} and @var{X}. +@xref{ATan2 Intrinsic}. + +@end ifset +@ifset familyVXT +@node Date Intrinsic +@subsubsection Date Intrinsic +@cindex Date intrinsic +@cindex intrinsics, Date + +@noindent +@example +CALL Date(@var{Date}) +@end example + +@noindent +@var{Date}: @code{CHARACTER}; scalar; INTENT(OUT). + +@noindent +Intrinsic groups: @code{vxt}. + +@noindent +Description: + +Returns @var{Date} in the form @samp{@var{dd}-@var{mmm}-@var{yy}}, +representing the numeric day of the month @var{dd}, a three-character +abbreviation of the month name @var{mmm} and the last two digits of +the year @var{yy}, e.g.@ @samp{25-Nov-96}. + +This intrinsic is not recommended, due to the year 2000 approaching. +@xref{CTime Intrinsic}, for information on obtaining more digits +for the current (or any) date. + +@end ifset +@ifset familyF2U +@node DbesJ0 Intrinsic +@subsubsection DbesJ0 Intrinsic +@cindex DbesJ0 intrinsic +@cindex intrinsics, DbesJ0 + +@noindent +@example +DbesJ0(@var{X}) +@end example + +@noindent +DbesJ0: @code{REAL(KIND=2)} function. + +@noindent +@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{unix}. + +@node DbesJ1 Intrinsic +@subsubsection DbesJ1 Intrinsic +@cindex DbesJ1 intrinsic +@cindex intrinsics, DbesJ1 + +@noindent +@example +DbesJ1(@var{X}) +@end example + +@noindent +DbesJ1: @code{REAL(KIND=2)} function. + +@noindent +@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{unix}. + +@node DbesJN Intrinsic +@subsubsection DbesJN Intrinsic +@cindex DbesJN intrinsic +@cindex intrinsics, DbesJN + +@noindent +@example +DbesJN(@var{N}, @var{X}) +@end example + +@noindent +DbesJN: @code{REAL(KIND=2)} function. + +@noindent +@var{N}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{unix}. + +@node DbesY0 Intrinsic +@subsubsection DbesY0 Intrinsic +@cindex DbesY0 intrinsic +@cindex intrinsics, DbesY0 + +@noindent +@example +DbesY0(@var{X}) +@end example + +@noindent +DbesY0: @code{REAL(KIND=2)} function. + +@noindent +@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{unix}. + +@node DbesY1 Intrinsic +@subsubsection DbesY1 Intrinsic +@cindex DbesY1 intrinsic +@cindex intrinsics, DbesY1 + +@noindent +@example +DbesY1(@var{X}) +@end example + +@noindent +DbesY1: @code{REAL(KIND=2)} function. + +@noindent +@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{unix}. + +@node DbesYN Intrinsic +@subsubsection DbesYN Intrinsic +@cindex DbesYN intrinsic +@cindex intrinsics, DbesYN + +@noindent +@example +DbesYN(@var{N}, @var{X}) +@end example + +@noindent +DbesYN: @code{REAL(KIND=2)} function. + +@noindent +@var{N}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{unix}. + +@end ifset +@ifset familyF77 +@node Dble Intrinsic +@subsubsection Dble Intrinsic +@cindex Dble intrinsic +@cindex intrinsics, Dble + +@noindent +@example +Dble(@var{A}) +@end example + +@noindent +Dble: @code{REAL(KIND=2)} function. + +@noindent +@var{A}: @code{INTEGER}, @code{REAL}, or @code{COMPLEX}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@end ifset +@ifset familyFVZ +@node DCmplx Intrinsic +@subsubsection DCmplx Intrinsic +@cindex DCmplx intrinsic +@cindex intrinsics, DCmplx + +@noindent +@example +DCmplx(@var{X}, @var{Y}) +@end example + +@noindent +DCmplx: @code{COMPLEX(KIND=2)} function. + +@noindent +@var{X}: @code{INTEGER}, @code{REAL}, or @code{COMPLEX}; scalar; INTENT(IN). + +@noindent +@var{Y}: @code{INTEGER} or @code{REAL}; OPTIONAL (must be omitted if @var{X} is @code{COMPLEX}); scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{f2c}, @code{vxt}. + +@node DConjg Intrinsic +@subsubsection DConjg Intrinsic +@cindex DConjg intrinsic +@cindex intrinsics, DConjg + +@noindent +@example +DConjg(@var{Z}) +@end example + +@noindent +DConjg: @code{COMPLEX(KIND=2)} function. + +@noindent +@var{Z}: @code{COMPLEX(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{f2c}, @code{vxt}. + +@noindent +Description: + +Archaic form of @code{CONJG()} that is specific +to one type for @var{Z}. +@xref{ATan2 Intrinsic}. + +@end ifset +@ifset familyF77 +@node DCos Intrinsic +@subsubsection DCos Intrinsic +@cindex DCos intrinsic +@cindex intrinsics, DCos + +@noindent +@example +DCos(@var{X}) +@end example + +@noindent +DCos: @code{REAL(KIND=2)} function. + +@noindent +@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@node DCosH Intrinsic +@subsubsection DCosH Intrinsic +@cindex DCosH intrinsic +@cindex intrinsics, DCosH + +@noindent +@example +DCosH(@var{X}) +@end example + +@noindent +DCosH: @code{REAL(KIND=2)} function. + +@noindent +@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@node DDiM Intrinsic +@subsubsection DDiM Intrinsic +@cindex DDiM intrinsic +@cindex intrinsics, DDiM + +@noindent +@example +DDiM(@var{X}, @var{Y}) +@end example + +@noindent +DDiM: @code{REAL(KIND=2)} function. + +@noindent +@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). + +@noindent +@var{Y}: @code{REAL(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@end ifset +@ifset familyF2U +@node DErF Intrinsic +@subsubsection DErF Intrinsic +@cindex DErF intrinsic +@cindex intrinsics, DErF + +@noindent +@example +DErF(@var{X}) +@end example + +@noindent +DErF: @code{REAL(KIND=2)} function. + +@noindent +@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{unix}. + +@node DErFC Intrinsic +@subsubsection DErFC Intrinsic +@cindex DErFC intrinsic +@cindex intrinsics, DErFC + +@noindent +@example +DErFC(@var{X}) +@end example + +@noindent +DErFC: @code{REAL(KIND=2)} function. + +@noindent +@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{unix}. + +@end ifset +@ifset familyF77 +@node DExp Intrinsic +@subsubsection DExp Intrinsic +@cindex DExp intrinsic +@cindex intrinsics, DExp + +@noindent +@example +DExp(@var{X}) +@end example + +@noindent +DExp: @code{REAL(KIND=2)} function. + +@noindent +@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@end ifset +@ifset familyFVZ +@node DFloat Intrinsic +@subsubsection DFloat Intrinsic +@cindex DFloat intrinsic +@cindex intrinsics, DFloat + +@noindent +@example +DFloat(@var{A}) +@end example + +@noindent +DFloat: @code{REAL(KIND=2)} function. + +@noindent +@var{A}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{f2c}, @code{vxt}. + +@end ifset +@ifset familyF77 +@node DiM Intrinsic +@subsubsection DiM Intrinsic +@cindex DiM intrinsic +@cindex intrinsics, DiM + +@noindent +@example +DiM(@var{X}, @var{Y}) +@end example + +@noindent +DiM: @code{INTEGER} or @code{REAL} function, the exact type being the result of cross-promoting the +types of all the arguments. + +@noindent +@var{X}: @code{INTEGER} or @code{REAL}; scalar; INTENT(IN). + +@noindent +@var{Y}: @code{INTEGER} or @code{REAL}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@end ifset +@ifset familyFVZ +@node DImag Intrinsic +@subsubsection DImag Intrinsic +@cindex DImag intrinsic +@cindex intrinsics, DImag + +@noindent +@example +DImag(@var{Z}) +@end example + +@noindent +DImag: @code{REAL(KIND=2)} function. + +@noindent +@var{Z}: @code{COMPLEX(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{f2c}, @code{vxt}. + +@end ifset +@ifset familyF77 +@node DInt Intrinsic +@subsubsection DInt Intrinsic +@cindex DInt intrinsic +@cindex intrinsics, DInt + +@noindent +@example +DInt(@var{A}) +@end example + +@noindent +DInt: @code{REAL(KIND=2)} function. + +@noindent +@var{A}: @code{REAL(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Archaic form of @code{AINT()} that is specific +to one type for @var{A}. +@xref{AInt Intrinsic}. + +@node DLog Intrinsic +@subsubsection DLog Intrinsic +@cindex DLog intrinsic +@cindex intrinsics, DLog + +@noindent +@example +DLog(@var{X}) +@end example + +@noindent +DLog: @code{REAL(KIND=2)} function. + +@noindent +@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Archaic form of @code{LOG()} that is specific +to one type for @var{X}. +@xref{Log Intrinsic}. + +@node DLog10 Intrinsic +@subsubsection DLog10 Intrinsic +@cindex DLog10 intrinsic +@cindex intrinsics, DLog10 + +@noindent +@example +DLog10(@var{X}) +@end example + +@noindent +DLog10: @code{REAL(KIND=2)} function. + +@noindent +@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Archaic form of @code{LOG10()} that is specific +to one type for @var{X}. +@xref{Log10 Intrinsic}. + +@node DMax1 Intrinsic +@subsubsection DMax1 Intrinsic +@cindex DMax1 intrinsic +@cindex intrinsics, DMax1 + +@noindent +@example +DMax1(@var{A}-1, @var{A}-2, @dots{}, @var{A}-n) +@end example + +@noindent +DMax1: @code{REAL(KIND=2)} function. + +@noindent +@var{A}: @code{REAL(KIND=2)}; at least two such arguments must be provided; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Archaic form of @code{MAX()} that is specific +to one type for @var{A}. +@xref{Max Intrinsic}. + +@node DMin1 Intrinsic +@subsubsection DMin1 Intrinsic +@cindex DMin1 intrinsic +@cindex intrinsics, DMin1 + +@noindent +@example +DMin1(@var{A}-1, @var{A}-2, @dots{}, @var{A}-n) +@end example + +@noindent +DMin1: @code{REAL(KIND=2)} function. + +@noindent +@var{A}: @code{REAL(KIND=2)}; at least two such arguments must be provided; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Archaic form of @code{MIN()} that is specific +to one type for @var{A}. +@xref{Min Intrinsic}. + +@node DMod Intrinsic +@subsubsection DMod Intrinsic +@cindex DMod intrinsic +@cindex intrinsics, DMod + +@noindent +@example +DMod(@var{A}, @var{P}) +@end example + +@noindent +DMod: @code{REAL(KIND=2)} function. + +@noindent +@var{A}: @code{REAL(KIND=2)}; scalar; INTENT(IN). + +@noindent +@var{P}: @code{REAL(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Archaic form of @code{MOD()} that is specific +to one type for @var{A}. +@xref{Mod Intrinsic}. + +@node DNInt Intrinsic +@subsubsection DNInt Intrinsic +@cindex DNInt intrinsic +@cindex intrinsics, DNInt + +@noindent +@example +DNInt(@var{A}) +@end example + +@noindent +DNInt: @code{REAL(KIND=2)} function. + +@noindent +@var{A}: @code{REAL(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Archaic form of @code{ANINT()} that is specific +to one type for @var{A}. +@xref{ANInt Intrinsic}. + +@node DProd Intrinsic +@subsubsection DProd Intrinsic +@cindex DProd intrinsic +@cindex intrinsics, DProd + +@noindent +@example +DProd(@var{X}, @var{Y}) +@end example + +@noindent +DProd: @code{REAL(KIND=2)} function. + +@noindent +@var{X}: @code{REAL(KIND=1)}; scalar; INTENT(IN). + +@noindent +@var{Y}: @code{REAL(KIND=1)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@end ifset +@ifset familyVXT +@node DReal Intrinsic +@subsubsection DReal Intrinsic +@cindex DReal intrinsic +@cindex intrinsics, DReal + +@noindent +@example +DReal(@var{A}) +@end example + +@noindent +DReal: @code{REAL(KIND=2)} function. + +@noindent +@var{A}: @code{INTEGER}, @code{REAL}, or @code{COMPLEX}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{vxt}. + +@end ifset +@ifset familyF77 +@node DSign Intrinsic +@subsubsection DSign Intrinsic +@cindex DSign intrinsic +@cindex intrinsics, DSign + +@noindent +@example +DSign(@var{A}, @var{B}) +@end example + +@noindent +DSign: @code{REAL(KIND=2)} function. + +@noindent +@var{A}: @code{REAL(KIND=2)}; scalar; INTENT(IN). + +@noindent +@var{B}: @code{REAL(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@node DSin Intrinsic +@subsubsection DSin Intrinsic +@cindex DSin intrinsic +@cindex intrinsics, DSin + +@noindent +@example +DSin(@var{X}) +@end example + +@noindent +DSin: @code{REAL(KIND=2)} function. + +@noindent +@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@node DSinH Intrinsic +@subsubsection DSinH Intrinsic +@cindex DSinH intrinsic +@cindex intrinsics, DSinH + +@noindent +@example +DSinH(@var{X}) +@end example + +@noindent +DSinH: @code{REAL(KIND=2)} function. + +@noindent +@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@node DSqRt Intrinsic +@subsubsection DSqRt Intrinsic +@cindex DSqRt intrinsic +@cindex intrinsics, DSqRt + +@noindent +@example +DSqRt(@var{X}) +@end example + +@noindent +DSqRt: @code{REAL(KIND=2)} function. + +@noindent +@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@node DTan Intrinsic +@subsubsection DTan Intrinsic +@cindex DTan intrinsic +@cindex intrinsics, DTan + +@noindent +@example +DTan(@var{X}) +@end example + +@noindent +DTan: @code{REAL(KIND=2)} function. + +@noindent +@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@node DTanH Intrinsic +@subsubsection DTanH Intrinsic +@cindex DTanH intrinsic +@cindex intrinsics, DTanH + +@noindent +@example +DTanH(@var{X}) +@end example + +@noindent +DTanH: @code{REAL(KIND=2)} function. + +@noindent +@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@end ifset +@ifset familyF2U +@node Dtime Intrinsic +@subsubsection Dtime Intrinsic +@cindex Dtime intrinsic +@cindex intrinsics, Dtime + +@noindent +@example +Dtime(@var{TArray}) +@end example + +@noindent +Dtime: @code{REAL(KIND=1)} function. + +@noindent +@var{TArray}: @code{REAL(KIND=1)}; DIMENSION(2); INTENT(OUT). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Initially, return in seconds the runtime (since the start of the +process' execution) as the function value and the user and system +components of this in @samp{@var{TArray}(1)} and @samp{@var{TArray}(2)} +respectively. +The functions' value is equal to @samp{@var{TArray}(1) + @samp{TArray}(2)}. + +Subsequent invocations of @samp{DTIME()} return values accumulated since the +previous invocation. + +@node ErF Intrinsic +@subsubsection ErF Intrinsic +@cindex ErF intrinsic +@cindex intrinsics, ErF + +@noindent +@example +ErF(@var{X}) +@end example + +@noindent +ErF: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{X}. + +@noindent +@var{X}: @code{REAL}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Returns the error function of @var{X}. +See @code{erf(3m)}, which provides the implementation. + +@node ErFC Intrinsic +@subsubsection ErFC Intrinsic +@cindex ErFC intrinsic +@cindex intrinsics, ErFC + +@noindent +@example +ErFC(@var{X}) +@end example + +@noindent +ErFC: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{X}. + +@noindent +@var{X}: @code{REAL}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Returns the complementary error function of @var{X}: +@code{ERFC(R) = 1 - ERF(R)} (except that the result may be more +accurate than explicitly evaluating that formulae would give). +See @code{erfc(3m)}, which provides the implementation. + +@node ETime Intrinsic +@subsubsection ETime Intrinsic +@cindex ETime intrinsic +@cindex intrinsics, ETime + +@noindent +@example +ETime(@var{TArray}) +@end example + +@noindent +ETime: @code{REAL(KIND=1)} function. + +@noindent +@var{TArray}: @code{REAL(KIND=1)}; DIMENSION(2); INTENT(OUT). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Return in seconds the runtime (since the start of the process' +execution) as the function value and the user and system components of +this in @samp{@var{TArray}(1)} and @samp{@var{TArray}(2)} respectively. +The functions' value is equal to @samp{@var{TArray}(1) + @var{TArray}(2)}. + +@node Exit Intrinsic +@subsubsection Exit Intrinsic +@cindex Exit intrinsic +@cindex intrinsics, Exit + +@noindent +@example +CALL Exit(@var{Status}) +@end example + +@noindent +@var{Status}: @code{INTEGER}; OPTIONAL; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Exit the program with status @var{Status} after closing open Fortran +i/o units and otherwise behaving as @code{exit(2)}. If @var{Status} +is omitted the canonical `success' value will be returned to the +system. + +@end ifset +@ifset familyF77 +@node Exp Intrinsic +@subsubsection Exp Intrinsic +@cindex Exp intrinsic +@cindex intrinsics, Exp + +@noindent +@example +Exp(@var{X}) +@end example + +@noindent +Exp: @code{REAL} or @code{COMPLEX} function, the exact type being that of argument @var{X}. + +@noindent +@var{X}: @code{REAL} or @code{COMPLEX}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@end ifset +@ifset familyF2U +@node Fdate Intrinsic +@subsubsection Fdate Intrinsic +@cindex Fdate intrinsic +@cindex intrinsics, Fdate + +@noindent +@example +Fdate() +@end example + +@noindent +Fdate: @code{CHARACTER*(*)} function. + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Returns the current date in the same format as @code{CTIME()}. + +Equivalent to: + +@example +CTIME(TIME()) +@end example + +@xref{CTime Intrinsic}. + +@node FGetC Intrinsic +@subsubsection FGetC Intrinsic +@cindex FGetC intrinsic +@cindex intrinsics, FGetC + +@noindent +@example +CALL FGetC(@var{Unit}, @var{C}, @var{Status}) +@end example + +@noindent +@var{Unit}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +@var{C}: @code{CHARACTER}; scalar; INTENT(OUT). + +@noindent +@var{Status}: @code{INTEGER}; scalar; INTENT(OUT). + +@noindent +Intrinsic groups: @code{unix}. + +@end ifset +@ifset familyF77 +@node Float Intrinsic +@subsubsection Float Intrinsic +@cindex Float intrinsic +@cindex intrinsics, Float + +@noindent +@example +Float(@var{A}) +@end example + +@noindent +Float: @code{REAL(KIND=1)} function. + +@noindent +@var{A}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@end ifset +@ifset familyF2U +@node Flush Intrinsic +@subsubsection Flush Intrinsic +@cindex Flush intrinsic +@cindex intrinsics, Flush + +@noindent +@example +CALL Flush(@var{Unit}) +@end example + +@noindent +@var{Unit}: @code{INTEGER}; OPTIONAL; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Flushes Fortran unit(s) currently open for output. +Without the optional argument, all such units are flushed, +otherwise just the unit specified by @var{Unit}. + +@node FNum Intrinsic +@subsubsection FNum Intrinsic +@cindex FNum intrinsic +@cindex intrinsics, FNum + +@noindent +@example +FNum(@var{Unit}) +@end example + +@noindent +FNum: @code{INTEGER(KIND=1)} function. + +@noindent +@var{Unit}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Returns the Unix file descriptor number corresponding to the open +Fortran I/O unit @var{Unit}. +This could be passed to an interface to C I/O routines. + +@node FPutC Intrinsic +@subsubsection FPutC Intrinsic +@cindex FPutC intrinsic +@cindex intrinsics, FPutC + +@noindent +@example +CALL FPutC(@var{Unit}, @var{C}, @var{Status}) +@end example + +@noindent +@var{Unit}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +@var{C}: @code{CHARACTER}; scalar; INTENT(IN). + +@noindent +@var{Status}: @code{INTEGER}; scalar; INTENT(OUT). + +@noindent +Intrinsic groups: @code{unix}. + +@node FSeek Intrinsic +@subsubsection FSeek Intrinsic +@cindex FSeek intrinsic +@cindex intrinsics, FSeek + +@noindent +@example +CALL FSeek(@var{Unit}, @var{Offset}, @var{Whence}, @var{ErrLab}) +@end example + +@noindent +@var{Unit}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +@var{Offset}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +@var{Whence}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +@var{ErrLab}: @samp{*@var{label}}, where @var{label} is the label +of an executable statement; OPTIONAL. + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Attempts to move Fortran unit @var{Unit} to the specified +@var{Offset}: absolute offset if @var{Offset}=0; relative to the +current offset if @var{Offset}=1; relative to the end of the file if +@var{Offset}=2. +It branches to label @var{Whence} if @var{Unit} is +not open or if the call otherwise fails. + +@node FStat Intrinsic +@subsubsection FStat Intrinsic +@cindex FStat intrinsic +@cindex intrinsics, FStat + +@noindent +@example +FStat(@var{Unit}, @var{SArray}) +@end example + +@noindent +FStat: @code{INTEGER(KIND=1)} function. + +@noindent +@var{Unit}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +@var{SArray}: @code{INTEGER(KIND=1)}; DIMENSION(13); INTENT(OUT). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Obtains data about the file open on Fortran I/O unit @var{Unit} and +places them in the array @var{SArray}. +The values in this array are +extracted from the @code{stat} structure as returned by +@code{fstat(2)} q.v., as follows: + +@enumerate +@item +File mode + +@item +Inode number + +@item +ID of device containing directory entry for file + +@item +Device id (if relevant) + +@item +Number of links + +@item +Owner's uid + +@item +Owner's gid + +@item +File size (bytes) + +@item +Last access time + +@item +Last modification time + +@item +Last file status change time + +@item +Preferred i/o block size + +@item +Number of blocks allocated +@end enumerate + +Not all these elements are relevant on all systems. +If an element is not relevant, it is returned as 0. + +Returns 0 on success, otherwise an error number. + +@node FTell Intrinsic +@subsubsection FTell Intrinsic +@cindex FTell intrinsic +@cindex intrinsics, FTell + +@noindent +@example +FTell(@var{Unit}) +@end example + +@noindent +FTell: @code{INTEGER(KIND=1)} function. + +@noindent +@var{Unit}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Returns the current offset of Fortran unit @var{Unit} (or @minus{}1 if +@var{Unit} is not open). + +@node GError Intrinsic +@subsubsection GError Intrinsic +@cindex GError intrinsic +@cindex intrinsics, GError + +@noindent +@example +CALL GError(@var{Message}) +@end example + +@noindent +@var{Message}: @code{CHARACTER}; scalar; INTENT(OUT). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Returns the system error message corresponding to the last system +error (C @code{errno}). + +@node GetArg Intrinsic +@subsubsection GetArg Intrinsic +@cindex GetArg intrinsic +@cindex intrinsics, GetArg + +@noindent +@example +CALL GetArg(@var{Pos}, @var{Value}) +@end example + +@noindent +@var{Pos}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +@var{Value}: @code{CHARACTER}; scalar; INTENT(OUT). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Sets @var{Value} to the @var{Pos}-th command-line argument (or to all +blanks if there are fewer than @var{Value} command-line arguments); +@code{CALL GETARG(0, @var{value})} sets @var{value} to the name of the +program (on systems that support this feature). + +@xref{IArgC Intrinsic}, for information on how to get the number +of arguments. + +@node GetCWD Intrinsic +@subsubsection GetCWD Intrinsic +@cindex GetCWD intrinsic +@cindex intrinsics, GetCWD + +@noindent +@example +GetCWD(@var{Name}) +@end example + +@noindent +GetCWD: @code{INTEGER(KIND=1)} function. + +@noindent +@var{Name}: @code{CHARACTER}; scalar; INTENT(OUT). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Places the current working directory in @var{Name}. +Returns 0 on +success, otherwise an error code. + +@node GetEnv Intrinsic +@subsubsection GetEnv Intrinsic +@cindex GetEnv intrinsic +@cindex intrinsics, GetEnv + +@noindent +@example +CALL GetEnv(@var{Name}, @var{Value}) +@end example + +@noindent +@var{Name}: @code{CHARACTER}; scalar; INTENT(IN). + +@noindent +@var{Value}: @code{CHARACTER}; scalar; INTENT(OUT). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Sets @var{Value} to the value of environment variable given by the +value of @var{Name} (@code{$name} in shell terms) or to blanks if +@code{$name} has not been set. + +@node GetGId Intrinsic +@subsubsection GetGId Intrinsic +@cindex GetGId intrinsic +@cindex intrinsics, GetGId + +@noindent +@example +GetGId() +@end example + +@noindent +GetGId: @code{INTEGER(KIND=1)} function. + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Returns the group id for the current process. + +@node GetLog Intrinsic +@subsubsection GetLog Intrinsic +@cindex GetLog intrinsic +@cindex intrinsics, GetLog + +@noindent +@example +CALL GetLog(@var{Login}) +@end example + +@noindent +@var{Login}: @code{CHARACTER}; scalar; INTENT(OUT). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Returns the login name for the process in @var{Login}. + +@node GetPId Intrinsic +@subsubsection GetPId Intrinsic +@cindex GetPId intrinsic +@cindex intrinsics, GetPId + +@noindent +@example +GetPId() +@end example + +@noindent +GetPId: @code{INTEGER(KIND=1)} function. + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Returns the process id for the current process. + +@node GetUId Intrinsic +@subsubsection GetUId Intrinsic +@cindex GetUId intrinsic +@cindex intrinsics, GetUId + +@noindent +@example +GetUId() +@end example + +@noindent +GetUId: @code{INTEGER(KIND=1)} function. + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Returns the user id for the current process. + +@node GMTime Intrinsic +@subsubsection GMTime Intrinsic +@cindex GMTime intrinsic +@cindex intrinsics, GMTime + +@noindent +@example +CALL GMTime(@var{STime}, @var{TArray}) +@end example + +@noindent +@var{STime}: @code{INTEGER(KIND=1)}; scalar; INTENT(IN). + +@noindent +@var{TArray}: @code{INTEGER(KIND=1)}; DIMENSION(9); INTENT(OUT). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Given a system time value @var{STime}, fills @var{TArray} with values +extracted from it appropriate to the GMT time zone using +@code{gmtime(3)}. + +The array elements are as follows: + +@enumerate +@item +Seconds after the minute, range 0--59 or 0--61 to allow for leap +seconds + +@item +Minutes after the hour, range 0--59 + +@item +Hours past midnight, range 0--23 + +@item +Day of month, range 0--31 + +@item +Number of months since January, range 0--12 + +@item +Number of days since Sunday, range 0--6 + +@item +Years since 1900 + +@item +Days since January 1 + +@item +Daylight savings indicator: positive if daylight savings is in effect, +zero if not, and negative if the information isn't available. +@end enumerate + +@node HostNm Intrinsic +@subsubsection HostNm Intrinsic +@cindex HostNm intrinsic +@cindex intrinsics, HostNm + +@noindent +@example +HostNm(@var{Name}) +@end example + +@noindent +HostNm: @code{INTEGER(KIND=1)} function. + +@noindent +@var{Name}: @code{CHARACTER}; scalar; INTENT(OUT). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Fills @var{Name} with the system's host name returned by +@code{gethostname(2)}, returning 0 on success or an error code. +This function is not available on all systems. + +@end ifset +@ifset familyF77 +@node IAbs Intrinsic +@subsubsection IAbs Intrinsic +@cindex IAbs intrinsic +@cindex intrinsics, IAbs + +@noindent +@example +IAbs(@var{A}) +@end example + +@noindent +IAbs: @code{INTEGER(KIND=1)} function. + +@noindent +@var{A}: @code{INTEGER(KIND=1)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Archaic form of @code{ABS()} that is specific +to one type for @var{A}. +@xref{Abs Intrinsic}. + +@end ifset +@ifset familyASC +@node IAChar Intrinsic +@subsubsection IAChar Intrinsic +@cindex IAChar intrinsic +@cindex intrinsics, IAChar + +@noindent +@example +IAChar(@var{C}) +@end example + +@noindent +IAChar: @code{INTEGER(KIND=1)} function. + +@noindent +@var{C}: @code{CHARACTER}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{f2c}, @code{f90}. + +@noindent +Description: + +Returns the code for the ASCII character in the +first character position of @var{C}. + +@xref{AChar Intrinsic}, for the inverse function. + +@xref{IChar Intrinsic}, for the function corresponding +to the system's native character set. + +@end ifset +@ifset familyMIL +@node IAnd Intrinsic +@subsubsection IAnd Intrinsic +@cindex IAnd intrinsic +@cindex intrinsics, IAnd + +@noindent +@example +IAnd(@var{I}, @var{J}) +@end example + +@noindent +IAnd: @code{INTEGER} function, the exact type being the result of cross-promoting the +types of all the arguments. + +@noindent +@var{I}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +@var{J}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{mil}, @code{f90}, @code{vxt}. + +@noindent +Description: + +Returns value resulting from boolean AND of +pair of bits in each of @var{I} and @var{J}. + +@end ifset +@ifset familyF2U +@node IArgC Intrinsic +@subsubsection IArgC Intrinsic +@cindex IArgC intrinsic +@cindex intrinsics, IArgC + +@noindent +@example +IArgC() +@end example + +@noindent +IArgC: @code{INTEGER(KIND=1)} function. + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Returns the number of command-line arguments. + +This count does not include the specification of the program +name itself. + +@end ifset +@ifset familyMIL +@node IBClr Intrinsic +@subsubsection IBClr Intrinsic +@cindex IBClr intrinsic +@cindex intrinsics, IBClr + +@noindent +@example +IBClr(@var{I}, @var{Pos}) +@end example + +@noindent +IBClr: @code{INTEGER} function, the @samp{KIND=} value of the type being that of argument @var{I}. + +@noindent +@var{I}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +@var{Pos}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{mil}, @code{f90}, @code{vxt}. + +@node IBits Intrinsic +@subsubsection IBits Intrinsic +@cindex IBits intrinsic +@cindex intrinsics, IBits + +@noindent +@example +IBits(@var{I}, @var{Pos}, @var{Len}) +@end example + +@noindent +IBits: @code{INTEGER} function, the @samp{KIND=} value of the type being that of argument @var{I}. + +@noindent +@var{I}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +@var{Pos}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +@var{Len}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{mil}, @code{f90}, @code{vxt}. + +@node IBSet Intrinsic +@subsubsection IBSet Intrinsic +@cindex IBSet intrinsic +@cindex intrinsics, IBSet + +@noindent +@example +IBSet(@var{I}, @var{Pos}) +@end example + +@noindent +IBSet: @code{INTEGER} function, the @samp{KIND=} value of the type being that of argument @var{I}. + +@noindent +@var{I}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +@var{Pos}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{mil}, @code{f90}, @code{vxt}. + +@end ifset +@ifset familyF77 +@node IChar Intrinsic +@subsubsection IChar Intrinsic +@cindex IChar intrinsic +@cindex intrinsics, IChar + +@noindent +@example +IChar(@var{C}) +@end example + +@noindent +IChar: @code{INTEGER(KIND=1)} function. + +@noindent +@var{C}: @code{CHARACTER}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Returns the code for the character in the +first character position of @var{C}. + +Because the system's native character set is used, +the correspondence between character and their codes +is not necessarily the same between GNU Fortran +implementations. + +@xref{Char Intrinsic}, for the inverse function. + +@xref{IAChar Intrinsic}, for the function corresponding +to the ASCII character set. + +@end ifset +@ifset familyF2U +@node IDate Intrinsic +@subsubsection IDate Intrinsic +@cindex IDate intrinsic +@cindex intrinsics, IDate + +@noindent +@example +CALL IDate(@var{TArray}) +@end example + +@noindent +@var{TArray}: @code{INTEGER(KIND=1)}; DIMENSION(3); INTENT(OUT). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Fills @var{TArray} with the numerical values at the current local time +of day, month (in the range 1--12), and year in elements 1, 2, and 3, +respectively. +The year has four significant digits. + +@end ifset +@ifset familyVXT +@node IDate Intrinsic (Form IDATE (VXT)) +@subsubsection IDate Intrinsic (Form IDATE (VXT)) +@cindex IDate intrinsic +@cindex intrinsics, IDate + +@noindent +@example +CALL IDate(@var{D}, @var{M}, @var{Y}) +@end example + +@noindent +@var{D}: @code{INTEGER(KIND=1)}; scalar; INTENT(OUT). + +@noindent +@var{M}: @code{INTEGER(KIND=1)}; scalar; INTENT(OUT). + +@noindent +@var{Y}: @code{INTEGER(KIND=1)}; scalar; INTENT(OUT). + +@noindent +Intrinsic groups: @code{vxt}. + +@noindent +Description: + +Returns the numerical values of the current local time. +The date is returned in @var{D}, +the month in @var{M} (in the range 1--12), +and the year in @var{Y} (in the range 0--99). + +This intrinsic is not recommended, due to the year 2000 approaching. +@xref{IDate Intrinsic}, for information on obtaining more digits +for the current local date. + +@end ifset +@ifset familyF77 +@node IDiM Intrinsic +@subsubsection IDiM Intrinsic +@cindex IDiM intrinsic +@cindex intrinsics, IDiM + +@noindent +@example +IDiM(@var{X}, @var{Y}) +@end example + +@noindent +IDiM: @code{INTEGER(KIND=1)} function. + +@noindent +@var{X}: @code{INTEGER(KIND=1)}; scalar; INTENT(IN). + +@noindent +@var{Y}: @code{INTEGER(KIND=1)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@node IDInt Intrinsic +@subsubsection IDInt Intrinsic +@cindex IDInt intrinsic +@cindex intrinsics, IDInt + +@noindent +@example +IDInt(@var{A}) +@end example + +@noindent +IDInt: @code{INTEGER(KIND=1)} function. + +@noindent +@var{A}: @code{REAL(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Archaic form of @code{INT()} that is specific +to one type for @var{A}. +@xref{Int Intrinsic}. + +@node IDNInt Intrinsic +@subsubsection IDNInt Intrinsic +@cindex IDNInt intrinsic +@cindex intrinsics, IDNInt + +@noindent +@example +IDNInt(@var{A}) +@end example + +@noindent +IDNInt: @code{INTEGER(KIND=1)} function. + +@noindent +@var{A}: @code{REAL(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Archaic form of @code{NINT()} that is specific +to one type for @var{A}. +@xref{NInt Intrinsic}. + +@end ifset +@ifset familyMIL +@node IEOr Intrinsic +@subsubsection IEOr Intrinsic +@cindex IEOr intrinsic +@cindex intrinsics, IEOr + +@noindent +@example +IEOr(@var{I}, @var{J}) +@end example + +@noindent +IEOr: @code{INTEGER} function, the exact type being the result of cross-promoting the +types of all the arguments. + +@noindent +@var{I}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +@var{J}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{mil}, @code{f90}, @code{vxt}. + +@noindent +Description: + +Returns value resulting from boolean exclusive-OR of +pair of bits in each of @var{I} and @var{J}. + +@end ifset +@ifset familyF2U +@node IErrNo Intrinsic +@subsubsection IErrNo Intrinsic +@cindex IErrNo intrinsic +@cindex intrinsics, IErrNo + +@noindent +@example +IErrNo() +@end example + +@noindent +IErrNo: @code{INTEGER(KIND=1)} function. + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Returns the last system error number (corresponding to the C +@code{errno}). + +@end ifset +@ifset familyF77 +@node IFix Intrinsic +@subsubsection IFix Intrinsic +@cindex IFix intrinsic +@cindex intrinsics, IFix + +@noindent +@example +IFix(@var{A}) +@end example + +@noindent +IFix: @code{INTEGER(KIND=1)} function. + +@noindent +@var{A}: @code{INTEGER}, @code{REAL}, or @code{COMPLEX}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Returns @var{A} with the fractional portion of its +magnitude truncated and its sign preserved, converted +to type @code{INTEGER(KIND=1)}. + +If @var{A} is type @code{COMPLEX}, its real part is +truncated and converted. + +@xref{NInt Intrinsic}, for how to convert, rounded to nearest +whole number. + +@xref{AInt Intrinsic}, for how to truncate to whole number +without converting. + +@end ifset +@ifset familyF2C +@node Imag Intrinsic +@subsubsection Imag Intrinsic +@cindex Imag intrinsic +@cindex intrinsics, Imag + +@noindent +@example +Imag(@var{Z}) +@end example + +@noindent +Imag: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{Z}. + +@noindent +@var{Z}: @code{COMPLEX}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{f2c}. + +@noindent +Description: + +The imaginary part of @var{Z} is returned, without conversion. + +@emph{Note:} The way to do this in standard Fortran 90 +is @samp{AIMAG(@var{Z})}. +However, when, for example, @var{Z} is @code{DOUBLE COMPLEX}, +@samp{AIMAG(@var{Z})} means something different for some compilers +that are not true Fortran 90 compilers but offer some +extensions standardized by Fortran 90 (such as the +@code{DOUBLE COMPLEX} type, also known as @code{COMPLEX(KIND=2)}). + +The advantage of @code{IMAG()} is that, while not necessarily +more or less portable than @code{AIMAG()}, it is more likely to +cause a compiler that doesn't support it to produce a diagnostic +than generate incorrect code. + +@xref{REAL() and AIMAG() of Complex}, for more information. + +@end ifset +@ifset familyGNU +@node ImagPart Intrinsic +@subsubsection ImagPart Intrinsic +@cindex ImagPart intrinsic +@cindex intrinsics, ImagPart + +@noindent +@example +ImagPart(@var{Z}) +@end example + +@noindent +ImagPart: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{Z}. + +@noindent +@var{Z}: @code{COMPLEX}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{gnu}. + +@noindent +Description: + +The imaginary part of @var{Z} is returned, without conversion. + +@emph{Note:} The way to do this in standard Fortran 90 +is @samp{AIMAG(@var{Z})}. +However, when, for example, @var{Z} is @code{DOUBLE COMPLEX}, +@samp{AIMAG(@var{Z})} means something different for some compilers +that are not true Fortran 90 compilers but offer some +extensions standardized by Fortran 90 (such as the +@code{DOUBLE COMPLEX} type, also known as @code{COMPLEX(KIND=2)}). + +The advantage of @code{IMAGPART()} is that, while not necessarily +more or less portable than @code{AIMAG()}, it is more likely to +cause a compiler that doesn't support it to produce a diagnostic +than generate incorrect code. + +@xref{REAL() and AIMAG() of Complex}, for more information. + +@end ifset +@ifset familyF77 +@node Index Intrinsic +@subsubsection Index Intrinsic +@cindex Index intrinsic +@cindex intrinsics, Index + +@noindent +@example +Index(@var{String}, @var{Substring}) +@end example + +@noindent +Index: @code{INTEGER(KIND=1)} function. + +@noindent +@var{String}: @code{CHARACTER}; scalar; INTENT(IN). + +@noindent +@var{Substring}: @code{CHARACTER}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@node Int Intrinsic +@subsubsection Int Intrinsic +@cindex Int intrinsic +@cindex intrinsics, Int + +@noindent +@example +Int(@var{A}) +@end example + +@noindent +Int: @code{INTEGER(KIND=1)} function. + +@noindent +@var{A}: @code{INTEGER}, @code{REAL}, or @code{COMPLEX}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Returns @var{A} with the fractional portion of its +magnitude truncated and its sign preserved, converted +to type @code{INTEGER(KIND=1)}. + +If @var{A} is type @code{COMPLEX}, its real part is +truncated and converted. + +@xref{NInt Intrinsic}, for how to convert, rounded to nearest +whole number. + +@xref{AInt Intrinsic}, for how to truncate to whole number +without converting. + +@end ifset +@ifset familyMIL +@node IOr Intrinsic +@subsubsection IOr Intrinsic +@cindex IOr intrinsic +@cindex intrinsics, IOr + +@noindent +@example +IOr(@var{I}, @var{J}) +@end example + +@noindent +IOr: @code{INTEGER} function, the exact type being the result of cross-promoting the +types of all the arguments. + +@noindent +@var{I}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +@var{J}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{mil}, @code{f90}, @code{vxt}. + +@noindent +Description: + +Returns value resulting from boolean OR of +pair of bits in each of @var{I} and @var{J}. + +@end ifset +@ifset familyF2U +@node IRand Intrinsic +@subsubsection IRand Intrinsic +@cindex IRand intrinsic +@cindex intrinsics, IRand + +@noindent +@example +IRand(@var{Flag}) +@end example + +@noindent +IRand: @code{INTEGER(KIND=1)} function. + +@noindent +@var{Flag}: @code{INTEGER}; OPTIONAL; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Returns a uniform quasi-random number up to a system-dependent limit. +If @var{Flag} is 0, the next number in sequence is returned; if +@var{Flag} is 1, the generator is restarted by calling the UNIX function +@samp{srand(0)}; if @var{Flag} has any other value, +it is used as a new seed with @code{srand()}. + +@xref{SRand Intrinsic}. + +@emph{Note:} As typically implemented (by the routine of the same +name in the C library), this random number generator is a very poor +one, though the BSD and GNU libraries provide a much better +implementation than the `traditional' one. +On a different system you almost certainly want to use something better. + +@node IsaTty Intrinsic +@subsubsection IsaTty Intrinsic +@cindex IsaTty intrinsic +@cindex intrinsics, IsaTty + +@noindent +@example +IsaTty(@var{Unit}) +@end example + +@noindent +IsaTty: @code{LOGICAL(KIND=1)} function. + +@noindent +@var{Unit}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Returns @code{.TRUE.} if and only if the Fortran I/O unit +specified by @var{Unit} is connected +to a terminal device. +See @code{isatty(3)}. + +@end ifset +@ifset familyMIL +@node IShft Intrinsic +@subsubsection IShft Intrinsic +@cindex IShft intrinsic +@cindex intrinsics, IShft + +@noindent +@example +IShft(@var{I}, @var{Shift}) +@end example + +@noindent +IShft: @code{INTEGER} function, the @samp{KIND=} value of the type being that of argument @var{I}. + +@noindent +@var{I}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +@var{Shift}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{mil}, @code{f90}, @code{vxt}. + +@node IShftC Intrinsic +@subsubsection IShftC Intrinsic +@cindex IShftC intrinsic +@cindex intrinsics, IShftC + +@noindent +@example +IShftC(@var{I}, @var{Shift}, @var{Size}) +@end example + +@noindent +IShftC: @code{INTEGER} function, the @samp{KIND=} value of the type being that of argument @var{I}. + +@noindent +@var{I}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +@var{Shift}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +@var{Size}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{mil}, @code{f90}, @code{vxt}. + +@end ifset +@ifset familyF77 +@node ISign Intrinsic +@subsubsection ISign Intrinsic +@cindex ISign intrinsic +@cindex intrinsics, ISign + +@noindent +@example +ISign(@var{A}, @var{B}) +@end example + +@noindent +ISign: @code{INTEGER(KIND=1)} function. + +@noindent +@var{A}: @code{INTEGER(KIND=1)}; scalar; INTENT(IN). + +@noindent +@var{B}: @code{INTEGER(KIND=1)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@end ifset +@ifset familyF2U +@node ITime Intrinsic +@subsubsection ITime Intrinsic +@cindex ITime intrinsic +@cindex intrinsics, ITime + +@noindent +@example +CALL ITime(@var{TArray}) +@end example + +@noindent +@var{TArray}: @code{INTEGER(KIND=1)}; DIMENSION(3); INTENT(OUT). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Returns the current local time hour, minutes, and seconds in elements +1, 2, and 3 of @var{TArray}, respectively. + +@node Kill Intrinsic +@subsubsection Kill Intrinsic +@cindex Kill intrinsic +@cindex intrinsics, Kill + +@noindent +@example +CALL Kill(@var{Pid}, @var{Signal}, @var{Status}) +@end example + +@noindent +@var{Pid}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +@var{Signal}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +@var{Status}: @code{INTEGER}; OPTIONAL; scalar; INTENT(OUT). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Sends the signal specified by @var{Signal} to the process @var{Pid}. Returns zero +on success, otherwise an error number. +See @code{kill(2)}. + +@end ifset +@ifset familyF77 +@node Len Intrinsic +@subsubsection Len Intrinsic +@cindex Len intrinsic +@cindex intrinsics, Len + +@noindent +@example +Len(@var{String}) +@end example + +@noindent +Len: @code{INTEGER(KIND=1)} function. + +@noindent +@var{String}: @code{CHARACTER}; scalar. + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@end ifset +@ifset familyF90 +@node Len_Trim Intrinsic +@subsubsection Len_Trim Intrinsic +@cindex Len_Trim intrinsic +@cindex intrinsics, Len_Trim + +@noindent +@example +Len_Trim(@var{String}) +@end example + +@noindent +Len_Trim: @code{INTEGER(KIND=1)} function. + +@noindent +@var{String}: @code{CHARACTER}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{f90}. + +@noindent +Description: + +Returns the index of the last non-blank character in @var{String}. +@code{LNBLNK} and @code{LEN_TRIM} are equivalent. + +@end ifset +@ifset familyF77 +@node LGe Intrinsic +@subsubsection LGe Intrinsic +@cindex LGe intrinsic +@cindex intrinsics, LGe + +@noindent +@example +LGe(@var{String_A}, @var{String_B}) +@end example + +@noindent +LGe: @code{LOGICAL(KIND=1)} function. + +@noindent +@var{String_A}: @code{CHARACTER}; scalar; INTENT(IN). + +@noindent +@var{String_B}: @code{CHARACTER}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@node LGt Intrinsic +@subsubsection LGt Intrinsic +@cindex LGt intrinsic +@cindex intrinsics, LGt + +@noindent +@example +LGt(@var{String_A}, @var{String_B}) +@end example + +@noindent +LGt: @code{LOGICAL(KIND=1)} function. + +@noindent +@var{String_A}: @code{CHARACTER}; scalar; INTENT(IN). + +@noindent +@var{String_B}: @code{CHARACTER}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@end ifset +@ifset familyF2U +@node Link Intrinsic +@subsubsection Link Intrinsic +@cindex Link intrinsic +@cindex intrinsics, Link + +@noindent +@example +CALL Link(@var{Path1}, @var{Path2}, @var{Status}) +@end example + +@noindent +@var{Path1}: @code{CHARACTER}; scalar; INTENT(IN). + +@noindent +@var{Path2}: @code{CHARACTER}; scalar; INTENT(IN). + +@noindent +@var{Status}: @code{INTEGER}; OPTIONAL; scalar; INTENT(OUT). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Makes a (hard) link from @var{Path1} to @var{Path2}. +If the +@var{Status} argument is supplied, it contains 0 on success or an error +code otherwise. +See @code{link(2)}. + +@end ifset +@ifset familyF77 +@node LLe Intrinsic +@subsubsection LLe Intrinsic +@cindex LLe intrinsic +@cindex intrinsics, LLe + +@noindent +@example +LLe(@var{String_A}, @var{String_B}) +@end example + +@noindent +LLe: @code{LOGICAL(KIND=1)} function. + +@noindent +@var{String_A}: @code{CHARACTER}; scalar; INTENT(IN). + +@noindent +@var{String_B}: @code{CHARACTER}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@node LLt Intrinsic +@subsubsection LLt Intrinsic +@cindex LLt intrinsic +@cindex intrinsics, LLt + +@noindent +@example +LLt(@var{String_A}, @var{String_B}) +@end example + +@noindent +LLt: @code{LOGICAL(KIND=1)} function. + +@noindent +@var{String_A}: @code{CHARACTER}; scalar; INTENT(IN). + +@noindent +@var{String_B}: @code{CHARACTER}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@end ifset +@ifset familyF2U +@node LnBlnk Intrinsic +@subsubsection LnBlnk Intrinsic +@cindex LnBlnk intrinsic +@cindex intrinsics, LnBlnk + +@noindent +@example +LnBlnk(@var{String}) +@end example + +@noindent +LnBlnk: @code{INTEGER(KIND=1)} function. + +@noindent +@var{String}: @code{CHARACTER}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Returns the index of the last non-blank character in @var{String}. +@code{LNBLNK} and @code{LEN_TRIM} are equivalent. + +@node Loc Intrinsic +@subsubsection Loc Intrinsic +@cindex Loc intrinsic +@cindex intrinsics, Loc + +@noindent +@example +Loc(@var{Entity}) +@end example + +@noindent +Loc: @code{INTEGER(KIND=0)} function. + +@noindent +@var{Entity}: Any type; cannot be a constant or expression. + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +The @code{LOC()} intrinsic works the +same way as the @code{%LOC()} construct. +@xref{%LOC(),,The @code{%LOC()} Construct}, for +more information. + +@end ifset +@ifset familyF77 +@node Log Intrinsic +@subsubsection Log Intrinsic +@cindex Log intrinsic +@cindex intrinsics, Log + +@noindent +@example +Log(@var{X}) +@end example + +@noindent +Log: @code{REAL} or @code{COMPLEX} function, the exact type being that of argument @var{X}. + +@noindent +@var{X}: @code{REAL} or @code{COMPLEX}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Returns the natural logarithm of @var{X}, which must +be greater than zero or, if type @code{COMPLEX}, must not +be zero. + +@xref{Exp Intrinsic}, for the inverse function. + +@xref{Log10 Intrinsic}, for the base-10 logarithm function. + +@node Log10 Intrinsic +@subsubsection Log10 Intrinsic +@cindex Log10 intrinsic +@cindex intrinsics, Log10 + +@noindent +@example +Log10(@var{X}) +@end example + +@noindent +Log10: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{X}. + +@noindent +@var{X}: @code{REAL}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Returns the natural logarithm of @var{X}, which must +be greater than zero or, if type @code{COMPLEX}, must not +be zero. + +The inverse function is @samp{10. ** LOG10(@var{X})}. + +@xref{Log Intrinsic}, for the natural logarithm function. + +@end ifset +@ifset familyF2U +@node Long Intrinsic +@subsubsection Long Intrinsic +@cindex Long intrinsic +@cindex intrinsics, Long + +@noindent +@example +Long(@var{A}) +@end example + +@noindent +Long: @code{INTEGER(KIND=1)} function. + +@noindent +@var{A}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{unix}. + +@end ifset +@ifset familyF2C +@node LShift Intrinsic +@subsubsection LShift Intrinsic +@cindex LShift intrinsic +@cindex intrinsics, LShift + +@noindent +@example +LShift(@var{I}, @var{Shift}) +@end example + +@noindent +LShift: @code{INTEGER} function, the @samp{KIND=} value of the type being that of argument @var{I}. + +@noindent +@var{I}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +@var{Shift}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{f2c}. + +@end ifset +@ifset familyF2U +@node LStat Intrinsic +@subsubsection LStat Intrinsic +@cindex LStat intrinsic +@cindex intrinsics, LStat + +@noindent +@example +LStat(@var{File}, @var{SArray}) +@end example + +@noindent +LStat: @code{INTEGER(KIND=1)} function. + +@noindent +@var{File}: @code{CHARACTER}; scalar; INTENT(IN). + +@noindent +@var{SArray}: @code{INTEGER(KIND=1)}; DIMENSION(13); INTENT(OUT). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Obtains data about the given @var{File} and places them in the array +@var{SArray}. +If @var{File} is a symbolic link it returns data on the +link itself, so the routine is available only on systems that support +symbolic links. +The values in this array are extracted from the +@code{stat} structure as returned by @code{fstat(2)} q.v., as follows: + +@enumerate +@item +File mode + +@item +Inode number + +@item +ID of device containing directory entry for file + +@item +Device id (if relevant) + +@item +Number of links + +@item +Owner's uid + +@item +Owner's gid + +@item +File size (bytes) + +@item +Last access time + +@item +Last modification time + +@item +Last file status change time + +@item +Preferred i/o block size + +@item +Number of blocks allocated +@end enumerate + +Not all these elements are relevant on all systems. +If an element is not relevant, it is returned as 0. + +Returns 0 on success, otherwise an error number. + +@node LTime Intrinsic +@subsubsection LTime Intrinsic +@cindex LTime intrinsic +@cindex intrinsics, LTime + +@noindent +@example +CALL LTime(@var{STime}, @var{TArray}) +@end example + +@noindent +@var{STime}: @code{INTEGER(KIND=1)}; scalar; INTENT(IN). + +@noindent +@var{TArray}: @code{INTEGER(KIND=1)}; DIMENSION(9); INTENT(OUT). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Given a system time value @var{STime}, fills @var{TArray} with values +extracted from it appropriate to the GMT time zone using +@code{localtime(3)}. + +The array elements are as follows: + +@enumerate +@item +Seconds after the minute, range 0--59 or 0--61 to allow for leap +seconds + +@item +Minutes after the hour, range 0--59 + +@item +Hours past midnight, range 0--23 + +@item +Day of month, range 0--31 + +@item +Number of months since January, range 0--12 + +@item +Number of days since Sunday, range 0--6 + +@item +Years since 1900 + +@item +Days since January 1 + +@item +Daylight savings indicator: positive if daylight savings is in effect, +zero if not, and negative if the information isn't available. +@end enumerate + +@end ifset +@ifset familyF77 +@node Max Intrinsic +@subsubsection Max Intrinsic +@cindex Max intrinsic +@cindex intrinsics, Max + +@noindent +@example +Max(@var{A}-1, @var{A}-2, @dots{}, @var{A}-n) +@end example + +@noindent +Max: @code{INTEGER} or @code{REAL} function, the exact type being the result of cross-promoting the +types of all the arguments. + +@noindent +@var{A}: @code{INTEGER} or @code{REAL}; at least two such arguments must be provided; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Returns the argument with the largest value. + +@xref{Min Intrinsic}, for the opposite function. + +@node Max0 Intrinsic +@subsubsection Max0 Intrinsic +@cindex Max0 intrinsic +@cindex intrinsics, Max0 + +@noindent +@example +Max0(@var{A}-1, @var{A}-2, @dots{}, @var{A}-n) +@end example + +@noindent +Max0: @code{INTEGER(KIND=1)} function. + +@noindent +@var{A}: @code{INTEGER(KIND=1)}; at least two such arguments must be provided; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Archaic form of @code{MAX()} that is specific +to one type for @var{A}. +@xref{Max Intrinsic}. + +@node Max1 Intrinsic +@subsubsection Max1 Intrinsic +@cindex Max1 intrinsic +@cindex intrinsics, Max1 + +@noindent +@example +Max1(@var{A}-1, @var{A}-2, @dots{}, @var{A}-n) +@end example + +@noindent +Max1: @code{INTEGER(KIND=1)} function. + +@noindent +@var{A}: @code{REAL(KIND=1)}; at least two such arguments must be provided; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Archaic form of @code{MAX()} that is specific +to one type for @var{A} and a different return type. +@xref{Max Intrinsic}. + +@end ifset +@ifset familyF2U +@node MClock Intrinsic +@subsubsection MClock Intrinsic +@cindex MClock intrinsic +@cindex intrinsics, MClock + +@noindent +@example +MClock() +@end example + +@noindent +MClock: @code{INTEGER(KIND=2)} function. + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Returns the number of clock ticks since the start of the process. +Only defined on systems with @code{clock(3)} (q.v.). + +@end ifset +@ifset familyF77 +@node Min Intrinsic +@subsubsection Min Intrinsic +@cindex Min intrinsic +@cindex intrinsics, Min + +@noindent +@example +Min(@var{A}-1, @var{A}-2, @dots{}, @var{A}-n) +@end example + +@noindent +Min: @code{INTEGER} or @code{REAL} function, the exact type being the result of cross-promoting the +types of all the arguments. + +@noindent +@var{A}: @code{INTEGER} or @code{REAL}; at least two such arguments must be provided; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Returns the argument with the smallest value. + +@xref{Max Intrinsic}, for the opposite function. + +@node Min0 Intrinsic +@subsubsection Min0 Intrinsic +@cindex Min0 intrinsic +@cindex intrinsics, Min0 + +@noindent +@example +Min0(@var{A}-1, @var{A}-2, @dots{}, @var{A}-n) +@end example + +@noindent +Min0: @code{INTEGER(KIND=1)} function. + +@noindent +@var{A}: @code{INTEGER(KIND=1)}; at least two such arguments must be provided; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Archaic form of @code{MIN()} that is specific +to one type for @var{A}. +@xref{Min Intrinsic}. + +@node Min1 Intrinsic +@subsubsection Min1 Intrinsic +@cindex Min1 intrinsic +@cindex intrinsics, Min1 + +@noindent +@example +Min1(@var{A}-1, @var{A}-2, @dots{}, @var{A}-n) +@end example + +@noindent +Min1: @code{INTEGER(KIND=1)} function. + +@noindent +@var{A}: @code{REAL(KIND=1)}; at least two such arguments must be provided; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Archaic form of @code{MIN()} that is specific +to one type for @var{A} and a different return type. +@xref{Min Intrinsic}. + +@node Mod Intrinsic +@subsubsection Mod Intrinsic +@cindex Mod intrinsic +@cindex intrinsics, Mod + +@noindent +@example +Mod(@var{A}, @var{P}) +@end example + +@noindent +Mod: @code{INTEGER} or @code{REAL} function, the exact type being the result of cross-promoting the +types of all the arguments. + +@noindent +@var{A}: @code{INTEGER} or @code{REAL}; scalar; INTENT(IN). + +@noindent +@var{P}: @code{INTEGER} or @code{REAL}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Returns remainder calculated as: + +@smallexample +@var{A} - (INT(@var{A} / @var{P}) * @var{P}) +@end smallexample + +@var{P} must not be zero. + +@end ifset +@ifset familyMIL +@node MvBits Intrinsic +@subsubsection MvBits Intrinsic +@cindex MvBits intrinsic +@cindex intrinsics, MvBits + +@noindent +@example +CALL MvBits(@var{From}, @var{FromPos}, @var{Len}, @var{TO}, @var{ToPos}) +@end example + +@noindent +@var{From}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +@var{FromPos}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +@var{Len}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +@var{TO}: @code{INTEGER} with same @samp{KIND=} value as for @var{From}; scalar; INTENT(INOUT). + +@noindent +@var{ToPos}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{mil}, @code{f90}, @code{vxt}. + +@end ifset +@ifset familyF77 +@node NInt Intrinsic +@subsubsection NInt Intrinsic +@cindex NInt intrinsic +@cindex intrinsics, NInt + +@noindent +@example +NInt(@var{A}) +@end example + +@noindent +NInt: @code{INTEGER(KIND=1)} function. + +@noindent +@var{A}: @code{REAL}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Returns @var{A} with the fractional portion of its +magnitude eliminated by rounding to the nearest whole +number and with its sign preserved, converted +to type @code{INTEGER(KIND=1)}. + +If @var{A} is type @code{COMPLEX}, its real part is +rounded and converted. + +A fractional portion exactly equal to +@samp{.5} is rounded to the whole number that +is larger in magnitude. +(Also called ``Fortran round''.) + +@xref{Int Intrinsic}, for how to convert, truncate to +whole number. + +@xref{ANInt Intrinsic}, for how to round to nearest whole number +without converting. + +@end ifset +@ifset familyMIL +@node Not Intrinsic +@subsubsection Not Intrinsic +@cindex Not intrinsic +@cindex intrinsics, Not + +@noindent +@example +Not(@var{I}) +@end example + +@noindent +Not: @code{INTEGER} function, the @samp{KIND=} value of the type being that of argument @var{I}. + +@noindent +@var{I}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{mil}, @code{f90}, @code{vxt}. + +@noindent +Description: + +Returns value resulting from boolean NOT of each bit +in @var{I}. + +@end ifset +@ifset familyF2C +@node Or Intrinsic +@subsubsection Or Intrinsic +@cindex Or intrinsic +@cindex intrinsics, Or + +@noindent +@example +Or(@var{I}, @var{J}) +@end example + +@noindent +Or: @code{INTEGER} or @code{LOGICAL} function, the exact type being the result of cross-promoting the +types of all the arguments. + +@noindent +@var{I}: @code{INTEGER} or @code{LOGICAL}; scalar; INTENT(IN). + +@noindent +@var{J}: @code{INTEGER} or @code{LOGICAL}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{f2c}. + +@noindent +Description: + +Returns value resulting from boolean OR of +pair of bits in each of @var{I} and @var{J}. + +@end ifset +@ifset familyF2U +@node PError Intrinsic +@subsubsection PError Intrinsic +@cindex PError intrinsic +@cindex intrinsics, PError + +@noindent +@example +CALL PError(@var{String}) +@end example + +@noindent +@var{String}: @code{CHARACTER}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Prints (on the C @code{stderr} stream) a newline-terminated error +message corresponding to the last system error. +This is prefixed by @var{String}, a colon and a space. +See @code{perror(3)}. + +@node Rand Intrinsic +@subsubsection Rand Intrinsic +@cindex Rand intrinsic +@cindex intrinsics, Rand + +@noindent +@example +Rand(@var{Flag}) +@end example + +@noindent +Rand: @code{REAL(KIND=1)} function. + +@noindent +@var{Flag}: @code{INTEGER}; OPTIONAL; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Returns a uniform quasi-random number between 0 and 1. +If @var{Flag} is 0, the next number in sequence is returned; if +@var{Flag} is 1, the generator is restarted by calling @samp{srand(0)}; +if @var{Flag} has any other value, it is used as a new seed with +@code{srand}. + +@xref{SRand Intrinsic}. + +@emph{Note:} As typically implemented (by the routine of the same +name in the C library), this random number generator is a very poor +one, though the BSD and GNU libraries provide a much better +implementation than the `traditional' one. +On a different system you +almost certainly want to use something better. + +@end ifset +@ifset familyF77 +@node Real Intrinsic +@subsubsection Real Intrinsic +@cindex Real intrinsic +@cindex intrinsics, Real + +@noindent +@example +Real(@var{A}) +@end example + +@noindent +Real: @code{REAL} function. +The exact type is @samp{REAL(KIND=1)} when argument @var{A} is +any type other than @code{COMPLEX}, or when it is @code{COMPLEX(KIND=1)}. +When @var{A} is any @code{COMPLEX} type other than @code{COMPLEX(KIND=1)}, +this intrinsic is valid only when used as the argument to +@code{REAL()}, as explained below. + +@noindent +@var{A}: @code{INTEGER}, @code{REAL}, or @code{COMPLEX}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@noindent +Description: + +Converts @var{A} to @code{REAL(KIND=1)}. + +Use of @code{REAL()} with a @code{COMPLEX} argument +(other than @code{COMPLEX(KIND=1)}) is restricted to the following case: + +@example +REAL(REAL(A)) +@end example + +@noindent +This expression converts the real part of A to +@code{REAL(KIND=1)}. + +@xref{REAL() and AIMAG() of Complex}, for more information. + +@end ifset +@ifset familyGNU +@node RealPart Intrinsic +@subsubsection RealPart Intrinsic +@cindex RealPart intrinsic +@cindex intrinsics, RealPart + +@noindent +@example +RealPart(@var{Z}) +@end example + +@noindent +RealPart: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{Z}. + +@noindent +@var{Z}: @code{COMPLEX}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{gnu}. + +@noindent +Description: + +The real part of @var{Z} is returned, without conversion. + +@emph{Note:} The way to do this in standard Fortran 90 +is @samp{REAL(@var{Z})}. +However, when, for example, @var{Z} is @code{COMPLEX(KIND=2)}, +@samp{REAL(@var{Z})} means something different for some compilers +that are not true Fortran 90 compilers but offer some +extensions standardized by Fortran 90 (such as the +@code{DOUBLE COMPLEX} type, also known as @code{COMPLEX(KIND=2)}). + +The advantage of @code{REALPART()} is that, while not necessarily +more or less portable than @code{REAL()}, it is more likely to +cause a compiler that doesn't support it to produce a diagnostic +than generate incorrect code. + +@xref{REAL() and AIMAG() of Complex}, for more information. + +@end ifset +@ifset familyF2U +@node Rename Intrinsic +@subsubsection Rename Intrinsic +@cindex Rename intrinsic +@cindex intrinsics, Rename + +@noindent +@example +CALL Rename(@var{Path1}, @var{Path2}, @var{Status}) +@end example + +@noindent +@var{Path1}: @code{CHARACTER}; scalar; INTENT(IN). + +@noindent +@var{Path2}: @code{CHARACTER}; scalar; INTENT(IN). + +@noindent +@var{Status}: @code{INTEGER}; OPTIONAL; scalar; INTENT(OUT). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Renames the file @var{Path1} to @var{Path2}. +See @code{rename(2)}. +If the @var{Status} argument is supplied, it contains 0 on success or an +error code otherwise upon return. + +@end ifset +@ifset familyF2C +@node RShift Intrinsic +@subsubsection RShift Intrinsic +@cindex RShift intrinsic +@cindex intrinsics, RShift + +@noindent +@example +RShift(@var{I}, @var{Shift}) +@end example + +@noindent +RShift: @code{INTEGER} function, the @samp{KIND=} value of the type being that of argument @var{I}. + +@noindent +@var{I}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +@var{Shift}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{f2c}. + +@end ifset +@ifset familyVXT +@node Secnds Intrinsic +@subsubsection Secnds Intrinsic +@cindex Secnds intrinsic +@cindex intrinsics, Secnds + +@noindent +@example +Secnds(@var{T}) +@end example + +@noindent +Secnds: @code{REAL(KIND=1)} function. + +@noindent +@var{T}: @code{REAL(KIND=1)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{vxt}. + +@noindent +Description: + +Returns the local time in seconds since midnight minus the value +@var{T}. + +@end ifset +@ifset familyF2U +@node Second Intrinsic +@subsubsection Second Intrinsic +@cindex Second intrinsic +@cindex intrinsics, Second + +@noindent +@example +Second() +@end example + +@noindent +Second: @code{REAL(KIND=1)} function. + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Returns the process' runtime in seconds---the same value as the +UNIX function @code{etime} returns. + +This routine is known from Cray Fortran. + +@node Second Intrinsic (Form SECOND (subroutine)) +@subsubsection Second Intrinsic (Form SECOND (subroutine)) +@cindex Second intrinsic +@cindex intrinsics, Second + +@noindent +@example +CALL Second(@var{Seconds}) +@end example + +@noindent +@var{Seconds}: @code{REAL(KIND=1)}; scalar; INTENT(OUT). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Returns the process' runtime in seconds in @var{Seconds}---the same value +as the UNIX function @code{etime} returns. + +This routine is known from Cray Fortran. + +@node Short Intrinsic +@subsubsection Short Intrinsic +@cindex Short intrinsic +@cindex intrinsics, Short + +@noindent +@example +Short(@var{A}) +@end example + +@noindent +Short: @code{INTEGER(KIND=6)} function. + +@noindent +@var{A}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{unix}. + +@end ifset +@ifset familyF77 +@node Sign Intrinsic +@subsubsection Sign Intrinsic +@cindex Sign intrinsic +@cindex intrinsics, Sign + +@noindent +@example +Sign(@var{A}, @var{B}) +@end example + +@noindent +Sign: @code{INTEGER} or @code{REAL} function, the exact type being the result of cross-promoting the +types of all the arguments. + +@noindent +@var{A}: @code{INTEGER} or @code{REAL}; scalar; INTENT(IN). + +@noindent +@var{B}: @code{INTEGER} or @code{REAL}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@end ifset +@ifset familyF2U +@node Signal Intrinsic +@subsubsection Signal Intrinsic +@cindex Signal intrinsic +@cindex intrinsics, Signal + +@noindent +@example +CALL Signal(@var{Number}, @var{Handler}) +@end example + +@noindent +@var{Number}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +@var{Handler}: Signal handler (@code{INTEGER FUNCTION} or @code{SUBROUTINE}) +or dummy/global @code{INTEGER(KIND=1)} scalar. + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +If @var{Handler} is a an @code{EXTERNAL} routine, arranges for it to be +invoked with a single integer argument (of system-dependent length) +when signal @var{Number} occurs. +If @var{Number} is an integer it can be +used to turn off handling of signal @var{Handler} or revert to its default +action. +See @code{signal(2)}. + +Note that @var{Handler} will be called with C conventions, so its value in +Fortran terms is obtained by applying @code{%loc} (or @var{loc}) to it. + +@end ifset +@ifset familyF77 +@node Sin Intrinsic +@subsubsection Sin Intrinsic +@cindex Sin intrinsic +@cindex intrinsics, Sin + +@noindent +@example +Sin(@var{X}) +@end example + +@noindent +Sin: @code{REAL} or @code{COMPLEX} function, the exact type being that of argument @var{X}. + +@noindent +@var{X}: @code{REAL} or @code{COMPLEX}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@node SinH Intrinsic +@subsubsection SinH Intrinsic +@cindex SinH intrinsic +@cindex intrinsics, SinH + +@noindent +@example +SinH(@var{X}) +@end example + +@noindent +SinH: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{X}. + +@noindent +@var{X}: @code{REAL}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@end ifset +@ifset familyF2U +@node Sleep Intrinsic +@subsubsection Sleep Intrinsic +@cindex Sleep intrinsic +@cindex intrinsics, Sleep + +@noindent +@example +CALL Sleep(@var{Seconds}) +@end example + +@noindent +@var{Seconds}: @code{INTEGER(KIND=1)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Causes the process to pause for @var{Seconds} seconds. +See @code{sleep(2)}. + +@end ifset +@ifset familyF77 +@node Sngl Intrinsic +@subsubsection Sngl Intrinsic +@cindex Sngl intrinsic +@cindex intrinsics, Sngl + +@noindent +@example +Sngl(@var{A}) +@end example + +@noindent +Sngl: @code{REAL(KIND=1)} function. + +@noindent +@var{A}: @code{REAL(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@node SqRt Intrinsic +@subsubsection SqRt Intrinsic +@cindex SqRt intrinsic +@cindex intrinsics, SqRt + +@noindent +@example +SqRt(@var{X}) +@end example + +@noindent +SqRt: @code{REAL} or @code{COMPLEX} function, the exact type being that of argument @var{X}. + +@noindent +@var{X}: @code{REAL} or @code{COMPLEX}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@end ifset +@ifset familyF2U +@node SRand Intrinsic +@subsubsection SRand Intrinsic +@cindex SRand intrinsic +@cindex intrinsics, SRand + +@noindent +@example +CALL SRand(@var{Seed}) +@end example + +@noindent +@var{Seed}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Reinitialises the generator with the seed in @var{Seed}. +@xref{IRand Intrinsic}. @xref{Rand Intrinsic}. + +@node Stat Intrinsic +@subsubsection Stat Intrinsic +@cindex Stat intrinsic +@cindex intrinsics, Stat + +@noindent +@example +Stat(@var{File}, @var{SArray}) +@end example + +@noindent +Stat: @code{INTEGER(KIND=1)} function. + +@noindent +@var{File}: @code{CHARACTER}; scalar; INTENT(IN). + +@noindent +@var{SArray}: @code{INTEGER(KIND=1)}; DIMENSION(13); INTENT(OUT). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Obtains data about the given @var{File} and places them in the array +@var{SArray}. +The values in this array are extracted from the +@code{stat} structure as returned by @code{fstat(2)} q.v., as follows: + +@enumerate +@item +File mode + +@item +Inode number + +@item +ID of device containing directory entry for file + +@item +Device id (if relevant) + +@item +Number of links + +@item +Owner's uid + +@item +Owner's gid + +@item +File size (bytes) + +@item +Last access time + +@item +Last modification time + +@item +Last file status change time + +@item +Preferred i/o block size + +@item +Number of blocks allocated +@end enumerate + +Not all these elements are relevant on all systems. +If an element is not relevant, it is returned as 0. + +Returns 0 on success, otherwise an error number. + +@node SymLnk Intrinsic +@subsubsection SymLnk Intrinsic +@cindex SymLnk intrinsic +@cindex intrinsics, SymLnk + +@noindent +@example +CALL SymLnk(@var{Path1}, @var{Path2}, @var{Status}) +@end example + +@noindent +@var{Path1}: @code{CHARACTER}; scalar; INTENT(IN). + +@noindent +@var{Path2}: @code{CHARACTER}; scalar; INTENT(IN). + +@noindent +@var{Status}: @code{INTEGER}; OPTIONAL; scalar; INTENT(OUT). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Makes a symbolic link from @var{Path1} to @var{Path2}. +If the +@var{Status} argument is supplied, it contains 0 on success or an error +code otherwise. +Available only on systems that support symbolic +links (see @code{symlink(2)}). + +@node System Intrinsic +@subsubsection System Intrinsic +@cindex System intrinsic +@cindex intrinsics, System + +@noindent +@example +CALL System(@var{Command}, @var{Status}) +@end example + +@noindent +@var{Command}: @code{CHARACTER}; scalar; INTENT(IN). + +@noindent +@var{Status}: @code{INTEGER(KIND=1)}; OPTIONAL; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Passes the command @var{Command} to a shell (see @code{system(3)}). +If argument @var{Status} is present, it contains the value returned by +@code{system(3)}, presumably 0 if the shell command succeeded. +Note that which shell is used to invoke the command is system-dependent +and environment-dependent. + +@end ifset +@ifset familyF90 +@node System_Clock Intrinsic +@subsubsection System_Clock Intrinsic +@cindex System_Clock intrinsic +@cindex intrinsics, System_Clock + +@noindent +@example +CALL System_Clock(@var{Count}, @var{Rate}, @var{Max}) +@end example + +@noindent +@var{Count}: @code{INTEGER(KIND=1)}; scalar; INTENT(OUT). + +@noindent +@var{Rate}: @code{INTEGER(KIND=1)}; scalar; INTENT(OUT). + +@noindent +@var{Max}: @code{INTEGER(KIND=1)}; scalar; INTENT(OUT). + +@noindent +Intrinsic groups: @code{f90}. + +@noindent +Description: + +Returns in @var{Count} the current value of the system clock; this is +the value returned by the UNIX function @code{times(2)} +in this implementation, but +isn't in general. +@var{Rate} is the number of clock ticks per second and +@var{Max} is the maximum value this can take, which isn't very useful +in this implementation since it's just the maximum C @code{unsigned +int} value. + +@end ifset +@ifset familyF77 +@node Tan Intrinsic +@subsubsection Tan Intrinsic +@cindex Tan intrinsic +@cindex intrinsics, Tan + +@noindent +@example +Tan(@var{X}) +@end example + +@noindent +Tan: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{X}. + +@noindent +@var{X}: @code{REAL}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@node TanH Intrinsic +@subsubsection TanH Intrinsic +@cindex TanH intrinsic +@cindex intrinsics, TanH + +@noindent +@example +TanH(@var{X}) +@end example + +@noindent +TanH: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{X}. + +@noindent +@var{X}: @code{REAL}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: (standard FORTRAN 77). + +@end ifset +@ifset familyF2U +@node Time Intrinsic +@subsubsection Time Intrinsic +@cindex Time intrinsic +@cindex intrinsics, Time + +@noindent +@example +Time() +@end example + +@noindent +Time: @code{INTEGER(KIND=2)} function. + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Returns the current time encoded as an integer in the manner of +the UNIX function @code{time(3)}. +This value is suitable for passing to @code{CTIME}, +@code{GMTIME}, and @code{LTIME}. + +@end ifset +@ifset familyVXT +@node Time Intrinsic (Form TIME (VXT)) +@subsubsection Time Intrinsic (Form TIME (VXT)) +@cindex Time intrinsic +@cindex intrinsics, Time + +@noindent +@example +CALL Time(@var{Time}) +@end example + +@noindent +@var{Time}: @code{CHARACTER*8}; scalar; INTENT(OUT). + +@noindent +Intrinsic groups: @code{vxt}. + +@end ifset +@ifset familyF2U +@node TtyNam Intrinsic +@subsubsection TtyNam Intrinsic +@cindex TtyNam intrinsic +@cindex intrinsics, TtyNam + +@noindent +@example +TtyNam(@var{Unit}) +@end example + +@noindent +TtyNam: @code{CHARACTER*(*)} function. + +@noindent +@var{Unit}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Returns the name of the terminal device open on logical unit +@var{Unit} or a blank string if @var{Unit} is not connected to a +terminal. + +@node UMask Intrinsic +@subsubsection UMask Intrinsic +@cindex UMask intrinsic +@cindex intrinsics, UMask + +@noindent +@example +CALL UMask(@var{Mask}, @var{Old}) +@end example + +@noindent +@var{Mask}: @code{INTEGER}; scalar; INTENT(IN). + +@noindent +@var{Old}: @code{INTEGER}; OPTIONAL; scalar; INTENT(OUT). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Sets the file creation mask to @var{Old} and returns the old value in +argument @var{Old} if it is supplied. +See @code{umask(2)}. + +@node Unlink Intrinsic +@subsubsection Unlink Intrinsic +@cindex Unlink intrinsic +@cindex intrinsics, Unlink + +@noindent +@example +CALL Unlink(@var{File}, @var{Status}) +@end example + +@noindent +@var{File}: @code{CHARACTER}; scalar; INTENT(IN). + +@noindent +@var{Status}: @code{INTEGER(KIND=1)}; OPTIONAL; scalar; INTENT(OUT). + +@noindent +Intrinsic groups: @code{unix}. + +@noindent +Description: + +Unlink the file @var{File}. +If the @var{Status} argument is supplied, it +contains 0 on success or an error code otherwise. +See @code{unlink(2)}. + +@end ifset +@ifset familyF2C +@node XOr Intrinsic +@subsubsection XOr Intrinsic +@cindex XOr intrinsic +@cindex intrinsics, XOr + +@noindent +@example +XOr(@var{I}, @var{J}) +@end example + +@noindent +XOr: @code{INTEGER} or @code{LOGICAL} function, the exact type being the result of cross-promoting the +types of all the arguments. + +@noindent +@var{I}: @code{INTEGER} or @code{LOGICAL}; scalar; INTENT(IN). + +@noindent +@var{J}: @code{INTEGER} or @code{LOGICAL}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{f2c}. + +@noindent +Description: + +Returns value resulting from boolean exclusive-OR of +pair of bits in each of @var{I} and @var{J}. + +@node ZAbs Intrinsic +@subsubsection ZAbs Intrinsic +@cindex ZAbs intrinsic +@cindex intrinsics, ZAbs + +@noindent +@example +ZAbs(@var{A}) +@end example + +@noindent +ZAbs: @code{REAL(KIND=2)} function. + +@noindent +@var{A}: @code{COMPLEX(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{f2c}. + +@noindent +Description: + +Archaic form of @code{ABS()} that is specific +to one type for @var{A}. +@xref{Abs Intrinsic}. + +@node ZCos Intrinsic +@subsubsection ZCos Intrinsic +@cindex ZCos intrinsic +@cindex intrinsics, ZCos + +@noindent +@example +ZCos(@var{X}) +@end example + +@noindent +ZCos: @code{COMPLEX(KIND=2)} function. + +@noindent +@var{X}: @code{COMPLEX(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{f2c}. + +@node ZExp Intrinsic +@subsubsection ZExp Intrinsic +@cindex ZExp intrinsic +@cindex intrinsics, ZExp + +@noindent +@example +ZExp(@var{X}) +@end example + +@noindent +ZExp: @code{COMPLEX(KIND=2)} function. + +@noindent +@var{X}: @code{COMPLEX(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{f2c}. + +@node ZLog Intrinsic +@subsubsection ZLog Intrinsic +@cindex ZLog intrinsic +@cindex intrinsics, ZLog + +@noindent +@example +ZLog(@var{X}) +@end example + +@noindent +ZLog: @code{COMPLEX(KIND=2)} function. + +@noindent +@var{X}: @code{COMPLEX(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{f2c}. + +@noindent +Description: + +Archaic form of @code{LOG()} that is specific +to one type for @var{X}. +@xref{Log Intrinsic}. + +@node ZSin Intrinsic +@subsubsection ZSin Intrinsic +@cindex ZSin intrinsic +@cindex intrinsics, ZSin + +@noindent +@example +ZSin(@var{X}) +@end example + +@noindent +ZSin: @code{COMPLEX(KIND=2)} function. + +@noindent +@var{X}: @code{COMPLEX(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{f2c}. + +@node ZSqRt Intrinsic +@subsubsection ZSqRt Intrinsic +@cindex ZSqRt intrinsic +@cindex intrinsics, ZSqRt + +@noindent +@example +ZSqRt(@var{X}) +@end example + +@noindent +ZSqRt: @code{COMPLEX(KIND=2)} function. + +@noindent +@var{X}: @code{COMPLEX(KIND=2)}; scalar; INTENT(IN). + +@noindent +Intrinsic groups: @code{f2c}. + +@end ifset diff --git a/gnu/usr.bin/gcc/f/intrin.c b/gnu/usr.bin/gcc/f/intrin.c index 231e795ec77..9b91acf87a2 100644 --- a/gnu/usr.bin/gcc/f/intrin.c +++ b/gnu/usr.bin/gcc/f/intrin.c @@ -1,5 +1,5 @@ /* intrin.c -- Recognize references to intrinsics - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995-1997 Free Software Foundation, Inc. Contributed by James Craig Burley (burley@gnu.ai.mit.edu). This file is part of GNU Fortran. @@ -69,6 +69,7 @@ static ffebad ffeintrin_check_ (ffeintrinImp imp, ffebldOp op, ffebld args, ffeinfoBasictype *xbt, ffeinfoKindtype *xkt, ffetargetCharacterSize *xsz, + bool *check_intrin, ffelexToken t, bool commit); static bool ffeintrin_check_any_ (ffebld arglist); @@ -157,6 +158,7 @@ ffeintrin_check_ (ffeintrinImp imp, ffebldOp op, ffebld args, ffeinfoBasictype *xbt, ffeinfoKindtype *xkt, ffetargetCharacterSize *xsz, + bool *check_intrin, ffelexToken t, bool commit) { @@ -171,6 +173,8 @@ ffeintrin_check_ (ffeintrinImp imp, ffebldOp op, bool need_col; ffeinfoBasictype col_bt = FFEINFO_basictypeNONE; ffeinfoKindtype col_kt = FFEINFO_kindtypeNONE; + int colon = (c[2] == ':') ? 2 : 3; + int argno; /* Check procedure type (function vs. subroutine) against invocation. */ @@ -196,7 +200,7 @@ ffeintrin_check_ (ffeintrinImp imp, ffebldOp op, else firstarg_kt = FFEINFO_kindtype; - for (argc = &c[5], + for (argc = &c[colon + 3], arg = args; *argc != '\0'; ) @@ -206,6 +210,8 @@ ffeintrin_check_ (ffeintrinImp imp, ffebldOp op, char extra = '\0'; char basic; char kind; + int length; + int elements; bool lastarg_complex = FALSE; /* We don't do anything with keywords yet. */ @@ -224,9 +230,31 @@ ffeintrin_check_ (ffeintrinImp imp, ffebldOp op, required = *(argc++); basic = *(argc++); kind = *(argc++); + if (*argc == '[') + { + length = *++argc - '0'; + if (*++argc != ']') + length = 10 * length + (*(argc++) - '0'); + ++argc; + } + else + length = -1; + if (*argc == '(') + { + elements = *++argc - '0'; + if (*++argc != ')') + elements = 10 * elements + (*(argc++) - '0'); + ++argc; + } + else if (*argc == '&') + { + elements = -1; + ++argc; + } + else + elements = 0; if ((*argc == '&') - || (*argc == 'g') - || (*argc == 's') + || (*argc == 'i') || (*argc == 'w') || (*argc == 'x')) extra = *(argc++); @@ -267,7 +295,9 @@ ffeintrin_check_ (ffeintrinImp imp, ffebldOp op, switch (basic) { case 'A': - okay = ffeinfo_basictype (i) == FFEINFO_basictypeCHARACTER; + okay = (ffeinfo_basictype (i) == FFEINFO_basictypeCHARACTER) + && ((length == -1) + || (ffeinfo_size (i) == (ffetargetCharacterSize) length)); break; case 'C': @@ -319,6 +349,29 @@ ffeintrin_check_ (ffeintrinImp imp, ffebldOp op, || (ffeinfo_basictype (i) == FFEINFO_basictypeREAL); break; + case 'g': + okay = ((ffebld_op (a) == FFEBLD_opLABTER) + || (ffebld_op (a) == FFEBLD_opLABTOK)); + elements = -1; + extra = '-'; + break; + + case 's': + okay = (((((ffeinfo_basictype (i) == FFEINFO_basictypeNONE) + && (ffeinfo_kindtype (i) == FFEINFO_kindtypeNONE) + && (ffeinfo_kind (i) == FFEINFO_kindSUBROUTINE)) + || ((ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER) + && (ffeinfo_kindtype (i) == FFEINFO_kindtypeINTEGERDEFAULT) + && (ffeinfo_kind (i) == FFEINFO_kindFUNCTION)) + || (ffeinfo_kind (i) == FFEINFO_kindNONE)) + && ((ffeinfo_where (i) == FFEINFO_whereDUMMY) + || (ffeinfo_where (i) == FFEINFO_whereGLOBAL))) + || ((ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER) + && (ffeinfo_kind (i) == FFEINFO_kindENTITY))); + elements = -1; + extra = '-'; + break; + case '-': default: okay = TRUE; @@ -327,19 +380,35 @@ ffeintrin_check_ (ffeintrinImp imp, ffebldOp op, switch (kind) { - case '1': - okay &= anynum || (ffeinfo_kindtype (i) == 1); - akt = 1; - break; - - case '2': - okay &= anynum || (ffeinfo_kindtype (i) == 2); - akt = 2; - break; - - case '3': - okay &= anynum || (ffeinfo_kindtype (i) == 3); - akt = 3; + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + akt = (kind - '0'); + if ((ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER) + || (ffeinfo_basictype (i) == FFEINFO_basictypeLOGICAL)) + { + switch (akt) + { /* Translate to internal kinds for now! */ + default: + break; + + case 2: + akt = 4; + break; + + case 3: + akt = 2; + break; + + case 4: + akt = 5; + break; + + case 6: + akt = 3; + break; + } + } + okay &= anynum || (ffeinfo_kindtype (i) == akt); break; case 'A': @@ -348,23 +417,32 @@ ffeintrin_check_ (ffeintrinImp imp, ffebldOp op, : firstarg_kt; break; - case 's': - if (((((ffeinfo_basictype (i) != FFEINFO_basictypeNONE) - || (ffeinfo_kindtype (i) != FFEINFO_kindtypeNONE) - || (ffeinfo_kind (i) != FFEINFO_kindSUBROUTINE)) - && ((ffeinfo_basictype (i) != FFEINFO_basictypeINTEGER) - || (ffeinfo_kindtype (i) != FFEINFO_kindtypeINTEGERDEFAULT) - || (ffeinfo_kind (i) != FFEINFO_kindFUNCTION)) - && (ffeinfo_kind (i) != FFEINFO_kindNONE)) - || ((ffeinfo_where (i) != FFEINFO_whereDUMMY) - && (ffeinfo_where (i) != FFEINFO_whereGLOBAL))) - && ((ffeinfo_basictype (i) != FFEINFO_basictypeINTEGER) - || (ffeinfo_kind (i) != FFEINFO_kindENTITY))) + case '*': + default: + break; + } + + switch (elements) + { + ffebld b; + + case -1: + break; + + case 0: + if (ffeinfo_rank (i) != 0) okay = FALSE; break; - case '0': default: + if ((ffeinfo_rank (i) != 1) + || (ffebld_op (a) != FFEBLD_opSYMTER) + || ((b = ffesymbol_arraysize (ffebld_symter (a))) == NULL) + || (ffebld_op (b) != FFEBLD_opCONTER) + || (ffeinfo_basictype (ffebld_info (b)) != FFEINFO_basictypeINTEGER) + || (ffeinfo_kindtype (ffebld_info (b)) != FFEINFO_kindtypeINTEGERDEFAULT) + || (ffebld_constant_integer1 (ffebld_conter (b)) != elements)) + okay = FALSE; break; } @@ -378,28 +456,21 @@ ffeintrin_check_ (ffeintrinImp imp, ffebldOp op, okay = FALSE; break; - case 'g': - if ((ffebld_op (a) != FFEBLD_opLABTER) - && (ffebld_op (a) != FFEBLD_opLABTOK)) - okay = FALSE; - break; - - case 's': - break; - case 'w': case 'x': if ((ffeinfo_kind (i) != FFEINFO_kindENTITY) - || (ffeinfo_rank (i) != 0) || ((ffebld_op (a) != FFEBLD_opSYMTER) && (ffebld_op (a) != FFEBLD_opARRAYREF) && (ffebld_op (a) != FFEBLD_opSUBSTR))) okay = FALSE; break; + case '-': + case 'i': + break; + default: - if ((ffeinfo_kind (i) != FFEINFO_kindENTITY) - || (ffeinfo_rank (i) != 0)) + if (ffeinfo_kind (i) != FFEINFO_kindENTITY) okay = FALSE; break; } @@ -471,7 +542,7 @@ ffeintrin_check_ (ffeintrinImp imp, ffebldOp op, { case 'A': bt = FFEINFO_basictypeCHARACTER; - sz = 1; + sz = (c[2] == '*') ? FFETARGET_charactersizeNONE : 1; break; case 'C': @@ -504,16 +575,34 @@ ffeintrin_check_ (ffeintrinImp imp, ffebldOp op, switch (c[1]) { - case '1': - kt = 1; - break; + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + kt = (c[1] - '0'); + if ((bt == FFEINFO_basictypeINTEGER) + || (bt == FFEINFO_basictypeLOGICAL)) + { + switch (kt) + { /* Translate to internal kinds for now! */ + default: + break; - case '2': - kt = 2; - break; + case 2: + kt = 4; + break; - case '3': - kt = 3; + case 3: + kt = 2; + break; + + case 4: + kt = 5; + break; + + case 6: + kt = 3; + break; + } + } break; case 'C': @@ -522,7 +611,11 @@ ffeintrin_check_ (ffeintrinImp imp, ffebldOp op, kt = 1; break; - case '0': + case 'p': + kt = ffecom_pointer_kind (); + break; + + case '=': need_col = TRUE; /* Fall through. */ case '-': @@ -533,14 +626,14 @@ ffeintrin_check_ (ffeintrinImp imp, ffebldOp op, /* Determine collective type of COL, if there is one. */ - if (need_col || c[3] != '-') + if (need_col || c[colon + 1] != '-') { bool okay = TRUE; bool have_anynum = FALSE; for (arg = args; arg != NULL; - arg = (c[3] == '*') ? ffebld_trail (arg) : NULL) + arg = (c[colon + 1] == '*') ? ffebld_trail (arg) : NULL) { ffebld a = ffebld_head (arg); ffeinfo i; @@ -660,14 +753,19 @@ ffeintrin_check_ (ffeintrinImp imp, ffebldOp op, switch (c[1]) { - case '0': + case '=': if (need_col) kt = col_kt; break; case 'C': - if (need_col && (col_bt == FFEINFO_basictypeCOMPLEX)) - kt = col_kt; + if (col_bt == FFEINFO_basictypeCOMPLEX) + { + if (col_kt != FFEINFO_kindtypeREALDEFAULT) + *check_intrin = TRUE; + if (need_col) + kt = col_kt; + } break; } @@ -677,16 +775,18 @@ ffeintrin_check_ (ffeintrinImp imp, ffebldOp op, /* Now, convert args in the arglist to the final type of the COL. */ - for (argc = &c[5], + for (argno = 0, argc = &c[colon + 3], arg = args; *argc != '\0'; - ) + ++argno) { char optional = '\0'; char required = '\0'; char extra = '\0'; char basic; char kind; + int length; + int elements; bool lastarg_complex = FALSE; /* We don't do anything with keywords yet. */ @@ -705,9 +805,31 @@ ffeintrin_check_ (ffeintrinImp imp, ffebldOp op, required = *(argc++); basic = *(argc++); kind = *(argc++); + if (*argc == '[') + { + length = *++argc - '0'; + if (*++argc != ']') + length = 10 * length + (*(argc++) - '0'); + ++argc; + } + else + length = -1; + if (*argc == '(') + { + elements = *++argc - '0'; + if (*++argc != ')') + elements = 10 * elements + (*(argc++) - '0'); + ++argc; + } + else if (*argc == '&') + { + elements = -1; + ++argc; + } + else + elements = 0; if ((*argc == '&') - || (*argc == 'g') - || (*argc == 's') + || (*argc == 'i') || (*argc == 'w') || (*argc == 'x')) extra = *(argc++); @@ -723,8 +845,8 @@ ffeintrin_check_ (ffeintrinImp imp, ffebldOp op, ffebld a; ffeinfo i; bool anynum; - ffeinfoBasictype abt; - ffeinfoKindtype akt; + ffeinfoBasictype abt = FFEINFO_basictypeNONE; + ffeinfoKindtype akt = FFEINFO_kindtypeNONE; if ((arg == NULL) || (ffebld_head (arg) == NULL)) @@ -741,16 +863,15 @@ ffeintrin_check_ (ffeintrinImp imp, ffebldOp op, /* Determine what the default type for anynum would be. */ - abt = FFEINFO_basictypeNONE; - akt = FFEINFO_kindtypeNONE; if (anynum) { - switch (c[3]) + switch (c[colon + 1]) { case '-': break; - case '1': - if (arg != args) + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + if (argno != (c[colon + 1] - '0')) break; case '*': abt = col_bt; @@ -767,7 +888,9 @@ ffeintrin_check_ (ffeintrinImp imp, ffebldOp op, switch (basic) { case 'A': - okay = ffeinfo_basictype (i) == FFEINFO_basictypeCHARACTER; + okay = (ffeinfo_basictype (i) == FFEINFO_basictypeCHARACTER) + && ((length == -1) + || (ffeinfo_size (i) == (ffetargetCharacterSize) length)); break; case 'C': @@ -819,6 +942,29 @@ ffeintrin_check_ (ffeintrinImp imp, ffebldOp op, || (ffeinfo_basictype (i) == FFEINFO_basictypeREAL); break; + case 'g': + okay = ((ffebld_op (a) == FFEBLD_opLABTER) + || (ffebld_op (a) == FFEBLD_opLABTOK)); + elements = -1; + extra = '-'; + break; + + case 's': + okay = (((((ffeinfo_basictype (i) == FFEINFO_basictypeNONE) + && (ffeinfo_kindtype (i) == FFEINFO_kindtypeNONE) + && (ffeinfo_kind (i) == FFEINFO_kindSUBROUTINE)) + || ((ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER) + && (ffeinfo_kindtype (i) == FFEINFO_kindtypeINTEGERDEFAULT) + && (ffeinfo_kind (i) == FFEINFO_kindFUNCTION)) + || (ffeinfo_kind (i) == FFEINFO_kindNONE)) + && ((ffeinfo_where (i) == FFEINFO_whereDUMMY) + || (ffeinfo_where (i) == FFEINFO_whereGLOBAL))) + || ((ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER) + && (ffeinfo_kind (i) == FFEINFO_kindENTITY))); + elements = -1; + extra = '-'; + break; + case '-': default: okay = TRUE; @@ -827,19 +973,35 @@ ffeintrin_check_ (ffeintrinImp imp, ffebldOp op, switch (kind) { - case '1': - okay &= anynum || (ffeinfo_kindtype (i) == 1); - akt = 1; - break; - - case '2': - okay &= anynum || (ffeinfo_kindtype (i) == 2); - akt = 2; - break; - - case '3': - okay &= anynum || (ffeinfo_kindtype (i) == 3); - akt = 3; + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + akt = (kind - '0'); + if ((ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER) + || (ffeinfo_basictype (i) == FFEINFO_basictypeLOGICAL)) + { + switch (akt) + { /* Translate to internal kinds for now! */ + default: + break; + + case 2: + akt = 4; + break; + + case 3: + akt = 2; + break; + + case 4: + akt = 5; + break; + + case 6: + akt = 3; + break; + } + } + okay &= anynum || (ffeinfo_kindtype (i) == akt); break; case 'A': @@ -848,23 +1010,32 @@ ffeintrin_check_ (ffeintrinImp imp, ffebldOp op, : firstarg_kt; break; - case 's': - if (((((ffeinfo_basictype (i) != FFEINFO_basictypeNONE) - || (ffeinfo_kindtype (i) != FFEINFO_kindtypeNONE) - || (ffeinfo_kind (i) != FFEINFO_kindSUBROUTINE)) - && ((ffeinfo_basictype (i) != FFEINFO_basictypeINTEGER) - || (ffeinfo_kindtype (i) != FFEINFO_kindtypeINTEGERDEFAULT) - || (ffeinfo_kind (i) != FFEINFO_kindFUNCTION)) - && (ffeinfo_kind (i) != FFEINFO_kindNONE)) - || ((ffeinfo_where (i) != FFEINFO_whereDUMMY) - && (ffeinfo_where (i) != FFEINFO_whereGLOBAL))) - && ((ffeinfo_basictype (i) != FFEINFO_basictypeINTEGER) - || (ffeinfo_kind (i) != FFEINFO_kindENTITY))) + case '*': + default: + break; + } + + switch (elements) + { + ffebld b; + + case -1: + break; + + case 0: + if (ffeinfo_rank (i) != 0) okay = FALSE; break; - case '0': default: + if ((ffeinfo_rank (i) != 1) + || (ffebld_op (a) != FFEBLD_opSYMTER) + || ((b = ffesymbol_arraysize (ffebld_symter (a))) == NULL) + || (ffebld_op (b) != FFEBLD_opCONTER) + || (ffeinfo_basictype (ffebld_info (b)) != FFEINFO_basictypeINTEGER) + || (ffeinfo_kindtype (ffebld_info (b)) != FFEINFO_kindtypeINTEGERDEFAULT) + || (ffebld_constant_integer1 (ffebld_conter (b)) != elements)) + okay = FALSE; break; } @@ -878,28 +1049,21 @@ ffeintrin_check_ (ffeintrinImp imp, ffebldOp op, okay = FALSE; break; - case 'g': - if ((ffebld_op (a) != FFEBLD_opLABTER) - && (ffebld_op (a) != FFEBLD_opLABTOK)) - okay = FALSE; - break; - - case 's': - break; - case 'w': case 'x': if ((ffeinfo_kind (i) != FFEINFO_kindENTITY) - || (ffeinfo_rank (i) != 0) || ((ffebld_op (a) != FFEBLD_opSYMTER) && (ffebld_op (a) != FFEBLD_opARRAYREF) && (ffebld_op (a) != FFEBLD_opSUBSTR))) okay = FALSE; break; + case '-': + case 'i': + break; + default: - if ((ffeinfo_kind (i) != FFEINFO_kindENTITY) - || (ffeinfo_rank (i) != 0)) + if (ffeinfo_kind (i) != FFEINFO_kindENTITY) okay = FALSE; break; } @@ -937,7 +1101,7 @@ ffeintrin_check_ (ffeintrinImp imp, ffebldOp op, FFEEXPR_contextLET); ffebld_set_head (arg, a); } - else if ((c[3] == '*') && commit) + else if ((c[colon + 1] == '*') && commit) { /* This is where we promote types to the consensus type for the COL. Maybe this is where -fpedantic @@ -1109,10 +1273,14 @@ ffeintrin_fulfill_generic (ffebld *expr, ffeinfo *info, ffelexToken t) if (state == FFE_intrinsicstateDELETED) continue; - if (timp == FFEINTRIN_impNONE) - tname = ffeintrin_specs_[tspec].name; - else - tname = ffeintrin_imps_[timp].name; + tname = ffeintrin_specs_[tspec].name; + + if (timp != FFEINTRIN_impNONE) + { + if (!(ffeintrin_imps_[timp].control[0] == '-') + != !(ffebld_op (*expr) == FFEBLD_opSUBRREF)) + continue; /* Form of reference must match form of specific. */ + } if (state == FFE_intrinsicstateDISABLED) terror = FFEBAD_INTRINSIC_DISABLED; @@ -1122,7 +1290,7 @@ ffeintrin_fulfill_generic (ffebld *expr, ffeinfo *info, ffelexToken t) { terror = ffeintrin_check_ (timp, ffebld_op (*expr), ffebld_right (*expr), - &tbt, &tkt, &tsz, t, FALSE); + &tbt, &tkt, &tsz, NULL, t, FALSE); if (terror == FFEBAD) { if (imp != FFEINTRIN_impNONE) @@ -1215,7 +1383,7 @@ ffeintrin_fulfill_generic (ffebld *expr, ffeinfo *info, ffelexToken t) } error = ffeintrin_check_ (imp, ffebld_op (*expr), ffebld_right (*expr), - &bt, &kt, &sz, t, TRUE); + &bt, &kt, &sz, NULL, t, TRUE); assert (error == FFEBAD); *info = ffeinfo_new (bt, kt, @@ -1243,8 +1411,9 @@ ffeintrin_fulfill_generic (ffebld *expr, ffeinfo *info, ffelexToken t) ffebld expr; // FUNCREF or SUBRREF with no info (caller // gets it from the modified info structure). ffeinfo info; // Already filled in, will be overwritten. + bool check_intrin; // May be omitted, else set TRUE if intrinsic needs checking. ffelexToken token; // Used for error message. - ffeintrin_fulfill_specific (&expr, &info, token); + ffeintrin_fulfill_specific (&expr, &info, &check_intrin, token); Based on the specific id, determine whether the arg list is valid (number, type, rank, and kind of args) and fill in the info structure @@ -1254,7 +1423,8 @@ ffeintrin_fulfill_generic (ffebld *expr, ffeinfo *info, ffelexToken t) accordingly. */ void -ffeintrin_fulfill_specific (ffebld *expr, ffeinfo *info, ffelexToken t) +ffeintrin_fulfill_specific (ffebld *expr, ffeinfo *info, + bool *check_intrin, ffelexToken t) { ffebld symter; ffebldOp op; @@ -1277,6 +1447,8 @@ ffeintrin_fulfill_specific (ffebld *expr, ffeinfo *info, ffelexToken t) state = ffeintrin_state_family (ffeintrin_specs_[spec].family); imp = ffeintrin_specs_[spec].implementation; + if (check_intrin != NULL) + *check_intrin = FALSE; any = ffeintrin_check_any_ (ffebld_right (*expr)); @@ -1288,8 +1460,10 @@ ffeintrin_fulfill_specific (ffebld *expr, ffeinfo *info, ffelexToken t) { error = ffeintrin_check_ (imp, ffebld_op (*expr), ffebld_right (*expr), - &bt, &kt, &sz, t, TRUE); + &bt, &kt, &sz, check_intrin, t, TRUE); } + else + error = FFEBAD; /* Not really needed, but quiet -Wuninitialized. */ if (any || (error != FFEBAD)) { @@ -1300,7 +1474,7 @@ ffeintrin_fulfill_specific (ffebld *expr, ffeinfo *info, ffelexToken t) ffebad_start (error); ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - if (imp == FFEINTRIN_impNONE) + if (spec != FFEINTRIN_specNONE) name = ffeintrin_specs_[spec].name; else name = ffeintrin_imps_[imp].name; @@ -1350,8 +1524,9 @@ ffeintrin_init_0 () char *p1; char *p2; char *p3; + int colon; - if (!ffe_is_do_internal_checks()) + if (!ffe_is_do_internal_checks ()) return; assert (FFEINTRIN_gen == ARRAY_SIZE (ffeintrin_gens_)); @@ -1368,6 +1543,9 @@ ffeintrin_init_0 () for (i = 0; ((size_t) i) < ARRAY_SIZE (ffeintrin_names_); ++i) { + assert ((ffeintrin_names_[i].generic == FFEINTRIN_genNONE) + || (ffeintrin_names_[i].specific == FFEINTRIN_specNONE)); + p1 = ffeintrin_names_[i].name_uc; p2 = ffeintrin_names_[i].name_lc; p3 = ffeintrin_names_[i].name_ic; @@ -1407,31 +1585,44 @@ ffeintrin_init_0 () continue; } if ((c[1] != '-') - && (c[1] != '0') - && (c[1] != '1') - && (c[1] != '2') - && (c[1] != '3') - && (c[1] != 'C')) + && (c[1] != '=') + && ((c[1] < '1') + || (c[1] > '9')) + && (c[1] != 'C') + && (c[1] != 'p')) { fprintf (stderr, "%s: bad return-kind-type\n", ffeintrin_imps_[i].name); continue; } - if ((c[2] != ':') || (c[4] != ':')) + if (c[2] == ':') + colon = 2; + else + { + if (c[2] != '*') + { + fprintf (stderr, "%s: bad return-modifier\n", + ffeintrin_imps_[i].name); + continue; + } + colon = 3; + } + if ((c[colon] != ':') || (c[colon + 2] != ':')) { fprintf (stderr, "%s: bad control\n", ffeintrin_imps_[i].name); continue; } - if ((c[3] != '-') - && (c[3] != '*') - && (c[3] != '1')) + if ((c[colon + 1] != '-') + && (c[colon + 1] != '*') + && ((c[colon + 1] < '0') + || (c[colon + 1] > '9'))) { fprintf (stderr, "%s: bad COL-spec\n", ffeintrin_imps_[i].name); continue; } - c += 5; + c += (colon + 3); while (c[0] != '\0') { while ((c[0] != '=') @@ -1453,7 +1644,7 @@ ffeintrin_init_0 () || (c[1] == 'p')) ++c; if (((c[1] != '-') - && (c[1] != 'A') + && (c[1] != 'A') && (c[1] != 'C') && (c[1] != 'I') && (c[1] != 'L') @@ -1461,20 +1652,49 @@ ffeintrin_init_0 () && (c[1] != 'B') && (c[1] != 'F') && (c[1] != 'N') - && (c[1] != 'S')) - || ((c[2] != '0') - && (c[2] != '1') - && (c[2] != '2') - && (c[2] != '3') - && (c[2] != 'A') - && (c[2] != 's'))) + && (c[1] != 'S') + && (c[1] != 'g') + && (c[1] != 's')) + || ((c[2] != '*') + && ((c[2] < '1') + || (c[2] > '9')) + && (c[2] != 'A'))) { fprintf (stderr, "%s: bad arg-type\n", ffeintrin_imps_[i].name); break; } + if (c[3] == '[') + { + if (((c[4] < '0') || (c[4] > '9')) + || ((c[5] != ']') + && (++c, (c[4] < '0') || (c[4] > '9') + || (c[5] != ']')))) + { + fprintf (stderr, "%s: bad arg-len\n", + ffeintrin_imps_[i].name); + break; + } + c += 3; + } + if (c[3] == '(') + { + if (((c[4] < '0') || (c[4] > '9')) + || ((c[5] != ')') + && (++c, (c[4] < '0') || (c[4] > '9') + || (c[5] != ')')))) + { + fprintf (stderr, "%s: bad arg-rank\n", + ffeintrin_imps_[i].name); + break; + } + c += 3; + } + else if ((c[3] == '&') + && (c[4] == '&')) + ++c; if ((c[3] == '&') - || (c[3] == 's') + || (c[3] == 'i') || (c[3] == 'w') || (c[3] == 'x')) ++c; @@ -1522,26 +1742,20 @@ ffeintrin_is_actualarg (ffeintrinSpec spec) ffeintrinGen gen; // (TRUE only) Generic id of intrinsic. ffeintrinSpec spec; // (TRUE only) Specific id of intrinsic. ffeintrinImp imp; // (TRUE only) Implementation id of intrinsic. - ffeinfoKind kind; // (TRUE:) kindFUNCTION, kindSUBROUTINE, - // or kindNONE; (FALSE:) kindANY, kindNONE. - if (ffeintrin_is_intrinsic (name, t, &gen, &spec, &imp, &kind)) + if (ffeintrin_is_intrinsic (name, t, explicit, + &gen, &spec, &imp)) // is an intrinsic, use gen, spec, imp, and - // kind accordingly. - - If FALSE is returned, kindANY says that the intrinsic exists but is - not valid for some reason (disabled or unimplemented), in which case a - diagnostic was generated (assuming t == NULL). */ + // kind accordingly. */ bool ffeintrin_is_intrinsic (char *name, ffelexToken t, bool explicit, ffeintrinGen *xgen, ffeintrinSpec *xspec, - ffeintrinImp *ximp, ffeinfoKind *xkind) + ffeintrinImp *ximp) { struct _ffeintrin_name_ *intrinsic; ffeintrinGen gen; ffeintrinSpec spec; ffeintrinImp imp; - ffeinfoKind kind; ffeIntrinsicState state; bool disabled = FALSE; bool unimpl = FALSE; @@ -1566,6 +1780,8 @@ ffeintrin_is_intrinsic (char *name, ffelexToken t, bool explicit, ffeintrinSpec tspec; bool ok = FALSE; + name = ffeintrin_gens_[gen].name; + for (i = 0; (((size_t) i) < ARRAY_SIZE (ffeintrin_gens_[gen].specs)) && ((tspec @@ -1606,6 +1822,8 @@ ffeintrin_is_intrinsic (char *name, ffelexToken t, bool explicit, if (spec != FFEINTRIN_specNONE) { + name = ffeintrin_specs_[spec].name; + if (((state = ffeintrin_state_family (ffeintrin_specs_[spec].family)) == FFE_intrinsicstateDELETED) || (!explicit @@ -1635,31 +1853,25 @@ ffeintrin_is_intrinsic (char *name, ffelexToken t, bool explicit, { ffebad_start (disabled ? FFEBAD_INTRINSIC_DISABLED - : FFEBAD_INTRINSIC_UNIMPL); + : FFEBAD_INTRINSIC_UNIMPLW); ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); ffebad_string (name); ffebad_finish (); } - if (disabled || unimpl) - *xkind = FFEINFO_kindANY; - else - *xkind = FFEINFO_kindNONE; return FALSE; } /* Determine whether intrinsic is function or subroutine. If no specific - id, scan list of possible specifics for generic to get consensus. Must - be unanimous, at least for now. */ + id, scan list of possible specifics for generic to get consensus. If + not unanimous, or clear from the context, return NONE. */ if (spec == FFEINTRIN_specNONE) { int i; ffeintrinSpec tspec; ffeintrinImp timp; - ffeinfoKind tkind; - - kind = FFEINFO_kindNONE; + bool at_least_one_ok = FALSE; for (i = 0; (((size_t) i) < ARRAY_SIZE (ffeintrin_gens_[gen].specs)) @@ -1667,31 +1879,31 @@ ffeintrin_is_intrinsic (char *name, ffelexToken t, bool explicit, = ffeintrin_gens_[gen].specs[i]) != FFEINTRIN_specNONE); ++i) { + if (((state = ffeintrin_state_family (ffeintrin_specs_[tspec].family)) + == FFE_intrinsicstateDELETED) + || (state == FFE_intrinsicstateDISABLED)) + continue; + if ((timp = ffeintrin_specs_[tspec].implementation) == FFEINTRIN_impNONE) continue; - if (ffeintrin_imps_[timp].control[0] == '-') - tkind = FFEINFO_kindSUBROUTINE; - else - tkind = FFEINFO_kindFUNCTION; + at_least_one_ok = TRUE; + break; + } - if ((kind == tkind) || (kind == FFEINFO_kindNONE)) - kind = tkind; - else - assert ("what kind of proc am i?" == NULL); + if (!at_least_one_ok) + { + *xgen = FFEINTRIN_genNONE; + *xspec = FFEINTRIN_specNONE; + *ximp = FFEINTRIN_impNONE; + return FALSE; } } - else /* Have specific, use that. */ - kind - = (ffeintrin_imps_[imp].control[0] == '-') - ? FFEINFO_kindSUBROUTINE - : FFEINFO_kindFUNCTION; *xgen = gen; *xspec = spec; *ximp = imp; - *xkind = kind; return TRUE; } @@ -1757,10 +1969,8 @@ ffeintrin_state_family (ffeintrinFamily family) state = ffe_state_max (state, ffe_intrinsic_state_mil ()); return state; - case FFEINTRIN_familyDCP: - state = ffe_intrinsic_state_vxt (); - state = ffe_state_max (state, ffe_intrinsic_state_f90 ()); - state = ffe_state_max (state, ffe_intrinsic_state_dcp ()); + case FFEINTRIN_familyGNU: + state = ffe_intrinsic_state_gnu (); return state; case FFEINTRIN_familyF90: @@ -1774,17 +1984,12 @@ ffeintrin_state_family (ffeintrinFamily family) case FFEINTRIN_familyFVZ: state = ffe_intrinsic_state_f2c (); state = ffe_state_max (state, ffe_intrinsic_state_vxt ()); - state = ffe_state_max (state, ffe_intrinsic_state_dcp ()); return state; case FFEINTRIN_familyF2C: state = ffe_intrinsic_state_f2c (); return state; - case FFEINTRIN_familyF2Z: - state = ffe_intrinsic_state_f2c (); - return state; - case FFEINTRIN_familyF2U: state = ffe_intrinsic_state_unix (); return state; diff --git a/gnu/usr.bin/gcc/f/intrin.def b/gnu/usr.bin/gcc/f/intrin.def index d0031414c70..17eba78404a 100644 --- a/gnu/usr.bin/gcc/f/intrin.def +++ b/gnu/usr.bin/gcc/f/intrin.def @@ -1,23 +1,6 @@ /* intrin.def -- Public #include File (module.h template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.ai.mit.edu). - -This file is part of GNU Fortran. - -GNU Fortran is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Fortran is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. + The Free Software Foundation has released this file into the + public domain. Owning Modules: intrin.c @@ -30,6 +13,7 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA DEFNAME ("ABORT", "abort", "Abort", genNONE, specABORT) /* UNIX */ DEFNAME ("ABS", "abs", "Abs", genNONE, specABS) +DEFNAME ("ACCESS", "access", "Access", genNONE, specACCESS) /* UNIX */ DEFNAME ("ACHAR", "achar", "AChar", genNONE, specACHAR) /* F90, F2C */ DEFNAME ("ACOS", "acos", "ACos", genNONE, specACOS) DEFNAME ("ACOSD", "acosd", "ACosD", genNONE, specACOSD) /* VXT */ @@ -60,6 +44,12 @@ DEFNAME ("ATAN", "atan", "ATan", genNONE, specATAN) DEFNAME ("ATAN2", "atan2", "ATan2", genNONE, specATAN2) DEFNAME ("ATAN2D", "atan2d", "ATan2D", genNONE, specATAN2D) /* VXT */ DEFNAME ("ATAND", "atand", "ATanD", genNONE, specATAND) /* VXT */ +DEFNAME ("BESJ0", "besj0", "BesJ0", genNONE, specBESJ0) /* UNIX */ +DEFNAME ("BESJ1", "besj1", "BesJ1", genNONE, specBESJ1) /* UNIX */ +DEFNAME ("BESJN", "besjn", "BesJN", genNONE, specBESJN) /* UNIX */ +DEFNAME ("BESY0", "besy0", "BesY0", genNONE, specBESY0) /* UNIX */ +DEFNAME ("BESY1", "besy1", "BesY1", genNONE, specBESY1) /* UNIX */ +DEFNAME ("BESYN", "besyn", "BesYN", genNONE, specBESYN) /* UNIX */ DEFNAME ("BITEST", "bitest", "BITest", genNONE, specBITEST) /* VXT */ DEFNAME ("BIT_SIZE", "bit_size", "Bit_Size", genNONE, specBIT_SIZE) /* F90 */ DEFNAME ("BJTEST", "bjtest", "BJTest", genNONE, specBJTEST) /* VXT */ @@ -75,8 +65,11 @@ DEFNAME ("CDSQRT", "cdsqrt", "CDSqRt", genNONE, specCDSQRT) /* VXT */ DEFNAME ("CEILING", "ceiling", "Ceiling", genNONE, specCEILING) /* F90 */ DEFNAME ("CEXP", "cexp", "CExp", genNONE, specCEXP) DEFNAME ("CHAR", "char", "Char", genNONE, specCHAR) +DEFNAME ("CHDIR", "chdir", "ChDir", genNONE, specCHDIR) /* UNIX */ +DEFNAME ("CHMOD", "chmod", "ChMod", genNONE, specCHMOD) /* UNIX */ DEFNAME ("CLOG", "clog", "CLog", genNONE, specCLOG) DEFNAME ("CMPLX", "cmplx", "Cmplx", genNONE, specCMPLX) +DEFNAME ("COMPLEX", "complex", "Complex", genNONE, specCOMPLEX) DEFNAME ("CONJG", "conjg", "Conjg", genNONE, specCONJG) DEFNAME ("COS", "cos", "Cos", genNONE, specCOS) DEFNAME ("COSD", "cosd", "CosD", genNONE, specCOSD) /* VXT */ @@ -85,6 +78,7 @@ DEFNAME ("COUNT", "count", "Count", genNONE, specCOUNT) /* F90 */ DEFNAME ("CSHIFT", "cshift", "CShift", genNONE, specCSHIFT) /* F90 */ DEFNAME ("CSIN", "csin", "CSin", genNONE, specCSIN) DEFNAME ("CSQRT", "csqrt", "CSqRt", genNONE, specCSQRT) +DEFNAME ("CTIME", "ctime", "CTime", genNONE, specCTIME) /* UNIX */ DEFNAME ("DABS", "dabs", "DAbs", genNONE, specDABS) DEFNAME ("DACOS", "dacos", "DACos", genNONE, specDACOS) DEFNAME ("DACOSD", "dacosd", "DACosD", genNONE, specDACOSD) /* VXT */ @@ -94,7 +88,14 @@ DEFNAME ("DATAN", "datan", "DATan", genNONE, specDATAN) DEFNAME ("DATAN2", "datan2", "DATan2", genNONE, specDATAN2) DEFNAME ("DATAN2D", "datan2d", "DATan2D", genNONE, specDATAN2D) /* VXT */ DEFNAME ("DATAND", "datand", "DATanD", genNONE, specDATAND) /* VXT */ +DEFNAME ("DATE", "date", "Date", genNONE, specDATE) /* VXT */ DEFNAME ("DATE_AND_TIME", "date_and_time", "Date_and_Time", genNONE, specDATE_AND_TIME) /* F90 */ +DEFNAME ("DBESJ0", "dbesj0", "DbesJ0", genNONE, specDBESJ0) /* UNIX */ +DEFNAME ("DBESJ1", "dbesj1", "DbesJ1", genNONE, specDBESJ1) /* UNIX */ +DEFNAME ("DBESJN", "dbesjn", "DbesJN", genNONE, specDBESJN) /* UNIX */ +DEFNAME ("DBESY0", "dbesy0", "DbesY0", genNONE, specDBESY0) /* UNIX */ +DEFNAME ("DBESY1", "dbesy1", "DbesY1", genNONE, specDBESY1) /* UNIX */ +DEFNAME ("DBESYN", "dbesyn", "DbesYN", genNONE, specDBESYN) /* UNIX */ DEFNAME ("DBLE", "dble", "Dble", genNONE, specDBLE) DEFNAME ("DBLEQ", "dbleq", "DbleQ", genNONE, specDBLEQ) /* VXT */ DEFNAME ("DCMPLX", "dcmplx", "DCmplx", genNONE, specDCMPLX) /* F2C, VXT */ @@ -102,7 +103,7 @@ DEFNAME ("DCONJG", "dconjg", "DConjg", genNONE, specDCONJG) /* F2C, VXT */ DEFNAME ("DCOS", "dcos", "DCos", genNONE, specDCOS) DEFNAME ("DCOSD", "dcosd", "DCosD", genNONE, specDCOSD) /* VXT */ DEFNAME ("DCOSH", "dcosh", "DCosH", genNONE, specDCOSH) -DEFNAME ("DDIM", "ddim", "DDim", genNONE, specDDIM) +DEFNAME ("DDIM", "ddim", "DDiM", genNONE, specDDIM) DEFNAME ("DERF", "derf", "DErF", genNONE, specDERF) /* UNIX */ DEFNAME ("DERFC", "derfc", "DErFC", genNONE, specDERFC) /* UNIX */ DEFNAME ("DEXP", "dexp", "DExp", genNONE, specDEXP) @@ -111,7 +112,7 @@ DEFNAME ("DFLOTI", "dfloti", "DFlotI", genNONE, specDFLOTI) /* VXT */ DEFNAME ("DFLOTJ", "dflotj", "DFlotJ", genNONE, specDFLOTJ) /* VXT */ DEFNAME ("DIGITS", "digits", "Digits", genNONE, specDIGITS) /* F90 */ DEFNAME ("DIM", "dim", "DiM", genNONE, specDIM) -DEFNAME ("DIMAG", "dimag", "DImag", genNONE, specDIMAG) /* VXT */ +DEFNAME ("DIMAG", "dimag", "DImag", genNONE, specDIMAG) /* F2C, VXT */ DEFNAME ("DINT", "dint", "DInt", genNONE, specDINT) DEFNAME ("DLOG", "dlog", "DLog", genNONE, specDLOG) DEFNAME ("DLOG10", "dlog10", "DLog10", genNONE, specDLOG10) @@ -130,29 +131,44 @@ DEFNAME ("DSQRT", "dsqrt", "DSqRt", genNONE, specDSQRT) DEFNAME ("DTAN", "dtan", "DTan", genNONE, specDTAN) DEFNAME ("DTAND", "dtand", "DTanD", genNONE, specDTAND) /* VXT */ DEFNAME ("DTANH", "dtanh", "DTanH", genNONE, specDTANH) +DEFNAME ("DTIME", "dtime", "Dtime", genNONE, specDTIME) /* UNIX */ DEFNAME ("EOSHIFT", "eoshift", "EOShift", genNONE, specEOSHIFT) /* F90 */ DEFNAME ("EPSILON", "epsilon", "Epsilon", genNONE, specEPSILON) /* F90 */ DEFNAME ("ERF", "erf", "ErF", genNONE, specERF) /* UNIX */ DEFNAME ("ERFC", "erfc", "ErFC", genNONE, specERFC) /* UNIX */ +DEFNAME ("ETIME", "etime", "ETime", genNONE, specETIME) /* UNIX */ DEFNAME ("EXIT", "exit", "Exit", genNONE, specEXIT) /* UNIX */ DEFNAME ("EXP", "exp", "Exp", genNONE, specEXP) DEFNAME ("EXPONENT", "exponent", "Exponent", genNONE, specEXPONENT) /* F90 */ +DEFNAME ("FDATE", "fdate", "Fdate", genNONE, specFDATE) /* UNIX */ +DEFNAME ("FGETC", "fgetc", "FGetC", genNONE, specFGETC) /* UNIX */ DEFNAME ("FLOAT", "float", "Float", genNONE, specFLOAT) DEFNAME ("FLOATI", "floati", "FloatI", genNONE, specFLOATI) /* VXT */ DEFNAME ("FLOATJ", "floatj", "FloatJ", genNONE, specFLOATJ) /* VXT */ DEFNAME ("FLOOR", "floor", "Floor", genNONE, specFLOOR) /* F90 */ DEFNAME ("FLUSH", "flush", "Flush", genNONE, specFLUSH) /* UNIX */ +DEFNAME ("FNUM", "fnum", "FNum", genNONE, specFNUM) /* UNIX */ DEFNAME ("FPABSP", "fpabsp", "FPAbsP", genFPABSP, specNONE) /* F2C */ DEFNAME ("FPEXPN", "fpexpn", "FPExpn", genFPEXPN, specNONE) /* F2C */ DEFNAME ("FPFRAC", "fpfrac", "FPFrac", genFPFRAC, specNONE) /* F2C */ DEFNAME ("FPMAKE", "fpmake", "FPMake", genFPMAKE, specNONE) /* F2C */ DEFNAME ("FPRRSP", "fprrsp", "FPRRSp", genFPRRSP, specNONE) /* F2C */ DEFNAME ("FPSCAL", "fpscal", "FPScal", genFPSCAL, specNONE) /* F2C */ +DEFNAME ("FPUTC", "fputc", "FPutC", genNONE, specFPUTC) /* UNIX */ DEFNAME ("FRACTION", "fraction", "Fraction", genNONE, specFRACTION) /* F90 */ DEFNAME ("FSEEK", "fseek", "FSeek", genNONE, specFSEEK) /* UNIX */ +DEFNAME ("FSTAT", "fstat", "FStat", genNONE, specFSTAT) /* UNIX */ DEFNAME ("FTELL", "ftell", "FTell", genNONE, specFTELL) /* UNIX */ +DEFNAME ("GERROR", "gerror", "GError", genNONE, specGERROR) /* UNIX */ DEFNAME ("GETARG", "getarg", "GetArg", genNONE, specGETARG) /* UNIX */ +DEFNAME ("GETCWD", "getcwd", "GetCWD", genNONE, specGETCWD) /* UNIX */ DEFNAME ("GETENV", "getenv", "GetEnv", genNONE, specGETENV) /* UNIX */ +DEFNAME ("GETGID", "getgid", "GetGId", genNONE, specGETGID) /* UNIX */ +DEFNAME ("GETLOG", "getlog", "GetLog", genNONE, specGETLOG) /* UNIX */ +DEFNAME ("GETPID", "getpid", "GetPId", genNONE, specGETPID) /* UNIX */ +DEFNAME ("GETUID", "getuid", "GetUId", genNONE, specGETUID) /* UNIX */ +DEFNAME ("GMTIME", "gmtime", "GMTime", genNONE, specGMTIME) /* UNIX */ +DEFNAME ("HOSTNM", "hostnm", "HostNm", genNONE, specHOSTNM) /* UNIX */ DEFNAME ("HUGE", "huge", "Huge", genNONE, specHUGE) /* F90 */ DEFNAME ("IABS", "iabs", "IAbs", genNONE, specIABS) DEFNAME ("IACHAR", "iachar", "IAChar", genNONE, specIACHAR) /* F90, F2C */ @@ -162,10 +178,12 @@ DEFNAME ("IBCLR", "ibclr", "IBClr", genNONE, specIBCLR) /* F90, VXT */ DEFNAME ("IBITS", "ibits", "IBits", genNONE, specIBITS) /* F90, VXT */ DEFNAME ("IBSET", "ibset", "IBSet", genNONE, specIBSET) /* F90, VXT */ DEFNAME ("ICHAR", "ichar", "IChar", genNONE, specICHAR) +DEFNAME ("IDATE", "idate", "IDate", genIDATE, specNONE) /* UNIX, VXT */ DEFNAME ("IDIM", "idim", "IDiM", genNONE, specIDIM) DEFNAME ("IDINT", "idint", "IDInt", genNONE, specIDINT) DEFNAME ("IDNINT", "idnint", "IDNInt", genNONE, specIDNINT) DEFNAME ("IEOR", "ieor", "IEOr", genNONE, specIEOR) /* F90, VXT */ +DEFNAME ("IERRNO", "ierrno", "IErrNo", genNONE, specIERRNO) /* UNIX */ DEFNAME ("IFIX", "ifix", "IFix", genNONE, specIFIX) DEFNAME ("IIABS", "iiabs", "IIAbs", genNONE, specIIABS) /* VXT */ DEFNAME ("IIAND", "iiand", "IIAnd", genNONE, specIIAND) /* VXT */ @@ -173,7 +191,7 @@ DEFNAME ("IIBCLR", "iibclr", "IIBClr", genNONE, specIIBCLR) /* VXT */ DEFNAME ("IIBITS", "iibits", "IIBits", genNONE, specIIBITS) /* VXT */ DEFNAME ("IIBSET", "iibset", "IIBSet", genNONE, specIIBSET) /* VXT */ DEFNAME ("IIDIM", "iidim", "IIDiM", genNONE, specIIDIM) /* VXT */ -DEFNAME ("IIDINT", "iidint", "IIDint", genNONE, specIIDINT) /* VXT */ +DEFNAME ("IIDINT", "iidint", "IIDInt", genNONE, specIIDINT) /* VXT */ DEFNAME ("IIDNNT", "iidnnt", "IIDNnt", genNONE, specIIDNNT) /* VXT */ DEFNAME ("IIEOR", "iieor", "IIEOr", genNONE, specIIEOR) /* VXT */ DEFNAME ("IIFIX", "iifix", "IIFix", genNONE, specIIFIX) /* VXT */ @@ -185,6 +203,7 @@ DEFNAME ("IISHFT", "iishft", "IIShft", genNONE, specNONE) /* VXT */ DEFNAME ("IISHFTC", "iishftc", "IIShftC", genNONE, specIISHFTC) /* VXT */ DEFNAME ("IISIGN", "iisign", "IISign", genNONE, specIISIGN) /* VXT */ DEFNAME ("IMAG", "imag", "Imag", genNONE, specIMAG) /* F2C */ +DEFNAME ("IMAGPART", "imagpart", "ImagPart", genNONE, specIMAGPART) /* GNU */ DEFNAME ("IMAX0", "imax0", "IMax0", genNONE, specIMAX0) /* VXT */ DEFNAME ("IMAX1", "imax1", "IMax1", genNONE, specIMAX1) /* VXT */ DEFNAME ("IMIN0", "imin0", "IMin0", genNONE, specIMIN0) /* VXT */ @@ -195,9 +214,12 @@ DEFNAME ("ININT", "inint", "INInt", genNONE, specININT) /* VXT */ DEFNAME ("INOT", "inot", "INot", genNONE, specINOT) /* VXT */ DEFNAME ("INT", "int", "Int", genNONE, specINT) DEFNAME ("IOR", "ior", "IOr", genNONE, specIOR) /* F90, VXT */ +DEFNAME ("IRAND", "irand", "IRand", genNONE, specIRAND) /* UNIX */ +DEFNAME ("ISATTY", "isatty", "IsaTty", genNONE, specISATTY) /* UNIX */ DEFNAME ("ISHFT", "ishft", "IShft", genNONE, specISHFT) /* F90 */ DEFNAME ("ISHFTC", "ishftc", "IShftC", genNONE, specISHFTC) /* F90, VXT */ DEFNAME ("ISIGN", "isign", "ISign", genNONE, specISIGN) +DEFNAME ("ITIME", "itime", "ITime", genNONE, specITIME) /* UNIX */ DEFNAME ("IZEXT", "izext", "IZExt", genNONE, specIZEXT) /* VXT */ DEFNAME ("JIABS", "jiabs", "JIAbs", genNONE, specJIABS) /* VXT */ DEFNAME ("JIAND", "jiand", "JIAnd", genNONE, specJIAND) /* VXT */ @@ -205,7 +227,7 @@ DEFNAME ("JIBCLR", "jibclr", "JIBClr", genNONE, specJIBCLR) /* VXT */ DEFNAME ("JIBITS", "jibits", "JIBits", genNONE, specJIBITS) /* VXT */ DEFNAME ("JIBSET", "jibset", "JIBSet", genNONE, specJIBSET) /* VXT */ DEFNAME ("JIDIM", "jidim", "JIDiM", genNONE, specJIDIM) /* VXT */ -DEFNAME ("JIDINT", "jidint", "JIDint", genNONE, specJIDINT) /* VXT */ +DEFNAME ("JIDINT", "jidint", "JIDInt", genNONE, specJIDINT) /* VXT */ DEFNAME ("JIDNNT", "jidnnt", "JIDNnt", genNONE, specJIDNNT) /* VXT */ DEFNAME ("JIEOR", "jieor", "JIEOr", genNONE, specJIEOR) /* VXT */ DEFNAME ("JIFIX", "jifix", "JIFix", genNONE, specJIFIX) /* VXT */ @@ -224,19 +246,25 @@ DEFNAME ("JMOD", "jmod", "JMod", genNONE, specJMOD) /* VXT */ DEFNAME ("JNINT", "jnint", "JNInt", genNONE, specJNINT) /* VXT */ DEFNAME ("JNOT", "jnot", "JNot", genNONE, specJNOT) /* VXT */ DEFNAME ("JZEXT", "jzext", "JZExt", genNONE, specJZEXT) /* VXT */ +DEFNAME ("KILL", "kill", "Kill", genNONE, specKILL) /* UNIX */ DEFNAME ("KIND", "kind", "Kind", genNONE, specKIND) /* F90 */ DEFNAME ("LBOUND", "lbound", "LBound", genNONE, specLBOUND) /* F90 */ DEFNAME ("LEN", "len", "Len", genNONE, specLEN) DEFNAME ("LEN_TRIM", "len_trim", "Len_Trim", genNONE, specLEN_TRIM) /* F90 */ DEFNAME ("LGE", "lge", "LGe", genNONE, specLGE) DEFNAME ("LGT", "lgt", "LGt", genNONE, specLGT) +DEFNAME ("LINK", "link", "Link", genNONE, specLINK) /* UNIX */ DEFNAME ("LLE", "lle", "LLe", genNONE, specLLE) DEFNAME ("LLT", "llt", "LLt", genNONE, specLLT) +DEFNAME ("LNBLNK", "lnblnk", "LnBlnk", genNONE, specLNBLNK) /* UNIX */ DEFNAME ("LOC", "loc", "Loc", genNONE, specLOC) /* VXT */ DEFNAME ("LOG", "log", "Log", genNONE, specLOG) DEFNAME ("LOG10", "log10", "Log10", genNONE, specLOG10) DEFNAME ("LOGICAL", "logical", "Logical", genNONE, specLOGICAL) /* F90 */ +DEFNAME ("LONG", "long", "Long", genNONE, specLONG) /* UNIX */ DEFNAME ("LSHIFT", "lshift", "LShift", genNONE, specLSHIFT) /* F2C */ +DEFNAME ("LSTAT", "lstat", "LStat", genNONE, specLSTAT) /* UNIX */ +DEFNAME ("LTIME", "ltime", "LTime", genNONE, specLTIME) /* UNIX */ DEFNAME ("MATMUL", "matmul", "MatMul", genNONE, specMATMUL) /* F90 */ DEFNAME ("MAX", "max", "Max", genNONE, specMAX) DEFNAME ("MAX0", "max0", "Max0", genNONE, specMAX0) @@ -244,6 +272,7 @@ DEFNAME ("MAX1", "max1", "Max1", genNONE, specMAX1) DEFNAME ("MAXEXPONENT", "maxexponent", "MaxExponent", genNONE, specMAXEXPONENT) /* F90 */ DEFNAME ("MAXLOC", "maxloc", "MaxLoc", genNONE, specMAXLOC) /* F90 */ DEFNAME ("MAXVAL", "maxval", "MaxVal", genNONE, specMAXVAL) /* F90 */ +DEFNAME ("MCLOCK", "mclock", "MClock", genNONE, specMCLOCK) /* UNIX */ DEFNAME ("MERGE", "merge", "Merge", genNONE, specMERGE) /* F90 */ DEFNAME ("MIN", "min", "Min", genNONE, specMIN) DEFNAME ("MIN0", "min0", "Min0", genNONE, specMIN0) @@ -259,6 +288,7 @@ DEFNAME ("NINT", "nint", "NInt", genNONE, specNINT) DEFNAME ("NOT", "not", "Not", genNONE, specNOT) /* F2C, F90, VXT */ DEFNAME ("OR", "or", "Or", genNONE, specOR) /* F2C */ DEFNAME ("PACK", "pack", "Pack", genNONE, specPACK) /* F90 */ +DEFNAME ("PERROR", "perror", "PError", genNONE, specPERROR) /* UNIX */ DEFNAME ("PRECISION", "precision", "Precision", genNONE, specPRECISION) /* F90 */ DEFNAME ("PRESENT", "present", "Present", genNONE, specPRESENT) /* F90 */ DEFNAME ("PRODUCT", "product", "Product", genNONE, specPRODUCT) /* F90 */ @@ -294,41 +324,55 @@ DEFNAME ("QTAN", "qtan", "QTan", genNONE, specQTAN) /* VXT */ DEFNAME ("QTAND", "qtand", "QTanD", genNONE, specQTAND) /* VXT */ DEFNAME ("QTANH", "qtanh", "QTanH", genNONE, specQTANH) /* VXT */ DEFNAME ("RADIX", "radix", "Radix", genNONE, specRADIX) /* F90 */ +DEFNAME ("RAND", "rand", "Rand", genNONE, specRAND) /* UNIX */ DEFNAME ("RANDOM_NUMBER", "random_number", "Random_Number", genNONE, specRANDOM_NUMBER) /* F90 */ DEFNAME ("RANDOM_SEED", "random_seed", "Random_Seed", genNONE, specRANDOM_SEED) /* F90 */ DEFNAME ("RANGE", "range", "Range", genNONE, specRANGE) /* F90 */ DEFNAME ("REAL", "real", "Real", genNONE, specREAL) +DEFNAME ("REALPART", "realpart", "RealPart", genNONE, specREALPART) /* GNU */ +DEFNAME ("RENAME", "rename", "Rename", genNONE, specRENAME) /* UNIX */ DEFNAME ("REPEAT", "repeat", "Repeat", genNONE, specREPEAT) /* F90 */ DEFNAME ("RESHAPE", "reshape", "Reshape", genNONE, specRESHAPE) /* F90 */ DEFNAME ("RRSPACING", "rrspacing", "RRSpacing", genNONE, specRRSPACING) /* F90 */ DEFNAME ("RSHIFT", "rshift", "RShift", genNONE, specRSHIFT) /* F2C */ DEFNAME ("SCALE", "scale", "Scale", genNONE, specSCALE) /* F90 */ DEFNAME ("SCAN", "scan", "Scan", genNONE, specSCAN) /* F90 */ +DEFNAME ("SECNDS", "secnds", "Secnds", genNONE, specSECNDS) /* VXT */ +DEFNAME ("SECOND", "second", "Second", genSECOND, specNONE) /* UNIX */ DEFNAME ("SELECTED_INT_KIND", "selected_int_kind", "Selected_Int_Kind", genNONE, specSEL_INT_KIND) /* F90 */ DEFNAME ("SELECTED_REAL_KIND", "selected_real_kind", "Selected_Real_Kind", genNONE, specSEL_REAL_KIND) /* F90 */ DEFNAME ("SET_EXPONENT", "set_exponent", "Set_Exponent", genNONE, specSET_EXPONENT) /* F90 */ DEFNAME ("SHAPE", "shape", "Shape", genNONE, specSHAPE) /* F90 */ +DEFNAME ("SHORT", "short", "Short", genNONE, specSHORT) /* UNIX */ DEFNAME ("SIGN", "sign", "Sign", genNONE, specSIGN) DEFNAME ("SIGNAL", "signal", "Signal", genNONE, specSIGNAL) /* UNIX */ DEFNAME ("SIN", "sin", "Sin", genNONE, specSIN) DEFNAME ("SIND", "sind", "SinD", genNONE, specSIND) /* VXT */ DEFNAME ("SINH", "sinh", "SinH", genNONE, specSINH) +DEFNAME ("SLEEP", "sleep", "Sleep", genNONE, specSLEEP) /* UNIX */ DEFNAME ("SNGL", "sngl", "Sngl", genNONE, specSNGL) DEFNAME ("SNGLQ", "snglq", "SnglQ", genNONE, specSNGLQ) /* VXT */ DEFNAME ("SPACING", "spacing", "Spacing", genNONE, specSPACING) /* F90 */ DEFNAME ("SPREAD", "spread", "Spread", genNONE, specSPREAD) /* F90 */ DEFNAME ("SQRT", "sqrt", "SqRt", genNONE, specSQRT) +DEFNAME ("SRAND", "srand", "SRand", genNONE, specSRAND) /* UNIX */ +DEFNAME ("STAT", "stat", "Stat", genNONE, specSTAT) /* UNIX */ DEFNAME ("SUM", "sum", "Sum", genNONE, specSUM) /* F90 */ +DEFNAME ("SYMLNK", "symlnk", "SymLnk", genNONE, specSYMLNK) /* UNIX */ DEFNAME ("SYSTEM", "system", "System", genNONE, specSYSTEM) /* UNIX */ DEFNAME ("SYSTEM_CLOCK", "system_clock", "System_Clock", genNONE, specSYSTEM_CLOCK) /* F90 */ DEFNAME ("TAN", "tan", "Tan", genNONE, specTAN) DEFNAME ("TAND", "tand", "TanD", genNONE, specTAND) /* VXT */ DEFNAME ("TANH", "tanh", "TanH", genNONE, specTANH) +DEFNAME ("TIME", "time", "Time", genTIME, specNONE) /* UNIX, VXT */ DEFNAME ("TINY", "tiny", "Tiny", genNONE, specTINY) /* F90 */ DEFNAME ("TRANSFER", "transfer", "Transfer", genNONE, specTRANSFER) /* F90 */ DEFNAME ("TRANSPOSE", "transpose", "Transpose", genNONE, specTRANSPOSE) /* F90 */ DEFNAME ("TRIM", "trim", "Trim", genNONE, specTRIM) /* F90 */ +DEFNAME ("TTYNAM", "ttynam", "TtyNam", genNONE, specTTYNAM) /* UNIX */ DEFNAME ("UBOUND", "ubound", "UBound", genNONE, specUBOUND) /* F90 */ +DEFNAME ("UMASK", "umask", "UMask", genNONE, specUMASK) /* UNIX */ +DEFNAME ("UNLINK", "unlink", "Unlink", genNONE, specUNLINK) /* UNIX */ DEFNAME ("UNPACK", "unpack", "Unpack", genNONE, specUNPACK) /* F90 */ DEFNAME ("VERIFY", "verify", "Verify", genNONE, specVERIFY) /* F90 */ DEFNAME ("XOR", "xor", "XOr", genNONE, specXOR) /* F2C */ @@ -348,31 +392,43 @@ DEFNAME ("ZSQRT", "zsqrt", "ZSqRt", genNONE, specZSQRT) /* F2C */ being used. Also, this includes the placeholder intrinsics that have no specific versions, but we want to reserve the names for now. */ -DEFGEN (FFEINTRIN_genFPABSP, "FPABSP", /* F2C */ +DEFGEN (FPABSP, "FPABSP", /* F2C */ FFEINTRIN_specNONE, FFEINTRIN_specNONE ) -DEFGEN (FFEINTRIN_genFPEXPN, "FPEXPN", /* F2C */ +DEFGEN (FPEXPN, "FPEXPN", /* F2C */ FFEINTRIN_specNONE, FFEINTRIN_specNONE ) -DEFGEN (FFEINTRIN_genFPFRAC, "FPFRAC", /* F2C */ +DEFGEN (FPFRAC, "FPFRAC", /* F2C */ FFEINTRIN_specNONE, FFEINTRIN_specNONE ) -DEFGEN (FFEINTRIN_genFPMAKE, "FPMAKE", /* F2C */ +DEFGEN (FPMAKE, "FPMAKE", /* F2C */ FFEINTRIN_specNONE, FFEINTRIN_specNONE ) -DEFGEN (FFEINTRIN_genFPRRSP, "FPRRSP", /* F2C */ +DEFGEN (FPRRSP, "FPRRSP", /* F2C */ FFEINTRIN_specNONE, FFEINTRIN_specNONE ) -DEFGEN (FFEINTRIN_genFPSCAL, "FPSCAL", /* F2C */ +DEFGEN (FPSCAL, "FPSCAL", /* F2C */ FFEINTRIN_specNONE, FFEINTRIN_specNONE ) -DEFGEN (FFEINTRIN_genNONE, "none", +DEFGEN (IDATE, "IDATE (UNIX or VXT)", /* UNIX/VXT */ + FFEINTRIN_specIDATE, + FFEINTRIN_specIDATEVXT + ) +DEFGEN (SECOND, "SECOND (function or subroutine)", /* UNIX/CRAY */ + FFEINTRIN_specSECONDFUNC, + FFEINTRIN_specSECONDSUBR + ) +DEFGEN (TIME, "TIME (UNIX or VXT)", /* UNIX/VXT */ + FFEINTRIN_specTIME, + FFEINTRIN_specTIMEVXT + ) +DEFGEN (NONE, "none", FFEINTRIN_specNONE, FFEINTRIN_specNONE ) @@ -386,1844 +442,2228 @@ DEFGEN (FFEINTRIN_genNONE, "none", The second boolean argument specifies whether the intrinsic is allowed by the standard to be passed as an actual argument. */ -DEFSPEC (FFEINTRIN_specABS, +DEFSPEC (ABS, "ABS", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impABS ) -DEFSPEC (FFEINTRIN_specACOS, +DEFSPEC (ACOS, "ACOS", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impACOS ) -DEFSPEC (FFEINTRIN_specAIMAG, +DEFSPEC (AIMAG, "AIMAG", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impAIMAG ) -DEFSPEC (FFEINTRIN_specAINT, +DEFSPEC (AINT, "AINT", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impAINT ) -DEFSPEC (FFEINTRIN_specALOG, +DEFSPEC (ALOG, "ALOG", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impALOG ) -DEFSPEC (FFEINTRIN_specALOG10, +DEFSPEC (ALOG10, "ALOG10", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impALOG10 ) -DEFSPEC (FFEINTRIN_specAMAX0, +DEFSPEC (AMAX0, "AMAX0", FALSE, FFEINTRIN_familyF77, FFEINTRIN_impAMAX0 ) -DEFSPEC (FFEINTRIN_specAMAX1, +DEFSPEC (AMAX1, "AMAX1", FALSE, FFEINTRIN_familyF77, FFEINTRIN_impAMAX1 ) -DEFSPEC (FFEINTRIN_specAMIN0, +DEFSPEC (AMIN0, "AMIN0", FALSE, FFEINTRIN_familyF77, FFEINTRIN_impAMIN0 ) -DEFSPEC (FFEINTRIN_specAMIN1, +DEFSPEC (AMIN1, "AMIN1", FALSE, FFEINTRIN_familyF77, FFEINTRIN_impAMIN1 ) -DEFSPEC (FFEINTRIN_specAMOD, +DEFSPEC (AMOD, "AMOD", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impAMOD ) -DEFSPEC (FFEINTRIN_specANINT, +DEFSPEC (ANINT, "ANINT", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impANINT ) -DEFSPEC (FFEINTRIN_specASIN, +DEFSPEC (ASIN, "ASIN", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impASIN ) -DEFSPEC (FFEINTRIN_specATAN, +DEFSPEC (ATAN, "ATAN", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impATAN ) -DEFSPEC (FFEINTRIN_specATAN2, +DEFSPEC (ATAN2, "ATAN2", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impATAN2 ) -DEFSPEC (FFEINTRIN_specCABS, +DEFSPEC (CABS, "CABS", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impCABS ) -DEFSPEC (FFEINTRIN_specCCOS, +DEFSPEC (CCOS, "CCOS", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impCCOS ) -DEFSPEC (FFEINTRIN_specCEXP, +DEFSPEC (CEXP, "CEXP", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impCEXP ) -DEFSPEC (FFEINTRIN_specCHAR, +DEFSPEC (CHAR, "CHAR", FALSE, FFEINTRIN_familyF77, FFEINTRIN_impCHAR ) -DEFSPEC (FFEINTRIN_specCLOG, +DEFSPEC (CLOG, "CLOG", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impCLOG ) -DEFSPEC (FFEINTRIN_specCMPLX, +DEFSPEC (CMPLX, "CMPLX", FALSE, FFEINTRIN_familyF77, FFEINTRIN_impCMPLX ) -DEFSPEC (FFEINTRIN_specCONJG, +DEFSPEC (CONJG, "CONJG", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impCONJG ) -DEFSPEC (FFEINTRIN_specCOS, +DEFSPEC (COS, "COS", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impCOS ) -DEFSPEC (FFEINTRIN_specCOSH, +DEFSPEC (COSH, "COSH", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impCOSH ) -DEFSPEC (FFEINTRIN_specCSIN, +DEFSPEC (CSIN, "CSIN", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impCSIN ) -DEFSPEC (FFEINTRIN_specCSQRT, +DEFSPEC (CSQRT, "CSQRT", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impCSQRT ) -DEFSPEC (FFEINTRIN_specDABS, +DEFSPEC (DABS, "DABS", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impDABS ) -DEFSPEC (FFEINTRIN_specDACOS, +DEFSPEC (DACOS, "DACOS", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impDACOS ) -DEFSPEC (FFEINTRIN_specDASIN, +DEFSPEC (DASIN, "DASIN", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impDASIN ) -DEFSPEC (FFEINTRIN_specDATAN, +DEFSPEC (DATAN, "DATAN", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impDATAN ) -DEFSPEC (FFEINTRIN_specDATAN2, +DEFSPEC (DATAN2, "DATAN2", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impDATAN2 ) -DEFSPEC (FFEINTRIN_specDBLE, +DEFSPEC (DBLE, "DBLE", FALSE, FFEINTRIN_familyF77, FFEINTRIN_impDBLE ) -DEFSPEC (FFEINTRIN_specDCOS, +DEFSPEC (DCOS, "DCOS", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impDCOS ) -DEFSPEC (FFEINTRIN_specDCOSH, +DEFSPEC (DCOSH, "DCOSH", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impDCOSH ) -DEFSPEC (FFEINTRIN_specDDIM, +DEFSPEC (DDIM, "DDIM", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impDDIM ) -DEFSPEC (FFEINTRIN_specDEXP, +DEFSPEC (DEXP, "DEXP", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impDEXP ) -DEFSPEC (FFEINTRIN_specDIM, +DEFSPEC (DIM, "DIM", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impDIM ) -DEFSPEC (FFEINTRIN_specDINT, +DEFSPEC (DINT, "DINT", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impDINT ) -DEFSPEC (FFEINTRIN_specDLOG, +DEFSPEC (DLOG, "DLOG", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impDLOG ) -DEFSPEC (FFEINTRIN_specDLOG10, +DEFSPEC (DLOG10, "DLOG10", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impDLOG10 ) -DEFSPEC (FFEINTRIN_specDMAX1, +DEFSPEC (DMAX1, "DMAX1", FALSE, FFEINTRIN_familyF77, FFEINTRIN_impDMAX1 ) -DEFSPEC (FFEINTRIN_specDMIN1, +DEFSPEC (DMIN1, "DMIN1", FALSE, FFEINTRIN_familyF77, FFEINTRIN_impDMIN1 ) -DEFSPEC (FFEINTRIN_specDMOD, +DEFSPEC (DMOD, "DMOD", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impDMOD ) -DEFSPEC (FFEINTRIN_specDNINT, +DEFSPEC (DNINT, "DNINT", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impDNINT ) -DEFSPEC (FFEINTRIN_specDPROD, +DEFSPEC (DPROD, "DPROD", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impDPROD ) -DEFSPEC (FFEINTRIN_specDSIGN, +DEFSPEC (DSIGN, "DSIGN", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impDSIGN ) -DEFSPEC (FFEINTRIN_specDSIN, +DEFSPEC (DSIN, "DSIN", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impDSIN ) -DEFSPEC (FFEINTRIN_specDSINH, +DEFSPEC (DSINH, "DSINH", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impDSINH ) -DEFSPEC (FFEINTRIN_specDSQRT, +DEFSPEC (DSQRT, "DSQRT", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impDSQRT ) -DEFSPEC (FFEINTRIN_specDTAN, +DEFSPEC (DTAN, "DTAN", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impDTAN ) -DEFSPEC (FFEINTRIN_specDTANH, +DEFSPEC (DTANH, "DTANH", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impDTANH ) -DEFSPEC (FFEINTRIN_specEXP, +DEFSPEC (EXP, "EXP", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impEXP ) -DEFSPEC (FFEINTRIN_specFLOAT, +DEFSPEC (FLOAT, "FLOAT", FALSE, FFEINTRIN_familyF77, - FFEINTRIN_impREAL + FFEINTRIN_impFLOAT ) -DEFSPEC (FFEINTRIN_specIABS, +DEFSPEC (IABS, "IABS", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impIABS ) -DEFSPEC (FFEINTRIN_specICHAR, +DEFSPEC (ICHAR, "ICHAR", FALSE, FFEINTRIN_familyF77, FFEINTRIN_impICHAR ) -DEFSPEC (FFEINTRIN_specIDIM, +DEFSPEC (IDIM, "IDIM", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impIDIM ) -DEFSPEC (FFEINTRIN_specIDINT, +DEFSPEC (IDINT, "IDINT", FALSE, FFEINTRIN_familyF77, - FFEINTRIN_impINT + FFEINTRIN_impIDINT ) -DEFSPEC (FFEINTRIN_specIDNINT, +DEFSPEC (IDNINT, "IDNINT", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impIDNINT ) -DEFSPEC (FFEINTRIN_specIFIX, +DEFSPEC (IFIX, "IFIX", FALSE, FFEINTRIN_familyF77, FFEINTRIN_impINT ) -DEFSPEC (FFEINTRIN_specINDEX, +DEFSPEC (INDEX, "INDEX", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impINDEX ) -DEFSPEC (FFEINTRIN_specINT, +DEFSPEC (INT, "INT", FALSE, FFEINTRIN_familyF77, FFEINTRIN_impINT ) -DEFSPEC (FFEINTRIN_specISIGN, +DEFSPEC (ISIGN, "ISIGN", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impISIGN ) -DEFSPEC (FFEINTRIN_specLEN, +DEFSPEC (LEN, "LEN", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impLEN ) -DEFSPEC (FFEINTRIN_specLGE, +DEFSPEC (LGE, "LGE", FALSE, FFEINTRIN_familyF77, FFEINTRIN_impLGE ) -DEFSPEC (FFEINTRIN_specLGT, +DEFSPEC (LGT, "LGT", FALSE, FFEINTRIN_familyF77, FFEINTRIN_impLGT ) -DEFSPEC (FFEINTRIN_specLLE, +DEFSPEC (LLE, "LLE", FALSE, FFEINTRIN_familyF77, FFEINTRIN_impLLE ) -DEFSPEC (FFEINTRIN_specLLT, +DEFSPEC (LLT, "LLT", FALSE, FFEINTRIN_familyF77, FFEINTRIN_impLLT ) -DEFSPEC (FFEINTRIN_specLOG, +DEFSPEC (LOG, "LOG", FALSE, FFEINTRIN_familyF77, FFEINTRIN_impLOG ) -DEFSPEC (FFEINTRIN_specLOG10, +DEFSPEC (LOG10, "LOG10", FALSE, FFEINTRIN_familyF77, FFEINTRIN_impLOG10 ) -DEFSPEC (FFEINTRIN_specMAX, +DEFSPEC (MAX, "MAX", FALSE, FFEINTRIN_familyF77, FFEINTRIN_impMAX ) -DEFSPEC (FFEINTRIN_specMAX0, +DEFSPEC (MAX0, "MAX0", FALSE, FFEINTRIN_familyF77, FFEINTRIN_impMAX0 ) -DEFSPEC (FFEINTRIN_specMAX1, +DEFSPEC (MAX1, "MAX1", FALSE, FFEINTRIN_familyF77, FFEINTRIN_impMAX1 ) -DEFSPEC (FFEINTRIN_specMIN, +DEFSPEC (MIN, "MIN", FALSE, FFEINTRIN_familyF77, FFEINTRIN_impMIN ) -DEFSPEC (FFEINTRIN_specMIN0, +DEFSPEC (MIN0, "MIN0", FALSE, FFEINTRIN_familyF77, FFEINTRIN_impMIN0 ) -DEFSPEC (FFEINTRIN_specMIN1, +DEFSPEC (MIN1, "MIN1", FALSE, FFEINTRIN_familyF77, FFEINTRIN_impMIN1 ) -DEFSPEC (FFEINTRIN_specMOD, +DEFSPEC (MOD, "MOD", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impMOD ) -DEFSPEC (FFEINTRIN_specNINT, +DEFSPEC (NINT, "NINT", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impNINT ) -DEFSPEC (FFEINTRIN_specREAL, +DEFSPEC (REAL, "REAL", FALSE, FFEINTRIN_familyF77, FFEINTRIN_impREAL ) -DEFSPEC (FFEINTRIN_specSIGN, +DEFSPEC (SIGN, "SIGN", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impSIGN ) -DEFSPEC (FFEINTRIN_specSIN, +DEFSPEC (SIN, "SIN", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impSIN ) -DEFSPEC (FFEINTRIN_specSINH, +DEFSPEC (SINH, "SINH", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impSINH ) -DEFSPEC (FFEINTRIN_specSNGL, +DEFSPEC (SNGL, "SNGL", FALSE, FFEINTRIN_familyF77, - FFEINTRIN_impREAL + FFEINTRIN_impSNGL ) -DEFSPEC (FFEINTRIN_specSQRT, +DEFSPEC (SQRT, "SQRT", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impSQRT ) -DEFSPEC (FFEINTRIN_specTAN, +DEFSPEC (TAN, "TAN", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impTAN ) -DEFSPEC (FFEINTRIN_specTANH, +DEFSPEC (TANH, "TANH", TRUE, FFEINTRIN_familyF77, FFEINTRIN_impTANH ) -DEFSPEC (FFEINTRIN_specABORT, +DEFSPEC (ABORT, "ABORT", FALSE, FFEINTRIN_familyF2U, FFEINTRIN_impABORT ) -DEFSPEC (FFEINTRIN_specACHAR, +DEFSPEC (ACCESS, + "ACCESS", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impACCESS +) +DEFSPEC (ACHAR, "ACHAR", FALSE, FFEINTRIN_familyASC, FFEINTRIN_impACHAR ) -DEFSPEC (FFEINTRIN_specACOSD, +DEFSPEC (ACOSD, "ACOSD", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specADJUSTL, +DEFSPEC (ADJUSTL, "ADJUSTL", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specADJUSTR, +DEFSPEC (ADJUSTR, "ADJUSTR", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specAIMAX0, +DEFSPEC (AIMAX0, "AIMAX0", FALSE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specAIMIN0, +DEFSPEC (AIMIN0, "AIMIN0", FALSE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specAJMAX0, +DEFSPEC (AJMAX0, "AJMAX0", FALSE, FFEINTRIN_familyVXT, - FFEINTRIN_impAMAX0 + FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specAJMIN0, +DEFSPEC (AJMIN0, "AJMIN0", FALSE, FFEINTRIN_familyVXT, - FFEINTRIN_impAMIN0 + FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specALL, +DEFSPEC (ALL, "ALL", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specALLOCATED, +DEFSPEC (ALLOCATED, "ALLOCATED", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specAND, +DEFSPEC (AND, "AND", FALSE, FFEINTRIN_familyF2C, - FFEINTRIN_impIAND + FFEINTRIN_impAND ) -DEFSPEC (FFEINTRIN_specANY, +DEFSPEC (ANY, "ANY", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specASIND, +DEFSPEC (ASIND, "ASIND", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specASSOCIATED, +DEFSPEC (ASSOCIATED, "ASSOCIATED", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specATAN2D, +DEFSPEC (ATAN2D, "ATAN2D", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specATAND, +DEFSPEC (ATAND, "ATAND", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specBIT_SIZE, +DEFSPEC (BESJ0, + "BESJ0", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impBESJ0 +) +DEFSPEC (BESJ1, + "BESJ1", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impBESJ1 +) +DEFSPEC (BESJN, + "BESJN", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impBESJN +) +DEFSPEC (BESY0, + "BESY0", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impBESY0 +) +DEFSPEC (BESY1, + "BESY1", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impBESY1 +) +DEFSPEC (BESYN, + "BESYN", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impBESYN +) +DEFSPEC (BIT_SIZE, "BIT_SIZE", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impBIT_SIZE ) -DEFSPEC (FFEINTRIN_specBITEST, +DEFSPEC (BITEST, "BITEST", FALSE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specBJTEST, +DEFSPEC (BJTEST, "BJTEST", FALSE, FFEINTRIN_familyVXT, - FFEINTRIN_impBTEST + FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specBTEST, +DEFSPEC (BTEST, "BTEST", FALSE, FFEINTRIN_familyMIL, FFEINTRIN_impBTEST ) -DEFSPEC (FFEINTRIN_specCDABS, +DEFSPEC (CDABS, "CDABS", TRUE, FFEINTRIN_familyFVZ, FFEINTRIN_impCDABS ) -DEFSPEC (FFEINTRIN_specCDCOS, +DEFSPEC (CDCOS, "CDCOS", TRUE, FFEINTRIN_familyFVZ, FFEINTRIN_impCDCOS ) -DEFSPEC (FFEINTRIN_specCDEXP, +DEFSPEC (CDEXP, "CDEXP", TRUE, FFEINTRIN_familyFVZ, FFEINTRIN_impCDEXP ) -DEFSPEC (FFEINTRIN_specCDLOG, +DEFSPEC (CDLOG, "CDLOG", TRUE, FFEINTRIN_familyFVZ, FFEINTRIN_impCDLOG ) -DEFSPEC (FFEINTRIN_specCDSIN, +DEFSPEC (CDSIN, "CDSIN", TRUE, FFEINTRIN_familyFVZ, FFEINTRIN_impCDSIN ) -DEFSPEC (FFEINTRIN_specCDSQRT, +DEFSPEC (CDSQRT, "CDSQRT", TRUE, FFEINTRIN_familyFVZ, FFEINTRIN_impCDSQRT ) -DEFSPEC (FFEINTRIN_specCEILING, +DEFSPEC (CEILING, "CEILING", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specCOSD, +DEFSPEC (CHDIR, + "CHDIR", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impCHDIR +) +DEFSPEC (CHMOD, + "CHMOD", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impCHMOD +) +DEFSPEC (COMPLEX, + "COMPLEX", + FALSE, + FFEINTRIN_familyGNU, + FFEINTRIN_impCOMPLEX + ) +DEFSPEC (COSD, "COSD", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specCOUNT, +DEFSPEC (COUNT, "COUNT", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specCSHIFT, +DEFSPEC (CSHIFT, "CSHIFT", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specDACOSD, +DEFSPEC (CTIME, + "CTIME", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impCTIME +) +DEFSPEC (DACOSD, "DACOSD", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specDASIND, +DEFSPEC (DASIND, "DASIND", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specDATAN2D, +DEFSPEC (DATAN2D, "DATAN2D", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specDATAND, +DEFSPEC (DATAND, "DATAND", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specDATE_AND_TIME, +DEFSPEC (DATE, + "DATE", + FALSE, + FFEINTRIN_familyVXT, + FFEINTRIN_impDATE +) +DEFSPEC (DATE_AND_TIME, "DATE_AND_TIME", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specDBLEQ, +DEFSPEC (DBESJ0, + "DBESJ0", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impDBESJ0 +) +DEFSPEC (DBESJ1, + "DBESJ1", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impDBESJ1 +) +DEFSPEC (DBESJN, + "DBESJN", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impDBESJN +) +DEFSPEC (DBESY0, + "DBESY0", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impDBESY0 +) +DEFSPEC (DBESY1, + "DBESY1", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impDBESY1 +) +DEFSPEC (DBESYN, + "DBESYN", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impDBESYN +) +DEFSPEC (DBLEQ, "DBLEQ", FALSE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specDCMPLX, +DEFSPEC (DCMPLX, "DCMPLX", FALSE, - FFEINTRIN_familyDCP, + FFEINTRIN_familyFVZ, FFEINTRIN_impDCMPLX ) -DEFSPEC (FFEINTRIN_specDCONJG, +DEFSPEC (DCONJG, "DCONJG", TRUE, FFEINTRIN_familyFVZ, FFEINTRIN_impDCONJG ) -DEFSPEC (FFEINTRIN_specDCOSD, +DEFSPEC (DCOSD, "DCOSD", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specDERF, +DEFSPEC (DERF, "DERF", FALSE, FFEINTRIN_familyF2U, FFEINTRIN_impDERF ) -DEFSPEC (FFEINTRIN_specDERFC, +DEFSPEC (DERFC, "DERFC", FALSE, FFEINTRIN_familyF2U, FFEINTRIN_impDERFC ) -DEFSPEC (FFEINTRIN_specDFLOAT, +DEFSPEC (DFLOAT, "DFLOAT", FALSE, - FFEINTRIN_familyF2C, - FFEINTRIN_impDBLE + FFEINTRIN_familyFVZ, + FFEINTRIN_impDFLOAT ) -DEFSPEC (FFEINTRIN_specDFLOTI, +DEFSPEC (DFLOTI, "DFLOTI", FALSE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specDFLOTJ, +DEFSPEC (DFLOTJ, "DFLOTJ", FALSE, FFEINTRIN_familyVXT, - FFEINTRIN_impDBLE + FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specDIGITS, +DEFSPEC (DIGITS, "DIGITS", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specDIMAG, +DEFSPEC (DIMAG, "DIMAG", TRUE, FFEINTRIN_familyFVZ, FFEINTRIN_impDIMAG ) -DEFSPEC (FFEINTRIN_specDOT_PRODUCT, +DEFSPEC (DOT_PRODUCT, "DOT_PRODUCT", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specDREAL, +DEFSPEC (DREAL, "DREAL", FALSE, - FFEINTRIN_familyFVZ, - FFEINTRIN_impDBLE + FFEINTRIN_familyVXT, + FFEINTRIN_impDREAL ) -DEFSPEC (FFEINTRIN_specDSIND, +DEFSPEC (DSIND, "DSIND", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specDTAND, +DEFSPEC (DTAND, "DTAND", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specEOSHIFT, +DEFSPEC (DTIME, + "DTIME", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impDTIME +) +DEFSPEC (EOSHIFT, "EOSHIFT", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specEPSILON, +DEFSPEC (EPSILON, "EPSILON", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specERF, +DEFSPEC (ERF, "ERF", FALSE, FFEINTRIN_familyF2U, FFEINTRIN_impERF ) -DEFSPEC (FFEINTRIN_specERFC, +DEFSPEC (ERFC, "ERFC", FALSE, FFEINTRIN_familyF2U, FFEINTRIN_impERFC ) -DEFSPEC (FFEINTRIN_specEXIT, +DEFSPEC (ETIME, + "ETIME", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impETIME +) +DEFSPEC (EXIT, "EXIT", FALSE, FFEINTRIN_familyF2U, FFEINTRIN_impEXIT ) -DEFSPEC (FFEINTRIN_specEXPONENT, +DEFSPEC (EXPONENT, "EXPONENT", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specFLOATI, +DEFSPEC (FDATE, + "FDATE", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impFDATE +) +DEFSPEC (FGETC, + "FGETC", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impFGETC +) +DEFSPEC (FLOATI, "FLOATI", FALSE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specFLOATJ, +DEFSPEC (FLOATJ, "FLOATJ", FALSE, FFEINTRIN_familyVXT, - FFEINTRIN_impREAL + FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specFLOOR, +DEFSPEC (FLOOR, "FLOOR", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specFLUSH, +DEFSPEC (FLUSH, "FLUSH", FALSE, FFEINTRIN_familyF2U, FFEINTRIN_impFLUSH ) -DEFSPEC (FFEINTRIN_specFRACTION, +DEFSPEC (FNUM, + "FNUM", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impFNUM +) +DEFSPEC (FPUTC, + "FPUTC", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impFPUTC +) +DEFSPEC (FRACTION, "FRACTION", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specFSEEK, +DEFSPEC (FSEEK, "FSEEK", FALSE, FFEINTRIN_familyF2U, FFEINTRIN_impFSEEK ) -DEFSPEC (FFEINTRIN_specFTELL, +DEFSPEC (FSTAT, + "FSTAT", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impFSTAT +) +DEFSPEC (FTELL, "FTELL", FALSE, FFEINTRIN_familyF2U, FFEINTRIN_impFTELL ) -DEFSPEC (FFEINTRIN_specGETARG, +DEFSPEC (GERROR, + "GERROR", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impGERROR +) +DEFSPEC (GETARG, "GETARG", FALSE, FFEINTRIN_familyF2U, FFEINTRIN_impGETARG ) -DEFSPEC (FFEINTRIN_specGETENV, +DEFSPEC (GETCWD, + "GETCWD", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impGETCWD +) +DEFSPEC (GETENV, "GETENV", FALSE, FFEINTRIN_familyF2U, FFEINTRIN_impGETENV ) -DEFSPEC (FFEINTRIN_specHUGE, +DEFSPEC (GETGID, + "GETGID", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impGETGID +) +DEFSPEC (GETLOG, + "GETLOG", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impGETLOG +) +DEFSPEC (GETPID, + "GETPID", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impGETPID +) +DEFSPEC (GETUID, + "GETUID", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impGETUID +) +DEFSPEC (GMTIME, + "GMTIME", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impGMTIME +) +DEFSPEC (HOSTNM, + "HOSTNM", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impHOSTNM +) +DEFSPEC (HUGE, "HUGE", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specIACHAR, +DEFSPEC (IACHAR, "IACHAR", FALSE, FFEINTRIN_familyASC, FFEINTRIN_impIACHAR ) -DEFSPEC (FFEINTRIN_specIAND, +DEFSPEC (IAND, "IAND", FALSE, FFEINTRIN_familyMIL, FFEINTRIN_impIAND ) -DEFSPEC (FFEINTRIN_specIARGC, +DEFSPEC (IARGC, "IARGC", FALSE, FFEINTRIN_familyF2U, FFEINTRIN_impIARGC ) -DEFSPEC (FFEINTRIN_specIBCLR, +DEFSPEC (IBCLR, "IBCLR", FALSE, FFEINTRIN_familyMIL, FFEINTRIN_impIBCLR ) -DEFSPEC (FFEINTRIN_specIBITS, +DEFSPEC (IBITS, "IBITS", FALSE, FFEINTRIN_familyMIL, FFEINTRIN_impIBITS ) -DEFSPEC (FFEINTRIN_specIBSET, +DEFSPEC (IBSET, "IBSET", FALSE, FFEINTRIN_familyMIL, FFEINTRIN_impIBSET ) -DEFSPEC (FFEINTRIN_specIEOR, +DEFSPEC (IDATE, + "IDATE (UNIX)", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impIDATE +) +DEFSPEC (IDATEVXT, + "IDATE (VXT)", + FALSE, + FFEINTRIN_familyVXT, + FFEINTRIN_impIDATEVXT +) +DEFSPEC (IEOR, "IEOR", FALSE, FFEINTRIN_familyMIL, FFEINTRIN_impIEOR ) -DEFSPEC (FFEINTRIN_specIIABS, +DEFSPEC (IERRNO, + "IERRNO", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impIERRNO +) +DEFSPEC (IIABS, "IIABS", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specIIAND, +DEFSPEC (IIAND, "IIAND", FALSE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specIIBCLR, +DEFSPEC (IIBCLR, "IIBCLR", FALSE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specIIBITS, +DEFSPEC (IIBITS, "IIBITS", FALSE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specIIBSET, +DEFSPEC (IIBSET, "IIBSET", FALSE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specIIDIM, +DEFSPEC (IIDIM, "IIDIM", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specIIDINT, +DEFSPEC (IIDINT, "IIDINT", FALSE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specIIDNNT, +DEFSPEC (IIDNNT, "IIDNNT", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specIIEOR, +DEFSPEC (IIEOR, "IIEOR", FALSE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specIIFIX, +DEFSPEC (IIFIX, "IIFIX", FALSE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specIINT, +DEFSPEC (IINT, "IINT", FALSE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specIIOR, +DEFSPEC (IIOR, "IIOR", FALSE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specIIQINT, +DEFSPEC (IIQINT, "IIQINT", FALSE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specIIQNNT, +DEFSPEC (IIQNNT, "IIQNNT", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specIISHFT, +DEFSPEC (IISHFT, "IISHFT", FALSE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specIISHFTC, +DEFSPEC (IISHFTC, "IISHFTC", FALSE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specIISIGN, +DEFSPEC (IISIGN, "IISIGN", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specIMAG, +DEFSPEC (IMAG, "IMAG", FALSE, FFEINTRIN_familyF2C, - FFEINTRIN_impAIMAG + FFEINTRIN_impIMAGPART + ) +DEFSPEC (IMAGPART, + "IMAGPART", + FALSE, + FFEINTRIN_familyGNU, + FFEINTRIN_impIMAGPART ) -DEFSPEC (FFEINTRIN_specIMAX0, +DEFSPEC (IMAX0, "IMAX0", FALSE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specIMAX1, +DEFSPEC (IMAX1, "IMAX1", FALSE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specIMIN0, +DEFSPEC (IMIN0, "IMIN0", FALSE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specIMIN1, +DEFSPEC (IMIN1, "IMIN1", FALSE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specIMOD, +DEFSPEC (IMOD, "IMOD", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specININT, +DEFSPEC (ININT, "ININT", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specINOT, +DEFSPEC (INOT, "INOT", FALSE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specIOR, +DEFSPEC (IOR, "IOR", FALSE, FFEINTRIN_familyMIL, FFEINTRIN_impIOR ) -DEFSPEC (FFEINTRIN_specISHFT, +DEFSPEC (IRAND, + "IRAND", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impIRAND +) +DEFSPEC (ISATTY, + "ISATTY", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impISATTY +) +DEFSPEC (ISHFT, "ISHFT", FALSE, FFEINTRIN_familyMIL, FFEINTRIN_impISHFT ) -DEFSPEC (FFEINTRIN_specISHFTC, +DEFSPEC (ISHFTC, "ISHFTC", FALSE, FFEINTRIN_familyMIL, FFEINTRIN_impISHFTC ) -DEFSPEC (FFEINTRIN_specIZEXT, +DEFSPEC (ITIME, + "ITIME", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impITIME +) +DEFSPEC (IZEXT, "IZEXT", FALSE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specJIABS, +DEFSPEC (JIABS, "JIABS", TRUE, FFEINTRIN_familyVXT, - FFEINTRIN_impIABS + FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specJIAND, +DEFSPEC (JIAND, "JIAND", FALSE, FFEINTRIN_familyVXT, - FFEINTRIN_impIAND + FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specJIBCLR, +DEFSPEC (JIBCLR, "JIBCLR", FALSE, FFEINTRIN_familyVXT, - FFEINTRIN_impIBCLR + FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specJIBITS, +DEFSPEC (JIBITS, "JIBITS", FALSE, FFEINTRIN_familyVXT, - FFEINTRIN_impIBITS + FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specJIBSET, +DEFSPEC (JIBSET, "JIBSET", FALSE, FFEINTRIN_familyVXT, - FFEINTRIN_impIBSET + FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specJIDIM, +DEFSPEC (JIDIM, "JIDIM", TRUE, FFEINTRIN_familyVXT, - FFEINTRIN_impIDIM + FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specJIDINT, +DEFSPEC (JIDINT, "JIDINT", FALSE, FFEINTRIN_familyVXT, - FFEINTRIN_impINT + FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specJIDNNT, +DEFSPEC (JIDNNT, "JIDNNT", TRUE, FFEINTRIN_familyVXT, - FFEINTRIN_impIDNINT + FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specJIEOR, +DEFSPEC (JIEOR, "JIEOR", FALSE, FFEINTRIN_familyVXT, - FFEINTRIN_impIEOR + FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specJIFIX, +DEFSPEC (JIFIX, "JIFIX", FALSE, FFEINTRIN_familyVXT, - FFEINTRIN_impINT + FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specJINT, +DEFSPEC (JINT, "JINT", FALSE, FFEINTRIN_familyVXT, - FFEINTRIN_impINT + FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specJIOR, +DEFSPEC (JIOR, "JIOR", FALSE, FFEINTRIN_familyVXT, - FFEINTRIN_impIOR + FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specJIQINT, +DEFSPEC (JIQINT, "JIQINT", FALSE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specJIQNNT, +DEFSPEC (JIQNNT, "JIQNNT", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specJISHFT, +DEFSPEC (JISHFT, "JISHFT", FALSE, FFEINTRIN_familyVXT, - FFEINTRIN_impISHFT + FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specJISHFTC, +DEFSPEC (JISHFTC, "JISHFTC", FALSE, FFEINTRIN_familyVXT, - FFEINTRIN_impISHFTC + FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specJISIGN, +DEFSPEC (JISIGN, "JISIGN", TRUE, FFEINTRIN_familyVXT, - FFEINTRIN_impISIGN + FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specJMAX0, +DEFSPEC (JMAX0, "JMAX0", FALSE, FFEINTRIN_familyVXT, - FFEINTRIN_impMAX0 + FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specJMAX1, +DEFSPEC (JMAX1, "JMAX1", FALSE, FFEINTRIN_familyVXT, - FFEINTRIN_impMAX1 + FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specJMIN0, +DEFSPEC (JMIN0, "JMIN0", FALSE, FFEINTRIN_familyVXT, - FFEINTRIN_impMIN0 + FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specJMIN1, +DEFSPEC (JMIN1, "JMIN1", FALSE, FFEINTRIN_familyVXT, - FFEINTRIN_impMIN1 + FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specJMOD, +DEFSPEC (JMOD, "JMOD", TRUE, FFEINTRIN_familyVXT, - FFEINTRIN_impMOD + FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specJNINT, +DEFSPEC (JNINT, "JNINT", TRUE, FFEINTRIN_familyVXT, - FFEINTRIN_impNINT + FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specJNOT, +DEFSPEC (JNOT, "JNOT", TRUE, FFEINTRIN_familyVXT, - FFEINTRIN_impNOT + FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specJZEXT, +DEFSPEC (JZEXT, "JZEXT", FALSE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specKIND, +DEFSPEC (KILL, + "KILL", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impKILL +) +DEFSPEC (KIND, "KIND", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specLBOUND, +DEFSPEC (LBOUND, "LBOUND", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specLEN_TRIM, +DEFSPEC (LINK, + "LINK", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impLINK +) +DEFSPEC (LEN_TRIM, "LEN_TRIM", FALSE, FFEINTRIN_familyF90, - FFEINTRIN_impNONE + FFEINTRIN_impLNBLNK ) -DEFSPEC (FFEINTRIN_specLOC, +DEFSPEC (LNBLNK, + "LNBLNK", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impLNBLNK +) +DEFSPEC (LOC, "LOC", FALSE, FFEINTRIN_familyF2U, FFEINTRIN_impLOC ) -DEFSPEC (FFEINTRIN_specLOGICAL, +DEFSPEC (LOGICAL, "LOGICAL", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specLSHIFT, +DEFSPEC (LONG, + "LONG", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impLONG + ) +DEFSPEC (LSHIFT, "LSHIFT", FALSE, FFEINTRIN_familyF2C, FFEINTRIN_impLSHIFT ) -DEFSPEC (FFEINTRIN_specMATMUL, +DEFSPEC (LSTAT, + "LSTAT", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impLSTAT +) +DEFSPEC (LTIME, + "LTIME", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impLTIME +) +DEFSPEC (MATMUL, "MATMUL", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specMAXEXPONENT, +DEFSPEC (MAXEXPONENT, "MAXEXPONENT", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specMAXLOC, +DEFSPEC (MAXLOC, "MAXLOC", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specMAXVAL, +DEFSPEC (MAXVAL, "MAXVAL", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specMERGE, +DEFSPEC (MCLOCK, + "MCLOCK", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impMCLOCK +) +DEFSPEC (MERGE, "MERGE", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specMINEXPONENT, +DEFSPEC (MINEXPONENT, "MINEXPONENT", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specMINLOC, +DEFSPEC (MINLOC, "MINLOC", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specMINVAL, +DEFSPEC (MINVAL, "MINVAL", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specMODULO, +DEFSPEC (MODULO, "MODULO", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specMVBITS, +DEFSPEC (MVBITS, "MVBITS", FALSE, FFEINTRIN_familyMIL, FFEINTRIN_impMVBITS ) -DEFSPEC (FFEINTRIN_specNEAREST, +DEFSPEC (NEAREST, "NEAREST", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specNOT, +DEFSPEC (NOT, "NOT", FALSE, FFEINTRIN_familyMIL, FFEINTRIN_impNOT ) -DEFSPEC (FFEINTRIN_specOR, +DEFSPEC (OR, "OR", FALSE, FFEINTRIN_familyF2C, - FFEINTRIN_impIOR + FFEINTRIN_impOR ) -DEFSPEC (FFEINTRIN_specPACK, +DEFSPEC (PACK, "PACK", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specPRECISION, +DEFSPEC (PERROR, + "PERROR", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impPERROR +) +DEFSPEC (PRECISION, "PRECISION", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specPRESENT, +DEFSPEC (PRESENT, "PRESENT", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specPRODUCT, +DEFSPEC (PRODUCT, "PRODUCT", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specQABS, +DEFSPEC (QABS, "QABS", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specQACOS, +DEFSPEC (QACOS, "QACOS", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specQACOSD, +DEFSPEC (QACOSD, "QACOSD", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specQASIN, +DEFSPEC (QASIN, "QASIN", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specQASIND, +DEFSPEC (QASIND, "QASIND", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specQATAN, +DEFSPEC (QATAN, "QATAN", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specQATAN2, +DEFSPEC (QATAN2, "QATAN2", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specQATAN2D, +DEFSPEC (QATAN2D, "QATAN2D", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specQATAND, +DEFSPEC (QATAND, "QATAND", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specQCOS, +DEFSPEC (QCOS, "QCOS", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specQCOSD, +DEFSPEC (QCOSD, "QCOSD", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specQCOSH, +DEFSPEC (QCOSH, "QCOSH", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specQDIM, +DEFSPEC (QDIM, "QDIM", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specQEXP, +DEFSPEC (QEXP, "QEXP", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specQEXT, +DEFSPEC (QEXT, "QEXT", FALSE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specQEXTD, +DEFSPEC (QEXTD, "QEXTD", FALSE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specQFLOAT, +DEFSPEC (QFLOAT, "QFLOAT", FALSE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specQINT, +DEFSPEC (QINT, "QINT", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specQLOG, +DEFSPEC (QLOG, "QLOG", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specQLOG10, +DEFSPEC (QLOG10, "QLOG10", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specQMAX1, +DEFSPEC (QMAX1, "QMAX1", FALSE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specQMIN1, +DEFSPEC (QMIN1, "QMIN1", FALSE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specQMOD, +DEFSPEC (QMOD, "QMOD", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specQNINT, +DEFSPEC (QNINT, "QNINT", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specQSIGN, +DEFSPEC (QSIGN, "QSIGN", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specQSIN, +DEFSPEC (QSIN, "QSIN", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specQSIND, +DEFSPEC (QSIND, "QSIND", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specQSINH, +DEFSPEC (QSINH, "QSINH", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specQSQRT, +DEFSPEC (QSQRT, "QSQRT", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specQTAN, +DEFSPEC (QTAN, "QTAN", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specQTAND, +DEFSPEC (QTAND, "QTAND", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specQTANH, +DEFSPEC (QTANH, "QTANH", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specRADIX, +DEFSPEC (RADIX, "RADIX", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specRANDOM_NUMBER, +DEFSPEC (RAND, + "RAND", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impRAND +) +DEFSPEC (RANDOM_NUMBER, "RANDOM_NUMBER", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specRANDOM_SEED, +DEFSPEC (RANDOM_SEED, "RANDOM_SEED", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specRANGE, +DEFSPEC (RANGE, "RANGE", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specREPEAT, +DEFSPEC (REALPART, + "REALPART", + FALSE, + FFEINTRIN_familyGNU, + FFEINTRIN_impREALPART + ) +DEFSPEC (RENAME, + "RENAME", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impRENAME +) +DEFSPEC (REPEAT, "REPEAT", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specRESHAPE, +DEFSPEC (RESHAPE, "RESHAPE", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specRRSPACING, +DEFSPEC (RRSPACING, "RRSPACING", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specRSHIFT, +DEFSPEC (RSHIFT, "RSHIFT", FALSE, FFEINTRIN_familyF2C, FFEINTRIN_impRSHIFT ) -DEFSPEC (FFEINTRIN_specSCALE, +DEFSPEC (SCALE, "SCALE", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specSCAN, +DEFSPEC (SCAN, "SCAN", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specSEL_INT_KIND, +DEFSPEC (SECNDS, + "SECNDS", + FALSE, + FFEINTRIN_familyVXT, + FFEINTRIN_impSECNDS +) +DEFSPEC (SECONDFUNC, + "SECOND (function)", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impSECONDFUNC +) +DEFSPEC (SECONDSUBR, + "SECOND (subroutine)", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impSECONDSUBR +) +DEFSPEC (SEL_INT_KIND, "SEL_INT_KIND", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specSEL_REAL_KIND, +DEFSPEC (SEL_REAL_KIND, "SEL_REAL_KIND", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specSET_EXPONENT, +DEFSPEC (SET_EXPONENT, "SET_EXPONENT", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specSHAPE, +DEFSPEC (SHAPE, "SHAPE", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specSIGNAL, +DEFSPEC (SHORT, + "SHORT", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impSHORT + ) +DEFSPEC (SIGNAL, "SIGNAL", FALSE, FFEINTRIN_familyF2U, FFEINTRIN_impSIGNAL ) -DEFSPEC (FFEINTRIN_specSIND, +DEFSPEC (SIND, "SIND", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specSNGLQ, +DEFSPEC (SLEEP, + "SLEEP", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impSLEEP +) +DEFSPEC (SNGLQ, "SNGLQ", FALSE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specSPACING, +DEFSPEC (SPACING, "SPACING", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specSPREAD, +DEFSPEC (SPREAD, "SPREAD", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specSUM, +DEFSPEC (SRAND, + "SRAND", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impSRAND +) +DEFSPEC (STAT, + "STAT", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impSTAT +) +DEFSPEC (SUM, "SUM", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specSYSTEM, +DEFSPEC (SYMLNK, + "SYMLNK", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impSYMLNK +) +DEFSPEC (SYSTEM, "SYSTEM", FALSE, FFEINTRIN_familyF2U, FFEINTRIN_impSYSTEM ) -DEFSPEC (FFEINTRIN_specSYSTEM_CLOCK, +DEFSPEC (SYSTEM_CLOCK, "SYSTEM_CLOCK", FALSE, FFEINTRIN_familyF90, - FFEINTRIN_impNONE + FFEINTRIN_impSYSTEM_CLOCK ) -DEFSPEC (FFEINTRIN_specTAND, +DEFSPEC (TAND, "TAND", TRUE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specTINY, +DEFSPEC (TIME, + "TIME (UNIX)", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impTIME +) +DEFSPEC (TIMEVXT, + "TIME (VXT)", + FALSE, + FFEINTRIN_familyVXT, + FFEINTRIN_impTIMEVXT +) +DEFSPEC (TINY, "TINY", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specTRANSFER, +DEFSPEC (TRANSFER, "TRANSFER", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specTRANSPOSE, +DEFSPEC (TRANSPOSE, "TRANSPOSE", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specTRIM, +DEFSPEC (TRIM, "TRIM", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specUBOUND, +DEFSPEC (TTYNAM, + "TTYNAM", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impTTYNAM +) +DEFSPEC (UBOUND, "UBOUND", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specUNPACK, +DEFSPEC (UMASK, + "UMASK", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impUMASK +) +DEFSPEC (UNLINK, + "UNLINK", + FALSE, + FFEINTRIN_familyF2U, + FFEINTRIN_impUNLINK +) +DEFSPEC (UNPACK, "UNPACK", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specVERIFY, +DEFSPEC (VERIFY, "VERIFY", FALSE, FFEINTRIN_familyF90, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specXOR, +DEFSPEC (XOR, "XOR", FALSE, FFEINTRIN_familyF2C, - FFEINTRIN_impIEOR + FFEINTRIN_impXOR ) -DEFSPEC (FFEINTRIN_specZABS, +DEFSPEC (ZABS, "ZABS", TRUE, - FFEINTRIN_familyF2Z, + FFEINTRIN_familyF2C, FFEINTRIN_impCDABS ) -DEFSPEC (FFEINTRIN_specZCOS, +DEFSPEC (ZCOS, "ZCOS", TRUE, - FFEINTRIN_familyF2Z, + FFEINTRIN_familyF2C, FFEINTRIN_impCDCOS ) -DEFSPEC (FFEINTRIN_specZEXP, +DEFSPEC (ZEXP, "ZEXP", TRUE, - FFEINTRIN_familyF2Z, + FFEINTRIN_familyF2C, FFEINTRIN_impCDEXP ) -DEFSPEC (FFEINTRIN_specZEXT, +DEFSPEC (ZEXT, "ZEXT", FALSE, FFEINTRIN_familyVXT, FFEINTRIN_impNONE ) -DEFSPEC (FFEINTRIN_specZLOG, +DEFSPEC (ZLOG, "ZLOG", TRUE, - FFEINTRIN_familyF2Z, + FFEINTRIN_familyF2C, FFEINTRIN_impCDLOG ) -DEFSPEC (FFEINTRIN_specZSIN, +DEFSPEC (ZSIN, "ZSIN", TRUE, - FFEINTRIN_familyF2Z, + FFEINTRIN_familyF2C, FFEINTRIN_impCDSIN ) -DEFSPEC (FFEINTRIN_specZSQRT, +DEFSPEC (ZSQRT, "ZSQRT", TRUE, - FFEINTRIN_familyF2Z, + FFEINTRIN_familyF2C, FFEINTRIN_impCDSQRT ) -DEFSPEC (FFEINTRIN_specNONE, +DEFSPEC (NONE, "none", FALSE, FFEINTRIN_familyNONE, @@ -2251,7 +2691,11 @@ DEFSPEC (FFEINTRIN_specNONE, no need to complain about ambiguity if two different-typed intrinsic run-time implementations have the same compile-time implementation, as long as there's a straightforward way of determining which was - meant (done by ffeintrin_fulfill_generic). */ + meant (done by ffeintrin_fulfill_generic). (Here `the same code at + compile time' may be the default dispatch defined by the + DEFIMP/DEFIMQ signatures -- see com.c.) Fixme: Note that + currently, DEFIMQs have to be a subroutine or function to match + what the corresponding DEFIMP of the same name is. */ /* The control string has the following format: @@ -2259,7 +2703,7 @@ DEFSPEC (FFEINTRIN_specNONE, <return-type> is: - <return-base-type><return-kind-type> + <return-base-type><return-kind-type>[<return-modifier>] <return-base-type> is: @@ -2277,11 +2721,19 @@ DEFSPEC (FFEINTRIN_specNONE, <return-kind-type> is: - Subroutine - 0 Decided by COL + = Decided by COL 1 (Default) - 2 (COMPLEX*16, INTEGER*1, LOGICAL*1, REAL*8) - 3 (INTEGER*2, LOGICAL*2) + 2 (Twice the size of 1) + 3 (Same size as CHARACTER*1) + 4 (Twice the size of 2) + 6 (Twice the size as 3) C Like 1 (F77), except (F90), if COL is COMPLEX, uses kind type of COL + p ffecom_pointer_kind_ + + <return-modifier> is: + + * Valid for <return-base-type> of `A' only, means program may + declare any length for return value, default being (*) <arglist-info> is: @@ -2289,13 +2741,13 @@ DEFSPEC (FFEINTRIN_specNONE, <COL-spec> is: - - No COL - * All arguments form COL - 1 Argument 1 forms COL + - No COL (return-base-type and return-kind-type must be definitive) + * All arguments form COL (must have more than one argument) + n Argument n (0 for first arg, 1 for second, etc.) forms COL <argitem-info> is: - <name>=[<optionality>]<arg-base-type><arg-kind-type>[<arg-extra>] + <name>=[<optionality>]<arg-base-type><arg-kind-type>[<arg-len>][<arg-rank>][<arg-extra>] <name> is the standard keyword name for the argument. @@ -2304,14 +2756,14 @@ DEFSPEC (FFEINTRIN_specNONE, ? Argument is optional ! Like ?, but argument must be omitted if previous arg was COMPLEX + One or more of these arguments must be specified - * Zero or more of these arguments may be specified - n Numbered names for arguments, one or more may be specified - p Like n, but two or more may be specified + * Zero or more of these arguments must be specified + n Numbered names for arguments, one or more must be specified + p Like n, but two or more must be specified <arg-base-type> is: - - Any is valid (but see arg-kind-type) - A Character + - Any is valid (arg-kind-type is 0) + A Character*(*) C Complex I Integer L Logical @@ -2319,34 +2771,46 @@ DEFSPEC (FFEINTRIN_specNONE, B Boolean (I or L) F Floating-point (C or R) N Numeric (C, I, or R) - S Scalar numeric (I or R; C mapped to R) + S Scalar numeric (I or R) + g GOTO label (alternate-return form of CALL) (arg-kind-type is 0) + s Signal handler (INTEGER FUNCTION, SUBROUTINE or dummy/global + default INTEGER variable) (arg-kind-type is 0) <arg-kind-type> is: - 0 Any is valid + * Any is valid 1 (Default) - 2 (COMPLEX*16, INTEGER*1, LOGICAL*1, REAL*8) - 3 (INTEGER*2, LOGICAL*2) + 2 (Twice the size of 1) + 3 (Same size as CHARACTER*1) + 4 (Twice the size of 2) + 6 (Twice the size as 3) A Same as first argument - g GOTO label (alternate-return form of CALL) - s Signal handler (INTEGER FUNCTION, SUBROUTINE or dummy/global - default INTEGER variable) (arg-base-type * only) + + <arg-len> is: + + (Default) CHARACTER*(*) + [n] CHARACTER*n + + <arg-rank> is: + + (default) Rank-0 (variable or array element) + (n) Rank-1 array n elements long + & Any (arg-extra is &) <arg-extra> is: - (default) Arg is (scalar) variable or constant - & Arg can have its address taken (LOC(), for example) - g GOTO label (alternate-return form of CALL) - s Signal handler (see <arg-kind>) + (default) Arg is INTENT(IN) + i Arg's attributes are all that matter (inquiry function) w Arg is INTENT(OUT) x Arg is INTENT(INOUT) + & Arg can have its address taken (LOC(), for example) */ -DEFIMP (ABS, "ABS", ABS, "S0:*:A=N0") -DEFIMP (ACOS, "ACOS", ACOS, "R0:*:X=R0") -DEFIMP (AIMAG, "AIMAG", AIMAG, "R0:*:Z=C0") -DEFIMP (AINT, "AINT", AINT, "R0:*:A=R0") +DEFIMP (ABS, "ABS", ABS, "S=:0:A=N*") +DEFIMP (ACOS, "ACOS", ACOS, "R=:0:X=R*") +DEFIMP (AIMAG, "AIMAG", AIMAG, "RC:0:Z=C*") +DEFIMP (AINT, "AINT", AINT, "R=:0:A=R*") DEFIMQ (ALOG, "ALOG", ALOG, "R1:-:X=R1", LOG) DEFIMQ (ALOG10, "ALOG10", ALOG10, "R1:-:X=R1", @@ -2361,23 +2825,23 @@ DEFIMQ (AMIN1, "AMIN1", , "R1:*:A=pR1", MIN) DEFIMQ (AMOD, "AMOD", AMOD, "R1:*:A=R1,P=R1", MOD) -DEFIMP (ANINT, "ANINT", ANINT, "R0:*:A=R0") -DEFIMP (ASIN, "ASIN", ASIN, "R0:*:X=R0") -DEFIMP (ATAN, "ATAN", ATAN, "R0:*:X=R0") -DEFIMP (ATAN2, "ATAN2", ATAN2, "R0:*:Y=R0,X=R0") +DEFIMP (ANINT, "ANINT", ANINT, "R=:0:A=R*") +DEFIMP (ASIN, "ASIN", ASIN, "R=:0:X=R*") +DEFIMP (ATAN, "ATAN", ATAN, "R=:0:X=R*") +DEFIMP (ATAN2, "ATAN2", ATAN2, "R=:*:Y=R*,X=R*") DEFIMQ (CABS, "CABS", CABS, "R1:-:A=C1", ABS) DEFIMQ (CCOS, "CCOS", CCOS, "C1:-:X=C1", COS) DEFIMQ (CEXP, "CEXP", CEXP, "C1:-:X=C1", EXP) -DEFIMP (CHAR, "CHAR", , "A1:-:I=I0") +DEFIMP (CHAR, "CHAR", , "A1:-:I=I*") DEFIMQ (CLOG, "CLOG", CLOG, "C1:-:X=C1", LOG) -DEFIMP (CMPLX, "CMPLX", , "C1:*:X=N0,Y=!S0") -DEFIMP (CONJG, "CONJG", CONJG, "C0:*:Z=C0") -DEFIMP (COS, "COS", COS, "F0:*:X=F0") -DEFIMP (COSH, "COSH", COSH, "R0:*:X=R0") +DEFIMP (CMPLX, "CMPLX", , "C1:*:X=N*,Y=!S*") +DEFIMP (CONJG, "CONJG", CONJG, "C=:0:Z=C*") +DEFIMP (COS, "COS", COS, "F=:0:X=F*") +DEFIMP (COSH, "COSH", COSH, "R=:0:X=R*") DEFIMQ (CSIN, "CSIN", CSIN, "C1:-:X=C1", SIN) DEFIMQ (CSQRT, "CSQRT", CSQRT, "C1:-:X=C1", @@ -2392,8 +2856,8 @@ DEFIMQ (DATAN, "DATAN", DATAN, "R2:-:X=R2", ATAN) DEFIMQ (DATAN2, "DATAN2", DATAN2, "R2:*:Y=R2,X=R2", ATAN2) -DEFIMP (DBLE, "DBLE", , "R2:-:A=N0") -DEFIMQ (DCMPLX, "DCMPLX", , "C2:*:X=N0,Y=!S0", +DEFIMP (DBLE, "DBLE", , "R2:-:A=N*") +DEFIMQ (DCMPLX, "DCMPLX", , "C2:*:X=N*,Y=!S*", CMPLX) DEFIMQ (DCOS, "DCOS", DCOS, "R2:-:X=R2", COS) @@ -2403,7 +2867,7 @@ DEFIMQ (DDIM, "DDIM", DDIM, "R2:*:X=R2,Y=R2", DIM) DEFIMQ (DEXP, "DEXP", DEXP, "R2:-:X=R2", EXP) -DEFIMP (DIM, "DIM", DIM, "S0:*:X=S0,Y=S0") +DEFIMP (DIM, "DIM", DIM, "S=:*:X=S*,Y=S*") DEFIMQ (DINT, "DINT", DINT, "R2:-:A=R2", AINT) DEFIMQ (DLOG, "DLOG", DLOG, "R2:-:X=R2", @@ -2431,27 +2895,32 @@ DEFIMQ (DTAN, "DTAN", DTAN, "R2:-:X=R2", TAN) DEFIMQ (DTANH, "DTANH", DTANH, "R2:-:X=R2", TANH) -DEFIMP (EXP, "EXP", EXP, "F0:*:X=F0") +DEFIMP (EXP, "EXP", EXP, "F=:0:X=F*") +DEFIMQ (FLOAT, "FLOAT", , "R1:-:A=I*", + REAL) DEFIMQ (IABS, "IABS", IABS, "I1:-:A=I1", ABS) -DEFIMP (ICHAR, "ICHAR", , "I1:-:C=A0") +DEFIMP (ICHAR, "ICHAR", , "I1:-:C=A*") DEFIMQ (IDIM, "IDIM", IDIM, "I1:*:X=I1,Y=I1", DIM) +DEFIMQ (IDINT, "IDINT", , "I1:-:A=R2", + INT) DEFIMQ (IDNINT, "IDNINT", IDNINT, "I1:-:A=R2", NINT) -DEFIMP (INDEX, "INDEX", INDEX, "I1:*:String=A0,Substring=A0") -DEFIMP (INT, "INT", , "I1:-:A=N0") +DEFIMP (INDEX, "INDEX", INDEX, "I1:*:String=A*,Substring=A*") +DEFIMP (INT, "INT", , "I1:-:A=N*") DEFIMQ (ISIGN, "ISIGN", ISIGN, "I1:*:A=I1,B=I1", SIGN) -DEFIMP (LEN, "LEN", LEN, "I1:-:String=A0") +DEFIMP (LEN, "LEN", LEN, "I1:-:String=A*i") DEFIMP (LGE, "LGE", LGE, "L1:*:String_A=A1,String_B=A1") DEFIMP (LGT, "LGT", LGT, "L1:*:String_A=A1,String_B=A1") DEFIMP (LLE, "LLE", LLE, "L1:*:String_A=A1,String_B=A1") DEFIMP (LLT, "LLT", LLT, "L1:*:String_A=A1,String_B=A1") -DEFIMP (LOG, "LOG", , "F0:*:X=F0") -DEFIMP (LOG10, "LOG10", , "R0:*:X=R0") -DEFIMP (MAX, "MAX", , "S0:*:A=pS0") -DEFIMP (MIN, "MIN", , "S0:*:A=pS0") +DEFIMP (LOG, "LOG", , "F=:0:X=F*") +DEFIMP (LOG10, "LOG10", , "R=:0:X=R*") +DEFIMP (LONG, "LONG", , "I1:-:A=I*") +DEFIMP (MAX, "MAX", , "S=:*:A=pS*") +DEFIMP (MIN, "MIN", , "S=:*:A=pS*") DEFIMQ (MAX0, "MAX0", , "I1:*:A=pI1", MAX) DEFIMQ (MAX1, "MAX1", , "I1:*:A=pR1", @@ -2460,21 +2929,30 @@ DEFIMQ (MIN0, "MIN0", , "I1:*:A=pI1", MIN) DEFIMQ (MIN1, "MIN1", , "I1:*:A=pR1", MIN) -DEFIMP (MOD, "MOD", MOD, "S0:*:A=S0,P=S0") -DEFIMP (NINT, "NINT", NINT, "I1:-:A=R0") -DEFIMP (REAL, "REAL", , "RC:*:A=N0") -DEFIMP (SIGN, "SIGN", SIGN, "S0:*:A=S0,B=S0") -DEFIMP (SIN, "SIN", SIN, "F0:*:X=F0") -DEFIMP (SINH, "SINH", SINH, "R0:*:X=R0") -DEFIMP (SQRT, "SQRT", SQRT, "F0:*:X=F0") -DEFIMP (TAN, "TAN", TAN, "R0:*:X=R0") -DEFIMP (TANH, "TANH", TANH, "R0:*:X=R0") +DEFIMP (MOD, "MOD", MOD, "S=:*:A=S*,P=S*") +DEFIMP (NINT, "NINT", NINT, "I1:-:A=R*") +DEFIMP (REAL, "REAL", , "RC:0:A=N*") +DEFIMP (SIGN, "SIGN", SIGN, "S=:*:A=S*,B=S*") +DEFIMP (SIN, "SIN", SIN, "F=:0:X=F*") +DEFIMP (SINH, "SINH", SINH, "R=:0:X=R*") +DEFIMQ (SNGL, "SNGL", , "R1:-:A=R2", + REAL) +DEFIMP (SQRT, "SQRT", SQRT, "F=:0:X=F*") +DEFIMP (TAN, "TAN", TAN, "R=:0:X=R*") +DEFIMP (TANH, "TANH", TANH, "R=:0:X=R*") DEFIMP (ABORT, "ABORT", ABORT, "--:-:") -DEFIMP (ACHAR, "ACHAR", , "A1:-:I=I0") -DEFIMP (AND, "AND", , "B0:*:I=B0,J=B0") -DEFIMP (BIT_SIZE, "BIT_SIZE", , "I0:*:I=I0") -DEFIMP (BTEST, "BTEST", , "L1:*:I=I0,Pos=I0") +DEFIMP (ACCESS, "ACCESS", ACCESS, "I1:-:Name=A1,Mode=A1") +DEFIMP (ACHAR, "ACHAR", , "A1:-:I=I*") +DEFIMP (AND, "AND", , "B=:*:I=B*,J=B*") +DEFIMP (BESJ0, "BESJ0", BESJ0, "R=:0:X=R*") +DEFIMP (BESJ1, "BESJ1", BESJ1, "R=:0:X=R*") +DEFIMP (BESJN, "BESJN", BESJN, "R=:1:N=I*,X=R*") +DEFIMP (BESY0, "BESY0", BESY0, "R=:0:X=R*") +DEFIMP (BESY1, "BESY1", BESY1, "R=:0:X=R*") +DEFIMP (BESYN, "BESYN", BESYN, "R=:1:N=I*,X=R*") +DEFIMP (BIT_SIZE, "BIT_SIZE", , "I=:0:I=I*i") +DEFIMP (BTEST, "BTEST", , "L1:*:I=I*,Pos=I*") DEFIMQ (CDABS, "CDABS", CDABS, "R2:-:A=C2", ABS) DEFIMQ (CDCOS, "CDCOS", CDCOS, "C2:-:X=C2", @@ -2487,40 +2965,109 @@ DEFIMQ (CDSIN, "CDSIN", CDSIN, "C2:-:X=C2", SIN) DEFIMQ (CDSQRT, "CDSQRT", CDSQRT, "C2:-:X=C2", SQRT) +DEFIMP (CHDIR, "CHDIR", CHDIR, "--:-:Dir=A1,Status=?I1w") +DEFIMP (CHMOD, "CHMOD", CHMOD, "--:-:Name=A1,Mode=A1,Status=?I*w") +DEFIMP (COMPLEX, "COMPLEX", , "C=:*:Real=S*,Imag=S*") +DEFIMP (CTIME, "CTIME", CTIME, "A1*:-:STime=I2") +DEFIMP (DATE, "DATE", DATE, "--:-:Date=A1w") +DEFIMQ (DBESJ0, "DBESJ0", DBESJ0, "R2:-:X=R2", + BESJ0) +DEFIMQ (DBESJ1, "DBESJ1", DBESJ1, "R2:-:X=R2", + BESJ1) +DEFIMQ (DBESJN, "DBESJN", DBESJN, "R2:-:N=I*,X=R2", + BESJN) +DEFIMQ (DBESY0, "DBESY0", DBESY0, "R2:-:X=R2", + BESY0) +DEFIMQ (DBESY1, "DBESY1", DBESY1, "R2:-:X=R2", + BESY1) +DEFIMQ (DBESYN, "DBESYN", DBESYN, "R2:-:N=I*,X=R2", + BESYN) DEFIMQ (DCONJG, "DCONJG", DCONJG, "C2:-:Z=C2", CONJG) DEFIMQ (DERF, "DERF", DERF, "R2:-:X=R2", ERF) DEFIMQ (DERFC, "DERFC", DERFC, "R2:-:X=R2", ERFC) +DEFIMQ (DFLOAT, "DFLOAT", , "R2:-:A=I*", + REAL) DEFIMQ (DIMAG, "DIMAG", DIMAG, "R2:-:Z=C2", AIMAG) -DEFIMP (ERF, "ERF", ERF, "R0:-:X=R0") -DEFIMP (ERFC, "ERFC", ERFC, "R0:-:X=R0") -DEFIMP (EXIT, "EXIT", EXIT, "--:-:Status=?I0") -DEFIMP (FLUSH, "FLUSH", FLUSH, "--:-:Unit=?I0") -DEFIMP (FSEEK, "FSEEK", FSEEK, "--:-:Unit=I0,Offset=I0,Whence=I0,ErrLab=?-gg") -DEFIMP (FTELL, "FTELL", FTELL, "I1:-:Unit=?I0") -DEFIMP (GETARG, "GETARG", GETARG, "--:-:Pos=I0,Value=A1w") +DEFIMQ (DREAL, "DREAL", , "R2:-:A=N*", + REAL) +DEFIMP (DTIME, "DTIME", DTIME, "R1:-:TArray=R1(2)w") +DEFIMP (ERF, "ERF", ERF, "R=:0:X=R*") +DEFIMP (ERFC, "ERFC", ERFC, "R=:0:X=R*") +DEFIMP (ETIME, "ETIME", ETIME, "R1:-:TArray=R1(2)w") +DEFIMP (EXIT, "EXIT", EXIT, "--:-:Status=?I*") +DEFIMP (FDATE, "FDATE", FDATE, "A1*:-:") +DEFIMP (FGET, "FGET", FGET, "--:-:C=A1w,Status=?I*w") +DEFIMP (FGETC, "FGETC", FGETC, "--:-:Unit=I*,C=A1w,Status=I*w") +DEFIMP (FLUSH, "FLUSH", FLUSH, "--:-:Unit=?I*") +DEFIMP (FNUM, "FNUM", FNUM, "I1:-:Unit=I*") +DEFIMP (FPUT, "FPUT", FPUT, "--:-:C=A1,Status=?I*w") +DEFIMP (FPUTC, "FPUTC", FPUTC, "--:-:Unit=I*,C=A1,Status=I*w") +DEFIMP (FSEEK, "FSEEK", FSEEK, "--:-:Unit=I*,Offset=I*,Whence=I*,ErrLab=?g*") +DEFIMP (FSTAT, "FSTAT", FSTAT, "I1:-:Unit=I*,SArray=I1(13)w") +DEFIMP (FTELL, "FTELL", FTELL, "I1:-:Unit=I*") +DEFIMP (GERROR, "GERROR", GERROR, "--:-:Message=A1w") +DEFIMP (GETARG, "GETARG", GETARG, "--:-:Pos=I*,Value=A1w") +DEFIMP (GETCWD, "GETCWD", GETCWD, "I1:-:Name=A1w") +DEFIMP (GETGID, "GETGID", GETGID, "I1:-:") +DEFIMP (GETLOG, "GETLOG", GETLOG, "--:-:Login=A1w") +DEFIMP (GETPID, "GETPID", GETPID, "I1:-:") +DEFIMP (GETUID, "GETUID", GETUID, "I1:-:") DEFIMP (GETENV, "GETENV", GETENV, "--:-:Name=A1,Value=A1w") -DEFIMP (IACHAR, "IACHAR", , "I1:-:C=A0") -DEFIMP (IAND, "IAND", , "I0:*:I=I0,J=I0") +DEFIMP (GMTIME, "GMTIME", GMTIME, "--:-:STime=I1,TArray=I1(9)w") +DEFIMP (HOSTNM, "HOSTNM", HOSTNM, "I1:-:Name=A1w") +DEFIMP (IACHAR, "IACHAR", , "I1:-:C=A*") +DEFIMP (IAND, "IAND", , "I=:*:I=I*,J=I*") DEFIMP (IARGC, "IARGC", IARGC, "I1:-:") -DEFIMP (IBCLR, "IBCLR", , "I0:1:I=I0,Pos=I0") -DEFIMP (IBITS, "IBITS", , "I0:1:I=I0,Pos=I0,Len=I0") -DEFIMP (IBSET, "IBSET", , "I0:1:I=I0,Pos=I0") -DEFIMP (IEOR, "IEOR", , "I0:*:I=I0,J=I0") -DEFIMP (IOR, "IOR", , "I0:*:I=I0,J=I0") -DEFIMP (ISHFT, "ISHFT", , "I0:1:I=I0,Shift=I0") -DEFIMP (ISHFTC, "ISHFTC", , "I0:1:I=I0,Shift=I0,Size=I0") -DEFIMP (LOC, "LOC", , "I1:-:Variable=-0&") -DEFIMP (LSHIFT, "LSHIFT", , "I0:1:I=I0,Shift=I0") -DEFIMP (MVBITS, "MVBITS", , "--:-:From=I0,FromPos=I0,Len=I0,TO=IAx,ToPos=I0") -DEFIMP (NOT, "NOT", , "I0:*:I=I0") -DEFIMP (OR, "OR", , "B0:*:I=B0,J=B0") -DEFIMP (RSHIFT, "RSHIFT", , "I0:1:I=I0,Shift=I0") -DEFIMP (SIGNAL, "SIGNAL", , "--:-:Number=I0,Handler=-ss") -DEFIMP (SYSTEM, "SYSTEM", , "--:-:Command=A1,Status=?I1") -DEFIMP (XOR, "XOR", , "B0:*:I=B0,J=B0") +DEFIMP (IBCLR, "IBCLR", , "I=:0:I=I*,Pos=I*") +DEFIMP (IBITS, "IBITS", , "I=:0:I=I*,Pos=I*,Len=I*") +DEFIMP (IBSET, "IBSET", , "I=:0:I=I*,Pos=I*") +DEFIMP (IDATE, "IDATE (UNIX)", IDATE, "--:-:TArray=I1(3)w") +DEFIMP (IDATEVXT, "IDATE (VXT)", VXTIDATE, "--:-:D=I1w,M=I1w,Y=I1w") +DEFIMP (IEOR, "IEOR", , "I=:*:I=I*,J=I*") +DEFIMP (IOR, "IOR", , "I=:*:I=I*,J=I*") +DEFIMP (IERRNO, "IERRNO", IERRNO, "I1:-:") +DEFIMQ (IMAGPART, "IMAGPART", , "R=:0:Z=C*", + AIMAG) +DEFIMP (IRAND, "IRAND", IRAND, "I1:-:Flag=?I*") +DEFIMP (ISATTY, "ISATTY", ISATTY, "L1:-:Unit=I*") +DEFIMP (ISHFT, "ISHFT", , "I=:0:I=I*,Shift=I*") +DEFIMP (ISHFTC, "ISHFTC", , "I=:0:I=I*,Shift=I*,Size=I*") +DEFIMP (ITIME, "ITIME", ITIME, "--:-:TArray=I1(3)w") +DEFIMP (KILL, "KILL", KILL, "--:-:Pid=I*,Signal=I*,Status=?I*w") +DEFIMP (LINK, "LINK", LINK, "--:-:Path1=A1,Path2=A1,Status=?I*w") +DEFIMP (LNBLNK, "LNBLNK", LNBLNK, "I1:-:String=A1") +DEFIMP (LSTAT, "LSTAT", LSTAT, "I1:-:File=A1,SArray=I1(13)w") +DEFIMP (LTIME, "LTIME", LTIME, "--:-:STime=I1,TArray=I1(9)w") +DEFIMP (LOC, "LOC", , "Ip:-:Entity=-*&&") +DEFIMP (LSHIFT, "LSHIFT", , "I=:0:I=I*,Shift=I*") +DEFIMP (MCLOCK, "MCLOCK", MCLOCK, "I2:-:") +DEFIMP (MVBITS, "MVBITS", , "--:-:From=I*,FromPos=I*,Len=I*,TO=IAx,ToPos=I*") +DEFIMP (NOT, "NOT", , "I=:0:I=I*") +DEFIMP (OR, "OR", , "B=:*:I=B*,J=B*") +DEFIMP (PERROR, "PERROR", PERROR, "--:-:String=A1") +DEFIMP (RAND, "RAND", RAND, "R1:-:Flag=?I*") +DEFIMP (REALPART, "REALPART", , "R=:0:Z=C*") +DEFIMP (RENAME, "RENAME", RENAME, "--:-:Path1=A1,Path2=A1,Status=?I*w") +DEFIMP (RSHIFT, "RSHIFT", , "I=:0:I=I*,Shift=I*") +DEFIMP (SECNDS, "SECNDS", SECNDS, "R1:-:T=R1") +DEFIMP (SECONDFUNC, "SECOND (function)", SECOND, "R1:-:") +DEFIMP (SECONDSUBR, "SECOND (subroutine)", SECOND, "--:-:Seconds=R1w") +DEFIMP (SHORT, "SHORT", , "I6:-:A=I*") +DEFIMP (SIGNAL, "SIGNAL", , "--:-:Number=I*,Handler=s*") +DEFIMP (SLEEP, "SLEEP", SLEEP, "--:-:Seconds=I1") +DEFIMP (SRAND, "SRAND", SRAND, "--:-:Seed=I*") +DEFIMP (STAT, "STAT", STAT, "I1:-:File=A1,SArray=I1(13)w") +DEFIMP (SYMLNK, "SYMLNK", SYMLNK, "--:-:Path1=A1,Path2=A1,Status=?I*w") +DEFIMP (SYSTEM, "SYSTEM", SYSTEM, "--:-:Command=A1,Status=?I1") +DEFIMP (SYSTEM_CLOCK, "SYSTEM_CLOCK", SYSTEM_CLOCK, "--:-:Count=I1w,Rate=I1w,Max=I1w") +DEFIMP (TIME, "TIME (UNIX)", TIME, "I2:-:") +DEFIMP (TIMEVXT, "TIME (VXT)", VXTTIME, "--:-:Time=A1[8]w") +DEFIMP (TTYNAM, "TTYNAM", TTYNAM, "A1*:-:Unit=I*") +DEFIMP (UMASK, "UMASK", UMASK, "--:-:Mask=I*,Old=?I*w") +DEFIMP (UNLINK, "UNLINK", UNLINK, "--:-:File=A1,Status=?I1w") +DEFIMP (XOR, "XOR", , "B=:*:I=B*,J=B*") DEFIMP (NONE, "none", , "") - diff --git a/gnu/usr.bin/gcc/f/intrin.h b/gnu/usr.bin/gcc/f/intrin.h index 16564d22d3d..fd5cbfed037 100644 --- a/gnu/usr.bin/gcc/f/intrin.h +++ b/gnu/usr.bin/gcc/f/intrin.h @@ -1,5 +1,5 @@ /* intrin.h -- Public interface for intrin.c - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995, 1996 Free Software Foundation, Inc. Contributed by James Craig Burley (burley@gnu.ai.mit.edu). This file is part of GNU Fortran. @@ -24,18 +24,21 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA #ifndef _H_f_intrin #define _H_f_intrin +#ifndef FFEINTRIN_DOC +#define FFEINTRIN_DOC 0 /* 1 means intrinsic documentation only (intdoc.c). */ +#endif + typedef enum { FFEINTRIN_familyNONE, /* Not in any family. */ FFEINTRIN_familyF77, /* ANSI FORTRAN 77. */ - FFEINTRIN_familyASC, /* ASCII-related (ACHAR, IACHAR). */ - FFEINTRIN_familyMIL, /* MIL STD 1753 (MVBITS, etc). */ - FFEINTRIN_familyDCP, /* Unnamed DOUBLE COMPLEX intrinsics. */ + FFEINTRIN_familyGNU, /* GNU Fortran intrinsics. */ + FFEINTRIN_familyF2C, /* f2c intrinsics. */ FFEINTRIN_familyF90, /* Fortran 90. */ FFEINTRIN_familyVXT, /* VAX/VMS FORTRAN. */ - FFEINTRIN_familyFVZ, /* f2c, VAX/VMS DOUBLE COMPLEX intrinsics. */ - FFEINTRIN_familyF2C, /* f2c intrinsics. */ - FFEINTRIN_familyF2Z, /* f2c DOUBLE COMPLEX intrinsics. */ + FFEINTRIN_familyMIL, /* MIL STD 1753 (MVBITS, etc), in mil, vxt, and f90. */ + FFEINTRIN_familyASC, /* ASCII-related (ACHAR, IACHAR), both f2c and f90. */ + FFEINTRIN_familyFVZ, /* in both f2c and VAX/VMS FORTRAN. */ FFEINTRIN_familyF2U, /* libf2c/libU77 UNIX system intrinsics. */ FFEINTRIN_family, } ffeintrinFamily; @@ -43,7 +46,7 @@ typedef enum typedef enum { #define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC) -#define DEFGEN(CODE,NAME,SPEC1,SPEC2) CODE, +#define DEFGEN(CODE,NAME,SPEC1,SPEC2) FFEINTRIN_gen ## CODE, #define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP) #define DEFIMP(CODE,NAME,GFRT,CONTROL) #define DEFIMQ(CODE,NAME,GFRT,CONTROL,CGIMP) @@ -60,7 +63,7 @@ typedef enum { #define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC) #define DEFGEN(CODE,NAME,SPEC1,SPEC2) -#define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP) CODE, +#define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP) FFEINTRIN_spec ## CODE, #define DEFIMP(CODE,NAME,GFRT,CONTROL) #define DEFIMQ(CODE,NAME,GFRT,CONTROL,CGIMP) #include "intrin.def" @@ -88,6 +91,8 @@ typedef enum FFEINTRIN_imp } ffeintrinImp; +#if !FFEINTRIN_DOC + #include "bld.h" #include "info.h" @@ -95,7 +100,8 @@ ffeinfoBasictype ffeintrin_basictype (ffeintrinSpec spec); ffeintrinImp ffeintrin_codegen_imp (ffeintrinImp imp); ffeintrinFamily ffeintrin_family (ffeintrinSpec spec); void ffeintrin_fulfill_generic (ffebld *expr, ffeinfo *info, ffelexToken t); -void ffeintrin_fulfill_specific (ffebld *expr, ffeinfo *info, ffelexToken t); +void ffeintrin_fulfill_specific (ffebld *expr, ffeinfo *info, + bool *check_intrin, ffelexToken t); #if FFECOM_targetCURRENT == FFECOM_targetGCC ffecomGfrt ffeintrin_gfrt (ffeintrinImp imp); #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */ @@ -107,7 +113,7 @@ void ffeintrin_init_0 (void); bool ffeintrin_is_actualarg (ffeintrinSpec spec); bool ffeintrin_is_intrinsic (char *name, ffelexToken t, bool explicit, ffeintrinGen *gen, ffeintrinSpec *spec, - ffeintrinImp *imp, ffeinfoKind *kind); + ffeintrinImp *imp); ffeinfoKindtype ffeintrin_kindtype (ffeintrinSpec spec); char *ffeintrin_name_generic (ffeintrinGen gen); char *ffeintrin_name_implementation (ffeintrinImp imp); @@ -119,6 +125,8 @@ ffeIntrinsicState ffeintrin_state_family (ffeintrinFamily family); #define ffeintrin_terminate_3() #define ffeintrin_terminate_4() +#endif /* !FFEINTRIN_DOC */ + /* End of #include file. */ #endif diff --git a/gnu/usr.bin/gcc/f/lang-options.h b/gnu/usr.bin/gcc/f/lang-options.h index f9eab62cc37..b150a2c41a6 100644 --- a/gnu/usr.bin/gcc/f/lang-options.h +++ b/gnu/usr.bin/gcc/f/lang-options.h @@ -1,5 +1,5 @@ /* lang-options.h file for Fortran - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995-1997 Free Software Foundation, Inc. Contributed by James Craig Burley (burley@gnu.ai.mit.edu). This file is part of GNU Fortran. @@ -52,16 +52,20 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA "-fno-fixed-form", "-fpedantic", "-fno-pedantic", - "-fvxt-not-f90", - "-ff90-not-vxt", + "-fvxt", + "-fno-vxt", "-fugly", "-fno-ugly", "-fugly-args", "-fno-ugly-args", + "-fugly-assign", + "-fno-ugly-assign", "-fugly-assumed", "-fno-ugly-assumed", "-fugly-comma", "-fno-ugly-comma", + "-fugly-complex", + "-fno-ugly-complex", "-fugly-init", "-fno-ugly-init", "-fugly-logint", @@ -72,6 +76,8 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA "-fno-init-local-zero", "-fbackslash", "-fno-backslash", + "-femulate-complex", + "-fno-emulate-complex", "-funderscoring", "-fno-underscoring", "-fsecond-underscore", diff --git a/gnu/usr.bin/gcc/f/lang-specs.h b/gnu/usr.bin/gcc/f/lang-specs.h index a2183903294..ea500c3d74a 100644 --- a/gnu/usr.bin/gcc/f/lang-specs.h +++ b/gnu/usr.bin/gcc/f/lang-specs.h @@ -1,5 +1,5 @@ /* lang-specs.h file for Fortran - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995, 1996 Free Software Foundation, Inc. Contributed by James Craig Burley (burley@gnu.ai.mit.edu). This file is part of GNU Fortran. diff --git a/gnu/usr.bin/gcc/f/lex.c b/gnu/usr.bin/gcc/f/lex.c index 21c493d22e8..79b3a9a6cca 100644 --- a/gnu/usr.bin/gcc/f/lex.c +++ b/gnu/usr.bin/gcc/f/lex.c @@ -1,5 +1,5 @@ /* Implementation of Fortran lexer - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995-1997 Free Software Foundation, Inc. Contributed by James Craig Burley (burley@gnu.ai.mit.edu). This file is part of GNU Fortran. @@ -61,6 +61,7 @@ static void ffelex_include_ (void); static bool ffelex_is_free_char_ctx_contin_ (ffewhereColumnNumber col); static bool ffelex_is_free_nonc_ctx_contin_ (ffewhereColumnNumber col); static void ffelex_next_line_ (void); +static void ffelex_prepare_eos_ (void); static void ffelex_send_token_ (void); static ffelexHandler ffelex_swallow_tokens_ (ffelexToken t); static ffelexToken ffelex_token_new_ (void); @@ -132,7 +133,7 @@ static ffewhereColumn ffelex_current_wc_; token. */ #define FFELEX_columnTOKEN_SIZE_ 63 #if FFELEX_columnTOKEN_SIZE_ < FFEWHERE_indexMAX -#error token size too small! +#error "token size too small!" #endif /* Current token being lexed. */ @@ -901,15 +902,17 @@ ffelex_file_push_ (int old_lineno, char *input_filename) if (input_file_stack) input_file_stack->name = input_filename; } - #endif + +/* Prepare to finish a statement-in-progress by sending the current + token, if any, then setting up EOS as the current token with the + appropriate current pointer. The caller can then move the current + pointer before actually sending EOS, if desired, as it is in + typical fixed-form cases. */ + static void -ffelex_finish_statement_ () +ffelex_prepare_eos_ () { - if ((ffelex_number_of_tokens_ == 0) - && (ffelex_token_->type == FFELEX_typeNONE)) - return; /* Don't have a statement pending. */ - if (ffelex_token_->type != FFELEX_typeNONE) { ffelex_backslash_ (EOF, 0); @@ -949,6 +952,18 @@ ffelex_finish_statement_ () ffelex_token_->type = FFELEX_typeEOS; ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); ffelex_token_->where_col = ffewhere_column_use (ffelex_current_wc_); +} + +static void +ffelex_finish_statement_ () +{ + if ((ffelex_number_of_tokens_ == 0) + && (ffelex_token_->type == FFELEX_typeNONE)) + return; /* Don't have a statement pending. */ + + if (ffelex_token_->type != FFELEX_typeEOS) + ffelex_prepare_eos_ (); + ffelex_permit_include_ = TRUE; ffelex_send_token_ (); ffelex_permit_include_ = FALSE; @@ -1520,7 +1535,7 @@ ffelex_include_ () if (card_length != 0) { #ifdef REDUCE_CARD_SIZE_AFTER_BIGGY /* Define if occasional large lines. */ -#error need to handle possible reduction of card size here!! +#error "need to handle possible reduction of card size here!!" #endif assert (ffelex_card_size_ >= card_length); /* It shrunk?? */ memcpy (ffelex_card_image_, card_image, card_length); @@ -2054,11 +2069,11 @@ ffelex_file_fixed (ffewhereFile wf, FILE *f) label) aside from a positive continuation character might have meaning in the midst of a character or hollerith constant. - 2. If a line has no explicit continuation character (a space in column 6 - and first non-blank character past column 6 is not a digit 0-9), then - there are two possibilities: + 2. If a line has no explicit continuation character (that is, it has a + space in column 6 and the first non-space character past column 6 is + not a digit 0-9), then there are two possibilities: - A. A label is present and/or a non-blank (and non-comment) character + A. A label is present and/or a non-space (and non-comment) character appears somewhere after column 6. Terminate processing of the previous statement, if any, send the new label for the next statement, if any, and start processing a new statement with this non-blank character, if @@ -2087,7 +2102,7 @@ ffelex_file_fixed (ffewhereFile wf, FILE *f) case '!': /* ANSI Fortran 90 says ! in column 6 is continuation. */ /* VXT Fortran says ! anywhere is comment, even column 6. */ - if (ffe_is_vxt_not_90 () || (column != 5)) + if (ffe_is_vxt () || (column != 5)) goto no_tokens_on_line; /* :::::::::::::::::::: */ goto got_a_continuation; /* :::::::::::::::::::: */ @@ -2096,10 +2111,13 @@ ffelex_file_fixed (ffewhereFile wf, FILE *f) goto some_other_character; /* :::::::::::::::::::: */ /* Fall through. */ if (column == 5) - goto got_a_continuation;/* :::::::::::::::::::: */ - /* This seems right to do. But it is close to call, since / * starting - in column 6 will thus be interpreted as a continuation line - beginning with '*'. */ + { + /* This seems right to do. But it is close to call, since / * starting + in column 6 will thus be interpreted as a continuation line + beginning with '*'. */ + + goto got_a_continuation;/* :::::::::::::::::::: */ + } /* Fall through. */ case '\0': /* End of line. Therefore may be continued-through line, so handle @@ -2213,6 +2231,9 @@ ffelex_file_fixed (ffewhereFile wf, FILE *f) an impending INCLUDE, and that requires accurate line info being maintained by the lexer. */ + if (finish_statement) + ffelex_prepare_eos_ (); /* Prepare EOS before we move current pointer. */ + ffewhere_line_kill (ffelex_current_wl_); ffewhere_column_kill (ffelex_current_wc_); ffelex_current_wl_ = ffewhere_line_new (ffelex_linecount_current_); @@ -2506,7 +2527,7 @@ ffelex_file_fixed (ffewhereFile wf, FILE *f) break; case '_': - if (ffe_is_90 ()) + if (1 || ffe_is_90 ()) { ffelex_token_->type = FFELEX_typeUNDERSCORE; ffelex_token_->where_line @@ -3442,7 +3463,7 @@ ffelex_file_free (ffewhereFile wf, FILE *f) break; case '_': - if (ffe_is_90 ()) + if (1 || ffe_is_90 ()) { ffelex_token_->type = FFELEX_typeUNDERSCORE; ffelex_token_->where_line diff --git a/gnu/usr.bin/gcc/f/name.h b/gnu/usr.bin/gcc/f/name.h index 1a5b4778ef4..e73d9504aa1 100644 --- a/gnu/usr.bin/gcc/f/name.h +++ b/gnu/usr.bin/gcc/f/name.h @@ -89,15 +89,16 @@ ffenameSpace ffename_space_new (mallocPool pool); #define ffename_init_2() #define ffename_init_3() #define ffename_init_4() +#define ffename_set_global(n,glob) ((n)->u.g = (glob)) +#define ffename_set_symbol(n,sym) ((n)->u.s = (sym)) +#define ffename_symbol(n) ((n)->u.s) #define ffename_terminate_0() #define ffename_terminate_1() #define ffename_terminate_2() #define ffename_terminate_3() #define ffename_terminate_4() -#define ffename_set_global(n,glob) ((n)->u.g = (glob)) -#define ffename_set_symbol(n,sym) ((n)->u.s = (sym)) -#define ffename_symbol(n) ((n)->u.s) #define ffename_text(n) ffelex_token_text((n)->t) +#define ffename_token(n) ((n)->t) #define ffename_where_filename(n) ffelex_token_where_filename((n)->t) #define ffename_where_filelinenum(n) ffelex_token_where_filelinenum((n)->t) #define ffename_where_line(n) ffelex_token_where_line((n)->t) diff --git a/gnu/usr.bin/gcc/f/news.texi b/gnu/usr.bin/gcc/f/news.texi index f0faa2d7806..60204c03927 100644 --- a/gnu/usr.bin/gcc/f/news.texi +++ b/gnu/usr.bin/gcc/f/news.texi @@ -1,11 +1,11 @@ -@c Copyright (C) 1995, 1996 Free Software Foundation, Inc. +@c Copyright (C) 1995-1997 Free Software Foundation, Inc. @c This is part of the G77 manual. @c For copying conditions, see the file g77.texi. @c The text of this file appears in the file BUGS @c in the G77 distribution, as well as in the G77 manual. -@c 1996-02-01 +@c 1997-02-25 @ifclear NEWSONLY @node News @@ -13,15 +13,271 @@ @end ifclear @cindex versions, recent @cindex recent versions -@c [In 0.5.20?] -@c @item -@c New option @samp{--enable-libu77} for use by installers -@c at configuration time to indicate that a version of the -@c @samp{libU77} is present and to be built and installed -@c along with the rest of @samp{libf2c}. + +@heading In 0.5.20: +@itemize @bullet +@item +The @samp{-fno-typeless-boz} option is now the default. + +This option specifies that non-decimal-radix +constants using the prefixed-radix form (such as @samp{Z'1234'}) +are to be interpreted as @code{INTEGER} constants. +Specify @samp{-ftypeless-boz} to cause such +constants to be interpreted as typeless. + +(Version 0.5.19 introduced @samp{-fno-typeless-boz} and +its inverse.) + +@item +Options @samp{-ff90-intrinsics-enable} and +@samp{-fvxt-intrinsics-enable} now are the +defaults. + +Some programs might use names that clash with +intrinsic names defined (and now enabled) by these +options or by the new @code{libU77} intrinsics. +Users of such programs might need to compile them +differently (using, for example, @samp{-ff90-intrinsics-disable}) +or, better yet, insert appropriate @code{EXTERNAL} +statements specifying that these names are not intended +to be names of intrinsics. + +@item +The @samp{ALWAYS_FLUSH} macro is no longer defined when +building @code{libf2c}, which should result in improved +I/O performance, especially over NFS. + +@emph{Note:} If you have code that depends on the behavior +of @code{libf2c} when built with @samp{ALWAYS_FLUSH} defined, +you will have to modify @code{libf2c} accordingly before +building it from this and future versions of @code{g77}. + +@item +Dave Love's implementation of @code{libU77} has been +added to the version of @code{libf2c} distributed with +and built as part of @code{g77}. +@code{g77} now knows about the routines in this library +as intrinsics. + +@item +New option @samp{-fvxt} specifies that the +source file is written in VXT Fortran, instead of GNU Fortran. + +@item +The @samp{-fvxt-not-f90} option has been deleted, +along with its inverse, @samp{-ff90-not-vxt}. + +If you used one of these deleted options, you should +re-read the pertinent documentation to determine which +options, if any, are appropriate for compiling your +code with this version of @code{g77}. + +@item +The @samp{-fugly} option now issues a warning, as it +likely will be removed in a future version. + +(Enabling all the @samp{-fugly-*} options is unlikely +to be feasible, or sensible, in the future, +so users should learn to specify only those +@samp{-fugly-*} options they really need for a +particular source file.) + +@item +The @samp{-fugly-assumed} option, introduced in +version 0.5.19, has been changed to +better accommodate old and new code. + +@item +Make a number of fixes to the @code{g77} front end and +the @code{gcc} back end to better support Alpha (AXP) +machines. +This includes providing at least one bug-fix to the +@code{gcc} back end for Alphas. + +@item +Related to supporting Alpha (AXP) machines, the @code{LOC()} +intrinsic and @code{%LOC()} construct now return +values of integer type that is the same width (holds +the same number of bits) as the pointer type on the +machine. + +On most machines, this won't make a difference, whereas +on Alphas, the type these constructs return is +@code{INTEGER*8} instead of the more common @code{INTEGER*4}. + +@item +Emulate @code{COMPLEX} arithmetic in the @code{g77} front +end, to avoid bugs in @code{complex} support in the +@code{gcc} back end. +New option @samp{-fno-emulate-complex} +causes @code{g77} to revert the 0.5.19 behavior. + +@item +Fix bug whereby @samp{REAL A(1)}, for example, caused +a compiler crash if @samp{-fugly-assumed} was in effect +and @var{A} was a local (automatic) array. +That case is no longer affected by the new +handling of @samp{-fugly-assumed}. + +@item +Fix @code{g77} command driver so that @samp{g77 -o foo.f} +no longer deletes @file{foo.f} before issuing other +diagnostics, and so the @samp{-x} option is properly +handled. + +@item +Enable inlining of subroutines and functions by the @code{gcc} +back end. +This works as it does for @code{gcc} itself---program units +may be inlined for invocations that follow them in the same +program unit, as long as the appropriate compile-time +options are specified. + +@item +Dummy arguments are no longer assumed to potentially alias +(overlap) +other dummy arguments or @code{COMMON} areas when any of +these are defined (assigned to) by Fortran code. + +This can result in faster and/or smaller programs when +compiling with optimization enabled, though on some +systems this effect is observed only when @samp{-fforce-addr} +also is specified. + +New options @samp{-falias-check}, @samp{-fargument-alias}, +@samp{-fargument-noalias}, +and @samp{-fno-argument-noalias-global} control the +way @code{g77} handles potential aliasing. + +@item +The @code{CONJG()} and @code{DCONJG()} intrinsics now +are compiled in-line. + +@item +The bug-fix for 0.5.19.1 has been re-done. +The @code{g77} compiler has been changed back to +assume @code{libf2c} has no aliasing problems in +its implementations of the @code{COMPLEX} (and +@code{DOUBLE COMPLEX}) intrinsics. +The @code{libf2c} has been changed to have no such +problems. + +As a result, 0.5.20 is expected to offer improved performance +over 0.5.19.1, perhaps as good as 0.5.19 in most +or all cases, due to this change alone. + +@emph{Note:} This change requires version 0.5.20 of +@code{libf2c}, at least, when linking code produced +by any versions of @code{g77} other than 0.5.19.1. +Use @samp{g77 -v} to determine the version numbers +of the @code{libF77}, @code{libI77}, and @code{libU77} +components of the @code{libf2c} library. +(If these version numbers are not printed---in +particular, if the linker complains about unresolved +references to names like @samp{g77__fvers__}---that +strongly suggests your installation has an obsolete +version of @code{libf2c}.) + +@item +New option @samp{-fugly-assign} specifies that the +same memory locations are to be used to hold the +values assigned by both statements @samp{I = 3} and +@samp{ASSIGN 10 TO I}, for example. +(Normally, @code{g77} uses a separate memory location +to hold assigned statement labels.) + +@item +@code{FORMAT} and @code{ENTRY} statements now are allowed to +precede @code{IMPLICIT NONE} statements. + +@item +Produce diagnostic for unsupported @code{SELECT CASE} on +@code{CHARACTER} type, instead of crashing, at compile time. + +@item +Fix crashes involving diagnosed or invalid code. + +@item +Change approach to building @code{libf2c} archive +(@file{libf2c.a}) so that members are added to it +only when truly necessary, so the user that installs +an already-built @code{g77} doesn't need to have write +access to the build tree (whereas the user doing the +build might not have access to install new software +on the system). + +@item +Support @code{gcc} version 2.7.2.2 +(modified by @code{g77} into version 2.7.2.2.f.2), +and remove +support for prior versions of @code{gcc}. + +@item +Upgrade to @code{libf2c} as of 1997-02-08, and +fix up some of the build procedures. + +@item +Improve general build procedures for @code{g77}, +fixing minor bugs (such as deletion of any file +named @file{f771} in the parent directory of @code{gcc/}). + +@item +Enable full support of @code{INTEGER*8} available in +@code{libf2c} and @file{f2c.h} so that @code{f2c} users +may make full use of its features via the @code{g77} +version of @file{f2c.h} and the @code{INTEGER*8} +support routines in the @code{g77} version of @code{libf2c}. + +@item +Improve @code{g77} driver and @code{libf2c} so that @samp{g77 -v} +yields version information on the library. + +@item +The @code{SNGL} and @code{FLOAT} intrinsics now are +specific intrinsics, instead of synonyms for the +generic intrinsic @code{REAL}. + +@item +New intrinsics have been added. +These are @code{REALPART}, @code{IMAGPART}, +@code{COMPLEX}, +@code{LONG}, and @code{SHORT}. + +@item +A new group of intrinsics, @samp{gnu}, has been added +to contain the new @code{REALPART}, @code{IMAGPART}, +and @code{COMPLEX} intrinsics. +An old group, @samp{dcp}, has been removed. + +@item +Complain about industry-wide ambiguous references +@samp{REAL(@var{expr})} and @samp{AIMAG(@var{expr})}, +where @var{expr} is @code{DOUBLE COMPLEX} (or any +complex type other than @code{COMPLEX}), unless +@samp{-ff90} option specifies Fortran 90 interpretation +or new @samp{-fugly-complex} option, in conjunction with +@samp{-fnot-f90}, specifies @code{f2c} interpretation. + +@item +Make improvements to diagnostics. + +@item +Speed up compiler a bit. + +@item +Improvements to documentation and indexing, including +a new chapter containing information on one, later +more, diagnostics that users are directed to pull +up automatically via a message in the diagnostic itself. + +(Hence the menu item @samp{M} for the node +@samp{Diagnostics} in the top-level menu of +the Info documentation.) +@end itemize @heading In 0.5.19.1: @itemize @bullet +@item Code-generation bugs afflicting operations on complex data have been fixed. @@ -46,26 +302,26 @@ For example, @samp{C = CSQRT(C)}, @samp{Z = Z/C}, and @samp{Z = Z**I} @heading In 0.5.19: @itemize @bullet @item -Fix @samp{FORMAT} statement parsing so negative values for +Fix @code{FORMAT} statement parsing so negative values for specifiers such as @samp{P} (e.g. @samp{FORMAT(-1PF8.1)}) are correctly processed as negative. @item -Fix @samp{SIGNAL} intrinsic so it once again accepts a +Fix @code{SIGNAL} intrinsic so it once again accepts a procedure as its second argument. @item A temporary kludge option provides bare-bones information on -@samp{COMMON} and @samp{EQUIVALENCE} members at debug time. +@code{COMMON} and @code{EQUIVALENCE} members at debug time. @item New @samp{-fonetrip} option specifies FORTRAN-66-style -one-trip @samp{DO} loops. +one-trip @code{DO} loops. @item New @samp{-fno-silent} option causes names of program units to be printed as they are compiled, in a fashion similar to -UNIX @samp{f77} and @samp{f2c}. +UNIX @code{f77} and @code{f2c}. @item New @samp{-fugly-assumed} option specifies that arrays @@ -75,7 +331,7 @@ treated as assumed-size. @item New @samp{-fno-typeless-boz} option specifies that non-decimal-radix constants using the prefixed-radix form (such as @samp{Z'1234'}) -are to be interpreted as @samp{INTEGER} constants. +are to be interpreted as @code{INTEGER} constants. @item New @samp{-ff66} option is a ``shorthand'' option that specifies @@ -83,7 +339,7 @@ behaviors considered appropriate for FORTRAN 66 programs. @item New @samp{-ff77} option is a ``shorthand'' option that specifies -behaviors considered appropriate for UNIX @samp{f77} programs. +behaviors considered appropriate for UNIX @code{f77} programs. @item New @samp{-fugly-comma} and @samp{-fugly-logint} options provided @@ -94,7 +350,7 @@ in that they do nothing more than enable (or disable) other @item Fix parsing of assignment statements involving targets that -are substrings of elements of @samp{CHARACTER} arrays having +are substrings of elements of @code{CHARACTER} arrays having names such as @samp{READ}, @samp{WRITE}, @samp{GOTO}, and @samp{REALFUNCTIONFOO}. @@ -102,7 +358,7 @@ names such as @samp{READ}, @samp{WRITE}, @samp{GOTO}, and Fix crashes involving diagnosed code. @item -Fix handling of local @samp{EQUIVALENCE} areas so certain cases +Fix handling of local @code{EQUIVALENCE} areas so certain cases of valid Fortran programs are not misdiagnosed as improperly extending the area backwards. @@ -115,21 +371,21 @@ fix up some of the build procedures. @item Change code generation for list-directed I/O so it allows -for new versions of @samp{libf2c} that might return non-zero +for new versions of @code{libf2c} that might return non-zero status codes for some operations previously assumed to always return zero. -This change not only affects how @samp{IOSTAT=} variables +This change not only affects how @code{IOSTAT=} variables are set by list-directed I/O, it also affects whether -@samp{END=} and @samp{ERR=} labels are reached by these +@code{END=} and @code{ERR=} labels are reached by these operations. @item -Add intrinsic support for new @samp{FTELL} and @samp{FSEEK} -procedures in @samp{libf2c}. +Add intrinsic support for new @code{FTELL} and @code{FSEEK} +procedures in @code{libf2c}. @item -Modify @samp{fseek_()} in @samp{libf2c} to be more portable +Modify @code{fseek_()} in @code{libf2c} to be more portable (though, in practice, there might be no systems where this matters) and to catch invalid @samp{whence} arguments. @@ -138,11 +394,11 @@ Some useless warnings from the @samp{-Wunused} option have been eliminated. @item -Fix a problem building the @samp{f771} executable +Fix a problem building the @file{f771} executable on AIX systems by linking with the @samp{-bbigtoc} option. @item -Abort configuration if @samp{gcc} has not been patched +Abort configuration if @code{gcc} has not been patched using the patch file provided in the @samp{gcc/f/gbe/} subdirectory. @@ -153,7 +409,7 @@ Also add printing of @code{g77} version number when the @samp{--verbose} (@samp{-v}) option is used. @item -Change internally generated name for local @samp{EQUIVALENCE} +Change internally generated name for local @code{EQUIVALENCE} areas to one based on the alphabetically sorted first name in the list of names for entities placed at the beginning of the areas. @@ -165,24 +421,24 @@ Improvements to documentation and indexing. @heading In 0.5.18: @itemize @bullet @item -Add some rudimentary support for @samp{INTEGER*1}, -@samp{INTEGER*2}, @samp{INTEGER*8}, -and their @samp{LOGICAL} equivalents. +Add some rudimentary support for @code{INTEGER*1}, +@code{INTEGER*2}, @code{INTEGER*8}, +and their @code{LOGICAL} equivalents. (This support works on most, maybe all, @code{gcc} targets.) -Thanks to Scott Snyder (@code{snyder@@d0sgif.fnal.gov}) +Thanks to Scott Snyder (@email{snyder@@d0sgif.fnal.gov}) for providing the patch for this! Among the missing elements from the support for these features are full intrinsic support and constants. @item -Add some rudimentary support for the @samp{BYTE} and -@samp{WORD} type-declaration statements. -@samp{BYTE} corresponds to @samp{INTEGER*1}, -while @samp{WORD} corresponds to @samp{INTEGER*2}. +Add some rudimentary support for the @code{BYTE} and +@code{WORD} type-declaration statements. +@code{BYTE} corresponds to @code{INTEGER*1}, +while @code{WORD} corresponds to @code{INTEGER*2}. -Thanks to Scott Snyder (@code{snyder@@d0sgif.fnal.gov}) +Thanks to Scott Snyder (@email{snyder@@d0sgif.fnal.gov}) for providing the patch for this! @item @@ -190,7 +446,7 @@ The compiler code handling intrinsics has been largely rewritten to accommodate the new types. No new intrinsics or arguments for existing intrinsics have been added, so there is, at this -point, no intrinsic to convert to @samp{INTEGER*8}, +point, no intrinsic to convert to @code{INTEGER*8}, for example. @item @@ -217,14 +473,14 @@ other value. @item With @samp{-ff90} in force, @code{g77} incorrectly -interpreted @samp{REAL(Z)} as returning a @samp{REAL} -result, instead of as a @samp{DOUBLE PRECISION} +interpreted @samp{REAL(Z)} as returning a @code{REAL} +result, instead of as a @code{DOUBLE PRECISION} result. -(Here, @samp{Z} is @samp{DOUBLE COMPLEX}.) +(Here, @samp{Z} is @code{DOUBLE COMPLEX}.) With @samp{-fno-f90} in force, the interpretation remains unchanged, since this appears to be how at least some -F77 code using the @samp{DOUBLE COMPLEX} extension expected +F77 code using the @code{DOUBLE COMPLEX} extension expected it to work. Essentially, @samp{REAL(Z)} in F90 is the same as @@ -233,18 +489,18 @@ be the same as @samp{REAL(REAL(Z))}. @item An expression involving exponentiation, where both operands -were type @samp{INTEGER} and the right-hand operand +were type @code{INTEGER} and the right-hand operand was negative, was erroneously evaluated. @item -Fix bugs involving @samp{DATA} implied-@samp{DO} constructs +Fix bugs involving @code{DATA} implied-@code{DO} constructs (these involved an errant diagnostic and a crash, both on good code, one involving subsequent statement-function definition). @item -Close @samp{INCLUDE} files after processing them, so compiling source -files with lots of @samp{INCLUDE} statements does not result in -being unable to open @samp{INCLUDE} files after all the available +Close @code{INCLUDE} files after processing them, so compiling source +files with lots of @code{INCLUDE} statements does not result in +being unable to open @code{INCLUDE} files after all the available file descriptors are used up. @item @@ -280,7 +536,7 @@ Fortran, and @var{n} is @samp{1} for the first Fortran patch for that version of @code{gcc}, @samp{2} for the second, and so on. -So, this introduces version @samp{2.7.2.f.1} of @code{gcc}. +So, this introduces version 2.7.2.f.1 of @code{gcc}. @item Make several improvements and fixes to diagnostics, including @@ -298,8 +554,8 @@ loops, instead of these being rejected unless @samp{-fpedantic} or @samp{-fugly} specified. @item -Allow @samp{SAVE} of a local variable or array, even after -it has been given an initial value via @samp{DATA}, for example. +Allow @code{SAVE} of a local variable or array, even after +it has been given an initial value via @code{DATA}, for example. @item Introduce an Info version of @code{g77} documentation, which @@ -311,8 +567,8 @@ The files @file{gcc/f/BUGS}, @file{gcc/f/INSTALL}, and the texinfo source when distributions are made. This effort was inspired by a first pass at translating -@code{g77-0.5.16/f/DOC} that was contributed to Craig by -David Ronis (@code{ronis@@onsager.chem.mcgill.ca}). +@file{g77-0.5.16/f/DOC} that was contributed to Craig by +David Ronis (@email{ronis@@onsager.chem.mcgill.ca}). @item New @samp{-fno-second-underscore} option to specify @@ -327,14 +583,14 @@ In particular, calculation of the iteration count is still done by converting the start, end, and increment parameters to the type of the @code{DO} variable, but the result of the calculation is always converted to -the default @samp{INTEGER} type. +the default @code{INTEGER} type. (This should have no effect on existing code compiled by @code{g77}, but code written to assume that use of a @emph{wider} type for the @code{DO} variable will result in an iteration count being fully calculated using that wider type (wider -than default @samp{INTEGER}) must be rewritten.) +than default @code{INTEGER}) must be rewritten.) @item Support @code{gcc} version 2.7.2. @@ -346,7 +602,7 @@ fix up some of the build procedures. Note that the email addresses related to @code{f2c} have changed---the distribution site now is named @code{netlib.bell-labs.com}, and the -maintainer's new address is @code{dmg@@bell-labs.com}. +maintainer's new address is @email{dmg@@bell-labs.com}. @end itemize @heading In 0.5.17: @@ -385,9 +641,9 @@ program unit (such as when input file contains @samp{@@foo}). Fix crashes, infinite loops (hangs), and such involving diagnosed code. @item -Fix @samp{ASSIGN}'ed variables so they can be @samp{SAVE}'d or dummy arguments, -and issue clearer error message in cases where target of @samp{ASSIGN} -or @samp{ASSIGN}ed @samp{GOTO}/@samp{FORMAT} is too small (which should +Fix @code{ASSIGN}'ed variables so they can be @code{SAVE}'d or dummy arguments, +and issue clearer error message in cases where target of @code{ASSIGN} +or @code{ASSIGN}ed @code{GOTO}/@code{FORMAT} is too small (which should never happen). @item @@ -400,12 +656,12 @@ options to compiler. @item Fix failure to always diagnose missing type declaration for -@samp{IMPLICIT NONE}. +@code{IMPLICIT NONE}. @item Fix compile-time performance problem (which could sometimes crash the compiler, cause a hang, or whatever, due to a bug -in the back end) involving exponentiation with a large @samp{INTEGER} +in the back end) involving exponentiation with a large @code{INTEGER} constant for the right-hand operator (e.g. @samp{I**32767}). @item @@ -418,8 +674,8 @@ interpreted by the Fortran standard (and @code{g77}) in ways that are surprising to many programmers. @item -Add @samp{ERF()} and @samp{ERFC()} as generic intrinsics mapping to existing -@samp{ERF}/@samp{DERF} and @samp{ERFC}/@samp{DERFC} specific intrinsics. +Add @code{ERF()} and @code{ERFC()} as generic intrinsics mapping to existing +@code{ERF}/@code{DERF} and @code{ERFC}/@code{DERFC} specific intrinsics. @emph{Note:} You should specify @samp{INTRINSIC ERF,ERFC} in any code where you might use @@ -428,8 +684,8 @@ these as generic intrinsics, to improve likelihood of diagnostics doesn't support these as intrinsics (e.g. @code{f2c}). @item -Remove from @samp{-fno-pedantic} the diagnostic about @samp{DO} -with non-@samp{INTEGER} index variable; issue that under +Remove from @samp{-fno-pedantic} the diagnostic about @code{DO} +with non-@code{INTEGER} index variable; issue that under @samp{-Wsurprising} instead. @item @@ -437,15 +693,15 @@ Clarify some diagnostics that say things like ``ignored'' when that's misleading. @item -Clarify diagnostic on use of @samp{.EQ.}/@samp{.NE.} on @samp{LOGICAL} +Clarify diagnostic on use of @code{.EQ.}/@code{.NE.} on @code{LOGICAL} operands. @item Minor improvements to code generation for various operations on -@samp{LOGICAL} operands. +@code{LOGICAL} operands. @item -Minor improvement to code generation for some @samp{DO} loops on some +Minor improvement to code generation for some @code{DO} loops on some machines. @item @@ -458,19 +714,19 @@ Upgrade to @code{libf2c} as of 1995-11-15. @heading In 0.5.16: @itemize @bullet @item -Fix a code-generation bug involving complicated @samp{EQUIVALENCE} statements -not involving @samp{COMMON}. +Fix a code-generation bug involving complicated @code{EQUIVALENCE} statements +not involving @code{COMMON}. @item Fix code-generation bugs involving invoking ``gratis'' library procedures in @code{libf2c} from code compiled with @samp{-fno-f2c} by making these procedures known to @code{g77} as intrinsics (not affected by -fno-f2c). -This is known to fix code invoking @samp{ERF()}, @samp{ERFC()}, -@samp{DERF()}, and @samp{DERFC()}. +This is known to fix code invoking @code{ERF()}, @code{ERFC()}, +@code{DERF()}, and @code{DERFC()}. @item Update @code{libf2c} to include netlib patches through 1995-08-16, and -@samp{#define} @samp{WANT_LEAD_0} to 1 to make @code{g77}-compiled code more +@code{#define} @samp{WANT_LEAD_0} to 1 to make @code{g77}-compiled code more consistent with other Fortran implementations by outputting leading zeros in formatted and list-directed output. @@ -482,9 +738,9 @@ compared to @code{f2c} plus @code{gcc} (but apparently only when using @file{gcc-2.7.0} or later). @item -Fix a code-generation bug involving invocation of @samp{COMPLEX} and -@samp{DOUBLE COMPLEX} @samp{FUNCTION}s and doing @samp{COMPLEX} and -@samp{DOUBLE COMPLEX} divides, when the result +Fix a code-generation bug involving invocation of @code{COMPLEX} and +@code{DOUBLE COMPLEX} @code{FUNCTION}s and doing @code{COMPLEX} and +@code{DOUBLE COMPLEX} divides, when the result of the invocation or divide is assigned directly to a variable that overlaps one or more of the arguments to the invocation or divide. @@ -500,7 +756,7 @@ Fix crash on expressions like @samp{COMPLEX**INTEGER}. @item Fix crash on expressions like @samp{(1D0,2D0)**2}, i.e. raising a -@samp{DOUBLE COMPLEX} constant to an @samp{INTEGER} constant power. +@code{DOUBLE COMPLEX} constant to an @code{INTEGER} constant power. @item Fix crashes and such involving diagnosed code. @@ -515,7 +771,7 @@ definitions. @item Fix bug resulting in debugger not knowing size of local equivalence -area when any member of area has initial value (via @samp{DATA}, +area when any member of area has initial value (via @code{DATA}, for example). @item @@ -530,7 +786,7 @@ gratuitously invoke the @item Fix diagnostic to point to correct source line when it immediately -follows an @samp{INCLUDE} statement. +follows an @code{INCLUDE} statement. @item Support more compiler options in @code{gcc}/@code{g77} when @@ -542,13 +798,13 @@ automatic insertion of configuration-specific linker specs. @item Add new intrinsics that interface to existing routines in @code{libf2c}: -@samp{ABORT}, @samp{DERF}, @samp{DERFC}, @samp{ERF}, @samp{ERFC}, @samp{EXIT}, -@samp{FLUSH}, @samp{GETARG}, @samp{GETENV}, @samp{IARGC}, -@samp{SIGNAL}, and @samp{SYSTEM}. -Note that @samp{ABORT}, @samp{EXIT}, @samp{FLUSH}, @samp{SIGNAL}, and -@samp{SYSTEM} are intrinsic subroutines, not functions (since they -have side effects), so to get the return values from @samp{SIGNAL} -and @samp{SYSTEM}, append a final argument specifying an @samp{INTEGER} +@code{ABORT}, @code{DERF}, @code{DERFC}, @code{ERF}, @code{ERFC}, @code{EXIT}, +@code{FLUSH}, @code{GETARG}, @code{GETENV}, @code{IARGC}, +@code{SIGNAL}, and @code{SYSTEM}. +Note that @code{ABORT}, @code{EXIT}, @code{FLUSH}, @code{SIGNAL}, and +@code{SYSTEM} are intrinsic subroutines, not functions (since they +have side effects), so to get the return values from @code{SIGNAL} +and @code{SYSTEM}, append a final argument specifying an @code{INTEGER} variable or array element (e.g. @samp{CALL SYSTEM('rm foo',ISTAT)}). @item @@ -556,7 +812,7 @@ Add new intrinsic group named @samp{unix} to contain the new intrinsics, and by default enable this new group. @item -Move @samp{LOC()} intrinsic out of the @samp{vxt} group to the new +Move @code{LOC()} intrinsic out of the @samp{vxt} group to the new @samp{unix} group. @item @@ -585,7 +841,7 @@ Support @code{gcc}'s @samp{-fident} and @samp{-fno-ident} options. @item When @samp{-Wunused} in effect, don't warn about local variables used as -statement-function dummy arguments or @samp{DATA} implied-@samp{DO} iteration +statement-function dummy arguments or @code{DATA} implied-@code{DO} iteration variables, even though, strictly speaking, these are not uses of the variables themselves. @@ -612,7 +868,7 @@ macros defined in @file{gcc/f/target.h} and used in places like @item Add warning to be printed for each invocation of the compiler -if the target machine @samp{INTEGER}, REAL, or @samp{LOGICAL} size +if the target machine @code{INTEGER}, @code{REAL}, or @code{LOGICAL} size is not 32 bits, since @code{g77} is known to not work well for such cases (to be fixed in Version 0.6---@pxref{Actual Bugs,,Actual Bugs We Haven't Fixed Yet}). @@ -631,7 +887,7 @@ smaller library without lots of debugging clutter. @itemize @bullet @item Fix bad code generation involving @samp{X**I} and temporary, internal variables -generated by @code{g77} and the back end (such as for @samp{DO} loops). +generated by @code{g77} and the back end (such as for @code{DO} loops). @item Fix crash given @samp{CHARACTER A;DATA A/.TRUE./}. @@ -647,7 +903,7 @@ Fix crash or other erratic behavior when null character constant Fix crash or other erratic behavior involving diagnosed code. @item -Fix code generation for external functions returning type @samp{REAL} when +Fix code generation for external functions returning type @code{REAL} when the @samp{-ff2c} option is in force (which it is by default) so that @code{f2c} compatibility is indeed provided. @@ -671,15 +927,15 @@ as @code{gcc} back end is to be fixed to do this even better, and it turned out to slow down some code in some cases after all. @item -In @samp{COMMON} and @samp{EQUIVALENCE} areas with any members given initial -values (e.g. via @samp{DATA}), uninitialized members now always +In @code{COMMON} and @code{EQUIVALENCE} areas with any members given initial +values (e.g. via @code{DATA}), uninitialized members now always initialized to binary zeros (though this is not required by the standard, and might not be done in future versions of @code{g77}). -Previously, in some @samp{COMMON}/@samp{EQUIVALENCE} areas +Previously, in some @code{COMMON}/@code{EQUIVALENCE} areas (essentially those with members of more than one type), the uninitialized members were initialized to spaces, to -cater to @samp{CHARACTER} types, but it seems no existing code expects +cater to @code{CHARACTER} types, but it seems no existing code expects that, while much existing code expects binary zeros. @end itemize @@ -690,7 +946,7 @@ Don't emit bad code when low bound of adjustable array is nonconstant and thus might vary as an expression at run time. @item -Emit correct code for calculation of number of trips in @samp{DO} loops +Emit correct code for calculation of number of trips in @code{DO} loops for cases where the loop should not execute at all. (This bug affected cases @@ -699,31 +955,31 @@ than the step count, though probably not for floating-point cases.) @item Fix crash when extra parentheses surround item in -@samp{DATA} implied-@samp{DO} list. +@code{DATA} implied-@code{DO} list. @item Fix crash over minor internal inconsistencies in handling diagnostics, just substitute dummy strings where necessary. @item -Fix crash on some systems when compiling call to @samp{MVBITS()} intrinsic. +Fix crash on some systems when compiling call to @code{MVBITS()} intrinsic. @item -Fix crash on array assignment @samp{TYPE@var{ddd}(...)=...}, where @var{ddd} +Fix crash on array assignment @samp{TYPE@var{ddd}(@dots{})=@dots{}}, where @var{ddd} is a string of one or more digits. @item -Fix crash on @samp{DCMPLX()} with a single @samp{INTEGER} argument. +Fix crash on @code{DCMPLX()} with a single @code{INTEGER} argument. @item Fix various crashes involving code with diagnosed errors. @item -Support @samp{-I} option for @samp{INCLUDE} statement, plus @code{gcc}'s +Support @samp{-I} option for @code{INCLUDE} statement, plus @code{gcc}'s @file{header.gcc} facility for handling systems like MS-DOS. @item -Allow @samp{INCLUDE} statement to be continued across multiple lines, +Allow @code{INCLUDE} statement to be continued across multiple lines, even allow it to coexist with other statements on the same line. @item @@ -750,10 +1006,10 @@ related warnings that might be helpful won't be seen. @item New @samp{-fbackslash} option, on by default, that causes @samp{\} -within @samp{CHARACTER} +within @code{CHARACTER} and Hollerith constants to be interpreted a la GNU C. Note that -this behavior is somewhat different from @samp{f2c}'s, which supports only +this behavior is somewhat different from @code{f2c}'s, which supports only a limited subset of backslash (escape) sequences. @item @@ -762,19 +1018,19 @@ Make @samp{-fugly-args} the default. @item New @samp{-fugly-init} option, on by default, that allows typeless/Hollerith to be specified as initial values for variables or named constants -(@samp{PARAMETER}), and also allows character<->numeric conversion in +(@code{PARAMETER}), and also allows character<->numeric conversion in those contexts---turn off via @samp{-fno-ugly-init}. @item New @samp{-finit-local-zero} option to initialize local variables to binary zeros. -This does not affect whether they are @samp{SAVE}d, i.e. made +This does not affect whether they are @code{SAVE}d, i.e. made automatic or static. @item New @samp{-Wimplicit} option to warn about implicitly typed variables, arrays, and functions. -(Basically causes all program units to default to @samp{IMPLICIT NONE}.) +(Basically causes all program units to default to @code{IMPLICIT NONE}.) @item @samp{-Wall} now implies @samp{-Wuninitialized} as with @code{gcc} @@ -783,20 +1039,20 @@ requires @samp{-O}), and implies @samp{-Wunused} as well. @item @samp{-Wunused} no longer gives spurious messages for unused -@samp{EXTERNAL} names (since they are assumed to refer to block data +@code{EXTERNAL} names (since they are assumed to refer to block data program units, to make use of libraries more reliable). @item -Support @samp{%LOC()} and @samp{LOC()} of character arguments. +Support @code{%LOC()} and @code{LOC()} of character arguments. @item Support null (zero-length) character constants and expressions. @item -Support @code{f2c}'s @samp{IMAG()} generic intrinsic. +Support @code{f2c}'s @code{IMAG()} generic intrinsic. @item -Support @samp{ICHAR()}, @samp{IACHAR()}, and @samp{LEN()} of +Support @code{ICHAR()}, @code{IACHAR()}, and @code{LEN()} of character expressions that are valid in assignments but not normally as actual arguments. @@ -804,11 +1060,11 @@ not normally as actual arguments. Support @code{f2c}-style @samp{&} in column 1 to mean continuation line. @item -Allow @samp{NAMELIST}, @samp{EXTERNAL}, @samp{INTRINSIC}, and @samp{VOLATILE} -in @samp{BLOCK DATA}, even though these are not allowed by the standard. +Allow @code{NAMELIST}, @code{EXTERNAL}, @code{INTRINSIC}, and @code{VOLATILE} +in @code{BLOCK DATA}, even though these are not allowed by the standard. @item -Allow @samp{RETURN} in main program unit. +Allow @code{RETURN} in main program unit. @item Changes to Hollerith-constant support to obey Appendix C of the @@ -823,28 +1079,28 @@ Hollerith ``format specifications'' in the form of arrays of non-character allowed. @item -Warnings issued when non-blank truncation occurs when converting +Warnings issued when non-space truncation occurs when converting to another type. @item When specified as actual argument, now passed -by reference to @samp{INTEGER} (padded on right with spaces if constant -too small, otherwise fully intact if constant wider the @samp{INTEGER} +by reference to @code{INTEGER} (padded on right with spaces if constant +too small, otherwise fully intact if constant wider the @code{INTEGER} type) instead of by value. @end itemize @strong{Warning:} @code{f2c} differs on the interpretation of @samp{CALL FOO(1HX)}, which it treats exactly the same as @samp{CALL FOO('X')}, but which the standard and @code{g77} treat -as @samp{CALL FOO(%REF('X '))} (padded with as many blanks as necessary -to widen to @samp{INTEGER}), essentially. +as @samp{CALL FOO(%REF('X '))} (padded with as many spaces as necessary +to widen to @code{INTEGER}), essentially. @item Changes and fixes to typeless-constant support: @itemize -- @item -Now treated as a typeless double-length @samp{INTEGER} value. +Now treated as a typeless double-length @code{INTEGER} value. @item Warnings issued when overflow occurs. @@ -859,15 +1115,15 @@ the target machine for whatever type it is turned into. @item When specified as actual argument, now passed as reference to -a default @samp{INTEGER} constant. +a default @code{INTEGER} constant. @end itemize @item -@samp{%DESCR()} of a non-@samp{CHARACTER} expression now passes a pointer to +@code{%DESCR()} of a non-@code{CHARACTER} expression now passes a pointer to the expression plus a length for the expression just as if -it were a @samp{CHARACTER} expression. +it were a @code{CHARACTER} expression. For example, @samp{CALL FOO(%DESCR(D))}, where -@samp{D} is @samp{REAL*8}, is the same as @samp{CALL FOO(D,%VAL(8)))}. +@samp{D} is @code{REAL*8}, is the same as @samp{CALL FOO(D,%VAL(8)))}. @item Name of multi-entrypoint master function changed to incorporate @@ -876,7 +1132,7 @@ value, so the name of the master function for @samp{SUBROUTINE X} with alternate entry points is now @samp{__g77_masterfun_x}. @item -Remove redundant message about zero-step-count @samp{DO} loops. +Remove redundant message about zero-step-count @code{DO} loops. @item Clean up diagnostic messages, shortening many of them. @@ -889,17 +1145,17 @@ Clarify implications of constant-handling bugs in @file{f/BUGS}. @item Generate better code for @samp{**} operator with a right-hand operand of -type @samp{INTEGER}. +type @code{INTEGER}. @item -Generate better code for @samp{SQRT()} and @samp{DSQRT()}, +Generate better code for @code{SQRT()} and @code{DSQRT()}, also when @samp{-ffast-math} -specified, enable better code generation for @samp{SIN()} and @samp{COS()}. +specified, enable better code generation for @code{SIN()} and @code{COS()}. @item Generate better code for some kinds of array references. @item -Speed up lexing somewhat (this makes the compilation phase noticably +Speed up lexing somewhat (this makes the compilation phase noticeably faster). @end itemize diff --git a/gnu/usr.bin/gcc/f/proj.h b/gnu/usr.bin/gcc/f/proj.h index ca092fa8985..205130a49d1 100644 --- a/gnu/usr.bin/gcc/f/proj.h +++ b/gnu/usr.bin/gcc/f/proj.h @@ -1,5 +1,5 @@ /* proj.h file for Gnu Fortran - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995, 1996 Free Software Foundation, Inc. Contributed by James Craig Burley (burley@gnu.ai.mit.edu). This file is part of GNU Fortran. diff --git a/gnu/usr.bin/gcc/f/runtime/ChangeLog b/gnu/usr.bin/gcc/f/runtime/ChangeLog index 8d2f0b12590..bd1edf5d3a8 100644 --- a/gnu/usr.bin/gcc/f/runtime/ChangeLog +++ b/gnu/usr.bin/gcc/f/runtime/ChangeLog @@ -1,3 +1,179 @@ +Fri Feb 28 13:16:50 1997 Craig Burley <burley@gnu.ai.mit.edu> + + * Version 0.5.20 released. + +Wed Feb 26 20:28:53 1997 Craig Burley <burley@gnu.ai.mit.edu> + + * Makefile.in: $(MAKE) invocations now explicitly + specify `-f Makefile', just in case the `makefile's + from the netlib distribution would get used instead. + +Mon Feb 24 16:43:39 1997 Craig Burley <burley@gnu.ai.mit.edu> + + * libU77/Makefile.in (check): Specify driver, and + don't bother enabling already-enabled intrinsic groups. + Also, get the $(srcdir) version of u77-test.f. + +Sat Feb 22 14:08:42 1997 Craig Burley <burley@gnu.ai.mit.edu> + + * libU77/u77-test.f: Explicitly declare intrinsics, get + rid of useless CHARACTER declarations on intrinsics (maybe + someday appropriate to implement meaning of that in g77 + and restore them?). + Add spin loop just to fatten up the timings a bit. + Clarify ETIME output as having three fields. + Call TIME with CHARACTER*8, not CHARACTER*6, argument. + Call new SECOND intrinsic subroutine, after calling + new DUMDUM subroutine just to ensure the correct value + doesn't get left around in a register or something. + +Thu Feb 20 15:22:42 1997 Craig Burley <burley@gnu.ai.mit.edu> + + * libU77/bes.c: Comment out all the code, as g77 avoids actually + calling it, going directly to the system's library instead. + +Mon Feb 17 02:27:41 1997 Craig Burley <burley@gnu.ai.mit.edu> + + * libU77/fgetc_.c (fgetc_): Allow return value to be + CHARACTER*(*), properly handle CHARACTER*0 and blank-pad + CHARACTER*n where n>1. + +Tue Feb 11 14:12:19 1997 Craig Burley <burley@gnu.ai.mit.edu> + + * Makefile.in: Clarify role of $(srcdir) here. Fix + various targets accordingly. Don't rely at all on + gcc/f/include/ being a link to gcc/include/ -- just + use it directly. + (${srcdir}/configure, ${srcdir}/libU77/configure): + Remove the config.cache files in build directory before + cd'ing to source directory as well. + + * libF77/Makefile.in, libI77/Makefile.in (ALL_CFLAGS): + Include `-I.' to pick up build directory. + Use gcc/include/ directly. + * libU77/Makefile.in (ALL_CFLAGS): Include `-I$(srcdir)' + to pick up source directory. + (OBJS): Fix typo in `chmod_.o' (was `chmod.o'). + +Mon Feb 10 12:54:47 1997 Craig Burley <burley@gnu.ai.mit.edu> + + * Makefile.in (UOBJ), libU77/Makefile.in (OBJS): Add + libU77/chmod_.o to list of objects. + * libU77/chmod_.c: Fix up headers. + Fix implementation to not prematurely truncate command + string and make room for trailing null. + + * libU77/ctime_.c: Incoming xstime argument is now longint. + * libU77/mclock_.c: Now returns longint. + * libU77/time_.c: Now returns longint. + +1997-02-10 Dave Love <d.love@dl.ac.uk> + + * etime_.c, dtime_.c: Typo rounded times to seconds. + + * date_.c: Add missing return. + + * hostnm_.c: #include unistd.h. + +Sat Feb 8 03:30:19 1997 Craig Burley <burley@gnu.ai.mit.edu> + + INTEGER*8 support built in to f2c.h and libf2c (since + gcc will be used to compile relevant code anyway): + * Makefile.in, libF77/Makefile.in: Add pow_qq.o, + qbitbits.o, and qbitshft.o to $POW and $F90BIT macros, + as appropriate. + * f2c.h.in: Define appropriate types and macros. + Place #error directive correctly. + * configure.in: Determine appropriate types for long + integer (F2C_LONGINT). + Meanwhile, quote strings in #error, for consistency. + Fix restoring of ac_cpp macro. + * configure: Regenerated using autoconf-2.12. + + * libF77/Version.c, libI77/Version.c, libU77/Version.c: + Update version numbers. + Change names and code for g77-specific version-printing + routines (shorter names should be safer to link on + weird, 8-char systems). + + * libF77/c_cos.c, libF77/c_div.c, libF77/c_exp.c, + libF77/c_log.c, libF77/c_sin.c, libF77/c_sqrt.c, + libF77/d_cnjg.c, libF77/pow_zi.c, libF77/r_cnjg.c, + libF77/z_cos.c, libF77/z_div.c, libF77/z_exp.c, + libF77/z_log.c, libF77/z_sin.c, libF77/z_sqrt.c: + Changed to work properly even when result is aliased + with any inputs. + + * libF77/makefile, libI77/makefile: Leave these in + the g77 distribution, so it is easier to track changes + to official libf2c. + + * libF77/signal_.c: Eliminate redundant `return 0;'. + + * libI77/fio.h (err, errfl): Fix these so they work + (and must be expressed) as statements. + Fix up many users of err() to include trailing semicolon. + + * Incorporate changes by Bell Labs to libf2c through 1997-02-07. + +1997-02-06 Dave Love <d.love@dl.ac.uk> + + * libU77/etime_.c, libU77/dtime_.c: Fix getrusage stuff. + + * libU77/config.h.in: Regenerate for HAVE_GETRUSAGE. + + * libU77/Makefile.in, libI77/Makefile.in, libF77/Makefile.in: + Redo *clean targets; distclean and maintainer-clean remove the stage? + and include links. This probably want looking at further. + +Wed Feb 5 00:21:23 1997 Craig Burley <burley@gnu.ai.mit.edu> + + Add libU77 library from Dave Love <d.love@dl.ac.uk>: + * Makefile.in: Add libU77 directory, rules, etc. + * configure.in: New libU77 directory, Makefile, etc. + + * Makefile.in, libF77/Makefile.in, libI77/Makefile.in, + libU77/Makefile.in: Reorganize these so $(AR) commands + handled by the top-level Makefile instead of the + subordinates. This permits it to do $(AR) only when + one or more object files actually change, instead of + having to force-update it as was necessary before. + And that had the disadvantage of requiring, e.g., user + root to have access to $(AR) to the library simply to + install g77, which might be problematic on an NFS setup. + (mostlyclean, clean, distclean, maintainer-clean): + Properly handle these rules. + + * Makefile.in: Don't invoke config.status here -- let + compiler-level stuff handle all that. + + * err.c [MISSING_FILE_ELEMS]: Declare malloc in this case + too, so it doesn't end up as an integer. + +Sat Feb 1 02:43:48 1997 Craig Burley <burley@gnu.ai.mit.edu> + + * libF77/Makefile.in: More fixup for $(F90BIT) -- wasn't + in list for ar command, and it wasn't correctly listed + in the list of things depending on f2c.h. + + * f2c.h.in: Fix up #error directive. + +1997-01-31 Dave Love <d.love@dl.ac.uk> + + * libF77/Makefile.in ($(lib)): Add $(F90BIT); shouldn't exclude + stuff f2c needs so we can share the library. + +Sat Jan 18 19:39:03 1997 Craig Burley <burley@gnu.ai.mit.edu> + + * configure.in: No longer define ALWAYS_FLUSH, the + resulting performance is too low. + +Wed Dec 18 12:06:02 1996 Craig Burley <burley@gnu.ai.mit.edu> + + Patch from Mumit Khan <khan@xraylith.wisc.edu>: + * libF77/s_paus.c: Add __CYGWIN32__ to list of macros + controlling how to pause. + Sun Dec 1 21:25:27 1996 Craig Burley <burley@gnu.ai.mit.edu> * configure: Regenerated using autoconf-2.12. @@ -52,7 +228,7 @@ Thu Oct 31 22:27:45 1996 Craig Burley <burley@gnu.ai.mit.edu> Wed Aug 28 13:25:29 1996 Dave Love <d.love@dl.ac.uk> - * libI77/rsne.c (x_rsne): Use size_t instead f int. + * libI77/rsne.c (x_rsne): Use size_t instead of int. * libI77/endfile.c (copy): Use size_t in place of int. diff --git a/gnu/usr.bin/gcc/f/runtime/Makefile.in b/gnu/usr.bin/gcc/f/runtime/Makefile.in index 88196acca14..3aae19baa64 100644 --- a/gnu/usr.bin/gcc/f/runtime/Makefile.in +++ b/gnu/usr.bin/gcc/f/runtime/Makefile.in @@ -1,5 +1,5 @@ # Makefile for GNU F77 compiler runtime. -# Copyright (C) 1995 Free Software Foundation, Inc. +# Copyright (C) 1995-1997 Free Software Foundation, Inc. # Contributed by Dave Love (d.love@dl.ac.uk). # #This file is part of GNU Fortran. @@ -21,6 +21,9 @@ #### Start of system configuration section. #### +# $(srcdir) must be set to the g77 runtime source directory +# (g77/f/runtime/). + srcdir = @srcdir@ VPATH = @srcdir@ @@ -63,7 +66,70 @@ infodir = $(prefix)/info SHELL = /bin/sh -SUBDIRS = libI77 libF77 +lib = ../../libf2c.a + +SUBDIRS = libI77 libF77 libU77 + +MISC = libF77/F77_aloc.o libF77/VersionF.o libF77/main.o libF77/s_rnge.o \ + libF77/abort_.o libF77/getarg_.o libF77/iargc_.o libF77/getenv_.o \ + libF77/signal_.o libF77/s_stop.o libF77/s_paus.o libF77/system_.o \ + libF77/cabs.o libF77/derf_.o libF77/derfc_.o libF77/erf_.o \ + libF77/erfc_.o libF77/sig_die.o libF77/exit.o +POW = libF77/pow_ci.o libF77/pow_dd.o libF77/pow_di.o libF77/pow_hh.o \ + libF77/pow_ii.o libF77/pow_ri.o libF77/pow_zi.o libF77/pow_zz.o \ + libF77/pow_qq.o +CX = libF77/c_abs.o libF77/c_cos.o libF77/c_div.o libF77/c_exp.o \ + libF77/c_log.o libF77/c_sin.o libF77/c_sqrt.o +DCX = libF77/z_abs.o libF77/z_cos.o libF77/z_div.o libF77/z_exp.o \ + libF77/z_log.o libF77/z_sin.o libF77/z_sqrt.o +REAL = libF77/r_abs.o libF77/r_acos.o libF77/r_asin.o libF77/r_atan.o \ + libF77/r_atn2.o libF77/r_cnjg.o libF77/r_cos.o libF77/r_cosh.o \ + libF77/r_dim.o libF77/r_exp.o libF77/r_imag.o libF77/r_int.o \ + libF77/r_lg10.o libF77/r_log.o libF77/r_mod.o libF77/r_nint.o \ + libF77/r_sign.o libF77/r_sin.o libF77/r_sinh.o libF77/r_sqrt.o \ + libF77/r_tan.o libF77/r_tanh.o +DBL = libF77/d_abs.o libF77/d_acos.o libF77/d_asin.o libF77/d_atan.o \ + libF77/d_atn2.o libF77/d_cnjg.o libF77/d_cos.o libF77/d_cosh.o \ + libF77/d_dim.o libF77/d_exp.o libF77/d_imag.o libF77/d_int.o \ + libF77/d_lg10.o libF77/d_log.o libF77/d_mod.o libF77/d_nint.o \ + libF77/d_prod.o libF77/d_sign.o libF77/d_sin.o libF77/d_sinh.o \ + libF77/d_sqrt.o libF77/d_tan.o libF77/d_tanh.o +INT = libF77/i_abs.o libF77/i_dim.o libF77/i_dnnt.o libF77/i_indx.o \ + libF77/i_len.o libF77/i_mod.o libF77/i_nint.o libF77/i_sign.o +HALF = libF77/h_abs.o libF77/h_dim.o libF77/h_dnnt.o libF77/h_indx.o \ + libF77/h_len.o libF77/h_mod.o libF77/h_nint.o libF77/h_sign.o +CMP = libF77/l_ge.o libF77/l_gt.o libF77/l_le.o libF77/l_lt.o \ + libF77/hl_ge.o libF77/hl_gt.o libF77/hl_le.o libF77/hl_lt.o +EFL = libF77/ef1asc_.o libF77/ef1cmc_.o +CHAR = libF77/s_cat.o libF77/s_cmp.o libF77/s_copy.o +F90BIT = libF77/lbitbits.o libF77/lbitshft.o libF77/qbitbits.o \ + libF77/qbitshft.o +FOBJ = $(MISC) $(POW) $(CX) $(DCX) $(REAL) $(DBL) $(INT) $(HALF) $(CMP) \ + $(EFL) $(CHAR) $(F90BIT) + +IOBJ = libI77/VersionI.o libI77/backspace.o libI77/close.o libI77/dfe.o \ + libI77/dolio.o libI77/due.o libI77/endfile.o libI77/err.o \ + libI77/fmt.o libI77/fmtlib.o libI77/iio.o libI77/ilnw.o \ + libI77/inquire.o libI77/lread.o libI77/lwrite.o libI77/open.o \ + libI77/rdfmt.o libI77/rewind.o libI77/rsfe.o libI77/rsli.o \ + libI77/rsne.o libI77/sfe.o libI77/sue.o libI77/typesize.o \ + libI77/uio.o libI77/util.o libI77/wref.o libI77/wrtfmt.o \ + libI77/wsfe.o libI77/wsle.o libI77/wsne.o libI77/xwsne.o \ + libI77/ftell_.o + +UOBJ = libU77/VersionU.o libU77/gerror_.o libU77/perror_.o libU77/ierrno_.o \ + libU77/itime_.o libU77/time_.o libU77/unlink_.o libU77/fnum_.o \ + libU77/getpid_.o libU77/getuid_.o libU77/getgid_.o libU77/kill_.o \ + libU77/rand_.o libU77/srand_.o libU77/irand_.o libU77/sleep_.o \ + libU77/idate_.o libU77/ctime_.o libU77/etime_.o libU77/dtime_.o \ + libU77/isatty_.o libU77/ltime_.o libU77/fstat_.o libU77/stat_.o \ + libU77/lstat_.o libU77/access_.o libU77/link_.o libU77/getlog_.o \ + libU77/ttynam_.o libU77/getcwd_.o libU77/vxttime_.o \ + libU77/vxtidate_.o libU77/gmtime_.o libU77/fdate_.o libU77/secnds_.o \ + libU77/bes.o libU77/dbes.o libU77/chdir_.o libU77/chmod_.o \ + libU77/lnblnk_.o libU77/hostnm_.o libU77/rename_.o libU77/fgetc_.o \ + libU77/fputc_.o libU77/umask_.o libU77/system_clock_.o libU77/date_.o \ + libU77/second_.o libU77/flush1_.o # flags_to_pass to recursive makes & configure (hence the quoting style) FLAGS_TO_PASS = \ @@ -90,48 +156,71 @@ CROSS_FLAGS_TO_PASS = \ RANLIB_TEST="$(RANLIB_TEST)" \ SHELL="$(SHELL)" -all: ../include/f2c.h libi77 libf77 +all: ../../include/f2c.h libi77 libf77 libu77 $(lib) + +$(lib): $(FOBJ) $(IOBJ) $(UOBJ) + -$(AR) $(AR_FLAGS) $(lib) $? + if $(RANLIB_TEST); then $(RANLIB) $(lib); \ + else true; fi libi77: libI77/Makefile if test "$(CROSS)"; then \ - cd libI77; $(MAKE) $(CROSS_FLAGS_TO_PASS) all ; \ + cd libI77; $(MAKE) -f Makefile $(CROSS_FLAGS_TO_PASS) all ; \ else \ - cd libI77; $(MAKE) $(FLAGS_TO_PASS) all ; \ + cd libI77; $(MAKE) -f Makefile $(FLAGS_TO_PASS) all ; \ fi + libf77: libF77/Makefile if test "$(CROSS)"; then \ - cd libF77; $(MAKE) $(CROSS_FLAGS_TO_PASS) all ; \ + cd libF77; $(MAKE) -f Makefile $(CROSS_FLAGS_TO_PASS) all ; \ else \ - cd libF77; $(MAKE) $(FLAGS_TO_PASS) all ; \ + cd libF77; $(MAKE) -f Makefile $(FLAGS_TO_PASS) all ; \ + fi + +libu77: libU77/Makefile + if test "$(CROSS)"; then \ + cd libU77; $(MAKE) -f Makefile $(CROSS_FLAGS_TO_PASS) all ; \ + else \ + cd libU77; $(MAKE) -f Makefile $(FLAGS_TO_PASS) all ; \ fi ${srcdir}/configure: ${srcdir}/configure.in - cd ${srcdir} && autoconf && rm -f config.cache -../include/f2c.h libI77/Makefile libF77/Makefile Makefile: Makefile.in \ - config.status - $(FLAGS_TO_PASS) CONFIG_SITE=/dev/null $(SHELL) config.status + rm -f config.cache && cd ${srcdir} && autoconf && rm -f config.cache +${srcdir}/libU77/configure: ${srcdir}/libU77/configure.in + rm -f libU77/config.cache && cd ${srcdir}/libU77 && autoconf && rm -f config.cache +#../include/f2c.h libI77/Makefile libF77/Makefile libU77/Makefile Makefile: ${srcdir}/Makefile.in \ +# config.status libU77/config.status +# $(FLAGS_TO_PASS) CONFIG_SITE=/dev/null $(SHELL) config.status +# cd libU77; $(FLAGS_TO_PASS) CONFIG_SITE=/dev/null $(SHELL) config.status + # Extra dependencies for the targets above: -libI77/Makefile: libI77/Makefile.in -libF77/Makefile: libF77/Makefile.in -# include is linked into .. -../include/f2c.h: f2c.h.in +libI77/Makefile: $(srcdir)/libI77/Makefile.in +libF77/Makefile: $(srcdir)/libF77/Makefile.in +libU77/Makefile: $(srcdir)/libU77/Makefile.in +../../include/f2c.h: $(srcdir)/f2c.h.in -config.status: configure - $(FLAGS_TO_PASS) CONFIG_SITE=/dev/null $(SHELL) config.status --recheck +#config.status: ${srcdir}/configure +# $(FLAGS_TO_PASS) CONFIG_SITE=/dev/null $(SHELL) config.status --recheck +#libU77/config.status: ${srcdir}/libU77/configure +# cd libU77; $(FLAGS_TO_PASS) CONFIG_SITE=/dev/null $(SHELL) config.status --recheck mostlyclean: + for i in libI77 libF77 libU77; do cd $$i; $(MAKE) -f Makefile mostlyclean; cd ..; done -clean: mostlyclean +clean: -rm -f config.log config.cache - for i in libI77 libF77; do cd $$i; $(MAKE) clean; cd ..; done + for i in libI77 libF77 libU77; do cd $$i; $(MAKE) -f Makefile clean; cd ..; done distclean: clean - -rm -f Makefile lib?77/Makefile config.status ../include/f2c.h + -rm -f Makefile lib?77/Makefile config.status libU77/config.status ../../include/f2c.h + +maintainer-clean: distclean + -rm -f $(srcdir)/configure $(srcdir)/libU77/configure uninstall: - rm ../include/f2c.h + rm ../../include/f2c.h -rebuilt: ${srcdir}/configure - echo Fortran library rebuildable files rebuilt. +rebuilt: ${srcdir}/configure ${srcdir}/libU77/configure -.PHONY: libf77 libi77 rebuilt +.PHONY: libf77 libi77 libu77 rebuilt mostlyclean clean distclean maintainer-clean \ + uninstall all diff --git a/gnu/usr.bin/gcc/f/runtime/README b/gnu/usr.bin/gcc/f/runtime/README index ae93d591e5a..32b68d36e81 100644 --- a/gnu/usr.bin/gcc/f/runtime/README +++ b/gnu/usr.bin/gcc/f/runtime/README @@ -1,4 +1,4 @@ -950827 +970205 This directory contains the f2c library packaged for use with g77 to configure and build automatically (in principle!) as part of the top-level configure and @@ -26,14 +26,6 @@ Some key changes made by Burley: (#define Pad_UDread), because that's the behavior most users expect. -- f2c.h configured to default to always flushing after output so that - ERR= and IOSTAT= report disk-full errors (assuming the underlying - system library code does that correctly), again because that's the - behavior most users expect (#define ALWAYS_FLUSH). But you should - write CALL FLUSH or CALL FLUSH(IUNIT) as appropriate in your source - code, because auto-flushing will not necessarily be enabled by - default in future versions of g77's run-time library. - - f2c.h configured to default to outputting leading zeros before decimal points in formatted and list-directed output, to be compatible with many other compilers (#define WANT_LEAD_0). Either way is diff --git a/gnu/usr.bin/gcc/f/runtime/TODO b/gnu/usr.bin/gcc/f/runtime/TODO index 526736062e2..513396572fe 100644 --- a/gnu/usr.bin/gcc/f/runtime/TODO +++ b/gnu/usr.bin/gcc/f/runtime/TODO @@ -1,8 +1,8 @@ -950212 +970205 TODO list for the g77 library -* `Makefile.in's should be tarted up to standard; I'm not sure they +* `Makefile.in's should be brought up to standard; I'm not sure they have a complete set of targets at present. * Investigate building shared libraries on systems we know about. @@ -11,9 +11,6 @@ TODO list for the g77 library * Allow the library to be stripped to save space. -* libU77-type routines (and interface to much of libc). Some work has - already been done on this: ask d.love@dl.ac.uk. - * An interface to IEEE maths functions from libc where this makes sense. diff --git a/gnu/usr.bin/gcc/f/runtime/configure b/gnu/usr.bin/gcc/f/runtime/configure index 0f412c86932..82388b5aa7c 100644 --- a/gnu/usr.bin/gcc/f/runtime/configure +++ b/gnu/usr.bin/gcc/f/runtime/configure @@ -1587,7 +1587,7 @@ F2C_INTEGER=long int #elif FFECOM_f2cINTEGER == FFECOM_f2ccodeINT F2C_INTEGER=int #else -# error Cannot find a suitable type for F2C_INTEGER +# error "Cannot find a suitable type for F2C_INTEGER" #endif EOF @@ -1610,7 +1610,7 @@ F2C_INTEGER=long int #elif FFECOM_f2cINTEGER == FFECOM_f2ccodeINT F2C_INTEGER=int #else -# error Cannot find a suitable type for F2C_INTEGER +# error "Cannot find a suitable type for F2C_INTEGER" #endif EOF @@ -1631,7 +1631,72 @@ fi echo "$ac_t""$ac_cv_sys_f2cinteger" 1>&6 F2C_INTEGER=$ac_cv_sys_f2cinteger -ac_cpp=late_ac_cpp +ac_cpp=$late_ac_cpp + + +echo $ac_n "checking f2c long int type""... $ac_c" 1>&6 +echo "configure:1639: checking f2c long int type" >&5 +late_ac_cpp=$ac_cpp +ac_cpp="$late_ac_cpp -I$srcdir/.. -I../.. -I$srcdir/../.. -I$srcdir/../../config" +if eval "test \"`echo '$''{'ac_cv_sys_f2clongint'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1646 "configure" +#include "confdefs.h" +#include "proj.h" +#define FFECOM_DETERMINE_TYPES 1 +#include "com.h" +#if FFECOM_f2cLONGINT == FFECOM_f2ccodeLONG +F2C_LONGINT=long int +#elif FFECOM_f2cLONGINT == FFECOM_f2ccodeLONGLONG +F2C_LONGINT=long long int +#else +# error "Cannot find a suitable type for F2C_LONGINT" +#endif + +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "F2C_LONGINT=long int" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_sys_f2clongint="long int" +fi +rm -f conftest* + +if test "$ac_cv_sys_f2clongint" = ""; then + cat > conftest.$ac_ext <<EOF +#line 1669 "configure" +#include "confdefs.h" +#include "proj.h" +#define FFECOM_DETERMINE_TYPES 1 +#include "com.h" +#if FFECOM_f2cLONGINT == FFECOM_f2ccodeLONG +F2C_LONGINT=long int +#elif FFECOM_f2cLONGINT == FFECOM_f2ccodeLONGLONG +F2C_LONGINT=long long int +#else +# error "Cannot find a suitable type for F2C_LONGINT" +#endif + +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "F2C_LONGINT=long long int" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_sys_f2clongint="long long int" +fi +rm -f conftest* + +fi +if test "$ac_cv_sys_f2clongint" = ""; then + echo "$ac_t""""" 1>&6 + { echo "configure: error: Can't determine type for f2c long int; config.log may help." 1>&2; exit 1; } +fi + +fi + +echo "$ac_t""$ac_cv_sys_f2clongint" 1>&6 +F2C_LONGINT=$ac_cv_sys_f2clongint +ac_cpp=$late_ac_cpp @@ -1658,10 +1723,6 @@ EOF -cat >> confdefs.h <<\EOF -#define ALWAYS_FLUSH 1 -EOF - cat >> confdefs.h <<\EOF @@ -1673,6 +1734,7 @@ EOF # got put here test -f libF77/makefile && mv libF77/makefile libF77/makefile.ori test -f libI77/makefile && mv libI77/makefile libI77/makefile.ori +test -f libU77/makefile && mv libU77/makefile libU77/makefile.ori trap '' 1 2 15 cat > confcache <<\EOF @@ -1786,7 +1848,7 @@ done ac_given_srcdir=$srcdir -trap 'rm -fr `echo "Makefile ../../include/f2c.h:f2c.h.in libI77/Makefile libF77/Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +trap 'rm -fr `echo "Makefile ../../include/f2c.h:f2c.h.in libI77/Makefile libF77/Makefile libU77/Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 EOF cat >> $CONFIG_STATUS <<EOF @@ -1822,6 +1884,7 @@ s%@RANLIB@%$RANLIB%g s%@RANLIB_TEST@%$RANLIB_TEST%g s%@CPP@%$CPP%g s%@F2C_INTEGER@%$F2C_INTEGER%g +s%@F2C_LONGINT@%$F2C_LONGINT%g s%@CROSS@%$CROSS%g CEOF @@ -1864,7 +1927,7 @@ EOF cat >> $CONFIG_STATUS <<EOF -CONFIG_FILES=\${CONFIG_FILES-"Makefile ../../include/f2c.h:f2c.h.in libI77/Makefile libF77/Makefile"} +CONFIG_FILES=\${CONFIG_FILES-"Makefile ../../include/f2c.h:f2c.h.in libI77/Makefile libF77/Makefile libU77/Makefile"} EOF cat >> $CONFIG_STATUS <<\EOF for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then diff --git a/gnu/usr.bin/gcc/f/runtime/configure.in b/gnu/usr.bin/gcc/f/runtime/configure.in index 755894abd6e..277dd061114 100644 --- a/gnu/usr.bin/gcc/f/runtime/configure.in +++ b/gnu/usr.bin/gcc/f/runtime/configure.in @@ -1,5 +1,5 @@ # Process this file with autoconf to produce a configure script. -# Copyright (C) 1995 Free Software Foundation, Inc. +# Copyright (C) 1995, 1997 Free Software Foundation, Inc. # Contributed by Dave Love (d.love@dl.ac.uk). # #This file is part of GNU Fortran. @@ -204,7 +204,7 @@ F2C_INTEGER=long int #elif FFECOM_f2cINTEGER == FFECOM_f2ccodeINT F2C_INTEGER=int #else -# error Cannot find a suitable type for F2C_INTEGER +# error "Cannot find a suitable type for F2C_INTEGER" #endif ], ac_cv_sys_f2cinteger="long int",) @@ -218,7 +218,7 @@ F2C_INTEGER=long int #elif FFECOM_f2cINTEGER == FFECOM_f2ccodeINT F2C_INTEGER=int #else -# error Cannot find a suitable type for F2C_INTEGER +# error "Cannot find a suitable type for F2C_INTEGER" #endif ], ac_cv_sys_f2cinteger=int,) @@ -230,9 +230,51 @@ fi ) AC_MSG_RESULT($ac_cv_sys_f2cinteger) F2C_INTEGER=$ac_cv_sys_f2cinteger -ac_cpp=late_ac_cpp +ac_cpp=$late_ac_cpp AC_SUBST(F2C_INTEGER) +AC_MSG_CHECKING(f2c long int type) +late_ac_cpp=$ac_cpp +ac_cpp="$late_ac_cpp -I$srcdir/.. -I../.. -I$srcdir/../.. -I$srcdir/../../config" +AC_CACHE_VAL(ac_cv_sys_f2clongint, +AC_EGREP_CPP(F2C_LONGINT=long int, +[#include "proj.h" +#define FFECOM_DETERMINE_TYPES 1 +#include "com.h" +#if FFECOM_f2cLONGINT == FFECOM_f2ccodeLONG +F2C_LONGINT=long int +#elif FFECOM_f2cLONGINT == FFECOM_f2ccodeLONGLONG +F2C_LONGINT=long long int +#else +# error "Cannot find a suitable type for F2C_LONGINT" +#endif +], + ac_cv_sys_f2clongint="long int",) +if test "$ac_cv_sys_f2clongint" = ""; then + AC_EGREP_CPP(F2C_LONGINT=long long int, +[#include "proj.h" +#define FFECOM_DETERMINE_TYPES 1 +#include "com.h" +#if FFECOM_f2cLONGINT == FFECOM_f2ccodeLONG +F2C_LONGINT=long int +#elif FFECOM_f2cLONGINT == FFECOM_f2ccodeLONGLONG +F2C_LONGINT=long long int +#else +# error "Cannot find a suitable type for F2C_LONGINT" +#endif +], + ac_cv_sys_f2clongint="long long int",) +fi +if test "$ac_cv_sys_f2clongint" = ""; then + AC_MSG_RESULT("") + AC_MSG_ERROR([Can't determine type for f2c long int; config.log may help.]) +fi +) +AC_MSG_RESULT($ac_cv_sys_f2clongint) +F2C_LONGINT=$ac_cv_sys_f2clongint +ac_cpp=$late_ac_cpp +AC_SUBST(F2C_LONGINT) + dnl maybe check for drem/remainder AC_SUBST(CROSS) @@ -264,7 +306,7 @@ dnl on a case-by-case basis when it can be shown to not be necessary dnl (e.g. no ERR= or IOSTAT=) or when it is given the appropriate dnl compile-time option or, perhaps, source-code directive. -AC_DEFINE(ALWAYS_FLUSH) +dnl AC_DEFINE(ALWAYS_FLUSH) dnl Most Fortran implementations do this, so to make it easier dnl to compare the output of g77-compiled programs to those compiled @@ -277,8 +319,9 @@ AC_DEFINE(WANT_LEAD_0) # got put here test -f libF77/makefile && mv libF77/makefile libF77/makefile.ori test -f libI77/makefile && mv libI77/makefile libI77/makefile.ori +test -f libU77/makefile && mv libU77/makefile libU77/makefile.ori -AC_OUTPUT(Makefile ../../include/f2c.h:f2c.h.in libI77/Makefile libF77/Makefile) +AC_OUTPUT(Makefile ../../include/f2c.h:f2c.h.in libI77/Makefile libF77/Makefile libU77/Makefile) dnl We might have configuration options to: dnl * allow non-standard string concatenation (use libF77 s_catow.o, diff --git a/gnu/usr.bin/gcc/f/runtime/f2c.h.in b/gnu/usr.bin/gcc/f/runtime/f2c.h.in index 9d1d5905bf7..90374678100 100644 --- a/gnu/usr.bin/gcc/f/runtime/f2c.h.in +++ b/gnu/usr.bin/gcc/f/runtime/f2c.h.in @@ -21,14 +21,10 @@ typedef @F2C_INTEGER@ /* long int */ logical; typedef short int shortlogical; typedef char logical1; typedef char integer1; -/* integer*8 support from f2c not currently supported: */ -#if 0 -typedef @F2C_LONGINT@ /* long long */ longint; /* system-dependent */ -typedef unsigned @F2C_LONGINT@ ulongint; /* system-dependent */ +typedef @F2C_LONGINT@ /* long long */ longint; /* system-dependent */ +typedef unsigned @F2C_LONGINT@ /* long long */ ulongint; /* system-dependent */ #define qbit_clear(a,b) ((a) & ~((ulongint)1 << (b))) #define qbit_set(a,b) ((a) | ((ulongint)1 << (b))) -#endif -typedef long long int longint; #define TRUE_ (1) #define FALSE_ (0) @@ -41,15 +37,15 @@ typedef long long int longint; /* I/O stuff */ #ifdef f2c_i2 - #error f2c_i2 will not work with g77!!!! +#error "f2c_i2 will not work with g77!!!!" /* for -i2 */ typedef short flag; typedef short ftnlen; typedef short ftnint; #else -typedef @F2C_INTEGER@ /* int or long int */ flag; -typedef @F2C_INTEGER@ /* int or long int */ ftnlen; -typedef @F2C_INTEGER@ /* int or long int */ ftnint; +typedef @F2C_INTEGER@ /* long int */ flag; +typedef @F2C_INTEGER@ /* long int */ ftnlen; +typedef @F2C_INTEGER@ /* long int */ ftnint; #endif /*external read, write*/ diff --git a/gnu/usr.bin/gcc/f/runtime/libF77/Makefile.in b/gnu/usr.bin/gcc/f/runtime/libF77/Makefile.in index 164c7bcef38..a5ca2a65859 100644 --- a/gnu/usr.bin/gcc/f/runtime/libF77/Makefile.in +++ b/gnu/usr.bin/gcc/f/runtime/libF77/Makefile.in @@ -38,7 +38,7 @@ DEFS = @DEFS@ CGFLAGS = -g0 # f2c.h should already be installed in xgcc's include directory but add that # to -I anyhow in case not using xgcc. -ALL_CFLAGS = -I$(srcdir) -I../../../include $(CPPFLAGS) $(DEFS) $(CFLAGS) +ALL_CFLAGS = -I. -I$(srcdir) -I../../../include $(CPPFLAGS) $(DEFS) $(CFLAGS) AR = @AR@ AR_FLAGS = rc RANLIB = @RANLIB@ @@ -50,15 +50,12 @@ CROSS = @CROSS@ .c.o: $(CC) -c -DSkip_f2c_Undefs $(ALL_CFLAGS) $(CGFLAGS) $< -# Next two lines were removed because Solaris doesn't like `ld -x', and -# it seems there's no real benefit to doing this anyway. -# ld -r -x -o $@x $@ -# mv $@x $@ MISC = F77_aloc.o VersionF.o main.o s_rnge.o abort_.o getarg_.o iargc_.o\ getenv_.o signal_.o s_stop.o s_paus.o system_.o cabs.o\ derf_.o derfc_.o erf_.o erfc_.o sig_die.o exit.o -POW = pow_ci.o pow_dd.o pow_di.o pow_hh.o pow_ii.o pow_ri.o pow_zi.o pow_zz.o +POW = pow_ci.o pow_dd.o pow_di.o pow_hh.o pow_ii.o pow_ri.o pow_zi.o pow_zz.o \ + pow_qq.o CX = c_abs.o c_cos.o c_div.o c_exp.o c_log.o c_sin.o c_sqrt.o DCX = z_abs.o z_cos.o z_div.o z_exp.o z_log.o z_sin.o z_sqrt.o REAL = r_abs.o r_acos.o r_asin.o r_atan.o r_atn2.o r_cnjg.o r_cos.o\ @@ -75,40 +72,24 @@ HALF = h_abs.o h_dim.o h_dnnt.o h_indx.o h_len.o h_mod.o h_nint.o h_sign.o CMP = l_ge.o l_gt.o l_le.o l_lt.o hl_ge.o hl_gt.o hl_le.o hl_lt.o EFL = ef1asc_.o ef1cmc_.o CHAR = s_cat.o s_cmp.o s_copy.o -F90BIT = lbitbits.o lbitshft.o +F90BIT = lbitbits.o lbitshft.o qbitbits.o qbitshft.o -lib = ../../../libf2c.a +F2C_H = ../../../include/f2c.h -F2C_H = ../../include/f2c.h - -all: $(lib) - -$(lib): force $(MISC) $(POW) $(CX) $(DCX) $(REAL) $(DBL) $(INT) \ - $(HALF) $(CMP) $(EFL) $(CHAR) -# Don't worry if ar fails, that can happen when a root-like user installs a -# system built by a user to which the installer has insufficient access -# to modify libf2c.a. Probably a better solution to this should be -# found, but this should do for now. -- burley 951226 - -$(AR) $(AR_FLAGS) $(lib) $(MISC) $(POW) $(CX) $(DCX) $(REAL) \ - $(DBL) $(INT) $(HALF) $(CMP) $(EFL) $(CHAR) - if $(RANLIB_TEST); then $(RANLIB) $(lib); \ - else true; fi - -uninstall: -install: +all: $(MISC) $(POW) $(CX) $(DCX) $(REAL) $(DBL) $(INT) \ + $(HALF) $(CMP) $(EFL) $(CHAR) $(F90BIT) VersionF.o: Version.c $(CC) -c $(CGFLAGS) -o $@ $(srcdir)/Version.c -# Next two lines were removed because Solaris doesn't like `ld -x', and -# it seems there's no real benefit to doing this anyway. -# ld -r -x -o $@x $@ -# mv $@x $@ -clean: - rm -f *.o +mostlyclean clean: + -rm -f *.o + +distclean maintainer-clean: clean + -rm -f stage? include Makefile # Not quite all these actually do depend on f2c.h... $(MISC) $(POW) $(CX) $(DCX) $(REAL) $(DBL) $(INT) \ - $(HALF) $(CMP) $(EFL) $(CHAR): $(F2C_H) $(F90BIT) + $(HALF) $(CMP) $(EFL) $(CHAR) $(F90BIT): $(F2C_H) -force: +.PHONY: mostlyclean clean distclean maintainer-clean all diff --git a/gnu/usr.bin/gcc/f/runtime/libF77/Version.c b/gnu/usr.bin/gcc/f/runtime/libF77/Version.c index d38e01d1907..3ff823b199e 100644 --- a/gnu/usr.bin/gcc/f/runtime/libF77/Version.c +++ b/gnu/usr.bin/gcc/f/runtime/libF77/Version.c @@ -3,7 +3,7 @@ static char junk[] = "\n@(#)LIBF77 VERSION 19960619\n"; /* */ -char __G77_LIBF77_VERSION__[] = "0.5.19"; +char __G77_LIBF77_VERSION__[] = "0.5.20"; /* 2.00 11 June 1980. File version.c added to library. @@ -52,7 +52,8 @@ char __G77_LIBF77_VERSION__[] = "0.5.19"; #include <stdio.h> void -g77_libf77_version () +g77__fvers__ () { - fprintf (stderr, "__G77_LIBF77_VERSION__: %s\n", __G77_LIBF77_VERSION__); + fprintf (stderr, "__G77_LIBF77_VERSION__: %s", __G77_LIBF77_VERSION__); + fputs (junk, stderr); } diff --git a/gnu/usr.bin/gcc/f/runtime/libF77/c_cos.c b/gnu/usr.bin/gcc/f/runtime/libF77/c_cos.c index 09c8719848f..9e833c168b3 100644 --- a/gnu/usr.bin/gcc/f/runtime/libF77/c_cos.c +++ b/gnu/usr.bin/gcc/f/runtime/libF77/c_cos.c @@ -3,14 +3,19 @@ #ifdef KR_headers extern double sin(), cos(), sinh(), cosh(); -VOID c_cos(r, z) complex *r, *z; +VOID c_cos(resx, z) complex *resx, *z; #else #undef abs #include <math.h> -void c_cos(complex *r, complex *z) +void c_cos(complex *resx, complex *z) #endif { -r->r = cos(z->r) * cosh(z->i); -r->i = - sin(z->r) * sinh(z->i); +complex res; + +res.r = cos(z->r) * cosh(z->i); +res.i = - sin(z->r) * sinh(z->i); + +resx->r = res.r; +resx->i = res.i; } diff --git a/gnu/usr.bin/gcc/f/runtime/libF77/c_div.c b/gnu/usr.bin/gcc/f/runtime/libF77/c_div.c index 0bb56b485e1..9568354bd53 100644 --- a/gnu/usr.bin/gcc/f/runtime/libF77/c_div.c +++ b/gnu/usr.bin/gcc/f/runtime/libF77/c_div.c @@ -2,15 +2,16 @@ #ifdef KR_headers extern VOID sig_die(); -VOID c_div(c, a, b) -complex *a, *b, *c; +VOID c_div(resx, a, b) +complex *a, *b, *resx; #else extern void sig_die(char*,int); -void c_div(complex *c, complex *a, complex *b) +void c_div(complex *resx, complex *a, complex *b) #endif { double ratio, den; double abr, abi; +complex res; if( (abr = b->r) < 0.) abr = - abr; @@ -22,15 +23,18 @@ if( abr <= abi ) sig_die("complex division by zero", 1); ratio = (double)b->r / b->i ; den = b->i * (1 + ratio*ratio); - c->r = (a->r*ratio + a->i) / den; - c->i = (a->i*ratio - a->r) / den; + res.r = (a->r*ratio + a->i) / den; + res.i = (a->i*ratio - a->r) / den; } else { ratio = (double)b->i / b->r ; den = b->r * (1 + ratio*ratio); - c->r = (a->r + a->i*ratio) / den; - c->i = (a->i - a->r*ratio) / den; + res.r = (a->r + a->i*ratio) / den; + res.i = (a->i - a->r*ratio) / den; } + +resx->r = res.r; +resx->i = res.i; } diff --git a/gnu/usr.bin/gcc/f/runtime/libF77/c_exp.c b/gnu/usr.bin/gcc/f/runtime/libF77/c_exp.c index 68aebd3dbfb..8d3d33d0fe3 100644 --- a/gnu/usr.bin/gcc/f/runtime/libF77/c_exp.c +++ b/gnu/usr.bin/gcc/f/runtime/libF77/c_exp.c @@ -3,17 +3,21 @@ #ifdef KR_headers extern double exp(), cos(), sin(); - VOID c_exp(r, z) complex *r, *z; + VOID c_exp(resx, z) complex *resx, *z; #else #undef abs #include <math.h> -void c_exp(complex *r, complex *z) +void c_exp(complex *resx, complex *z) #endif { double expx; +complex res; expx = exp(z->r); -r->r = expx * cos(z->i); -r->i = expx * sin(z->i); +res.r = expx * cos(z->i); +res.i = expx * sin(z->i); + +resx->r = res.r; +resx->i = res.i; } diff --git a/gnu/usr.bin/gcc/f/runtime/libF77/c_log.c b/gnu/usr.bin/gcc/f/runtime/libF77/c_log.c index 39dcfa50967..6715131ad1d 100644 --- a/gnu/usr.bin/gcc/f/runtime/libF77/c_log.c +++ b/gnu/usr.bin/gcc/f/runtime/libF77/c_log.c @@ -2,15 +2,20 @@ #ifdef KR_headers extern double log(), f__cabs(), atan2(); -VOID c_log(r, z) complex *r, *z; +VOID c_log(resx, z) complex *resx, *z; #else #undef abs #include <math.h> extern double f__cabs(double, double); -void c_log(complex *r, complex *z) +void c_log(complex *resx, complex *z) #endif { -r->i = atan2(z->i, z->r); -r->r = log( f__cabs(z->r, z->i) ); +complex res; + +res.i = atan2(z->i, z->r); +res.r = log( f__cabs(z->r, z->i) ); + +resx->r = res.r; +resx->i = res.i; } diff --git a/gnu/usr.bin/gcc/f/runtime/libF77/c_sin.c b/gnu/usr.bin/gcc/f/runtime/libF77/c_sin.c index 620360ce53e..7bf3e392bed 100644 --- a/gnu/usr.bin/gcc/f/runtime/libF77/c_sin.c +++ b/gnu/usr.bin/gcc/f/runtime/libF77/c_sin.c @@ -3,14 +3,19 @@ #ifdef KR_headers extern double sin(), cos(), sinh(), cosh(); -VOID c_sin(r, z) complex *r, *z; +VOID c_sin(resx, z) complex *resx, *z; #else #undef abs #include <math.h> -void c_sin(complex *r, complex *z) +void c_sin(complex *resx, complex *z) #endif { -r->r = sin(z->r) * cosh(z->i); -r->i = cos(z->r) * sinh(z->i); +complex res; + +res.r = sin(z->r) * cosh(z->i); +res.i = cos(z->r) * sinh(z->i); + +resx->r = res.r; +resx->i = res.i; } diff --git a/gnu/usr.bin/gcc/f/runtime/libF77/c_sqrt.c b/gnu/usr.bin/gcc/f/runtime/libF77/c_sqrt.c index 4095ce17b5b..775977a87f7 100644 --- a/gnu/usr.bin/gcc/f/runtime/libF77/c_sqrt.c +++ b/gnu/usr.bin/gcc/f/runtime/libF77/c_sqrt.c @@ -3,32 +3,36 @@ #ifdef KR_headers extern double sqrt(), f__cabs(); -VOID c_sqrt(r, z) complex *r, *z; +VOID c_sqrt(resx, z) complex *resx, *z; #else #undef abs #include <math.h> extern double f__cabs(double, double); -void c_sqrt(complex *r, complex *z) +void c_sqrt(complex *resx, complex *z) #endif { double mag, t; +complex res; if( (mag = f__cabs(z->r, z->i)) == 0.) - r->r = r->i = 0.; + res.r = res.i = 0.; else if(z->r > 0) { - r->r = t = sqrt(0.5 * (mag + z->r) ); + res.r = t = sqrt(0.5 * (mag + z->r) ); t = z->i / t; - r->i = 0.5 * t; + res.i = 0.5 * t; } else { t = sqrt(0.5 * (mag - z->r) ); if(z->i < 0) t = -t; - r->i = t; + res.i = t; t = z->i / t; - r->r = 0.5 * t; + res.r = 0.5 * t; } + +resx->r = res.r; +resx->i = res.i; } diff --git a/gnu/usr.bin/gcc/f/runtime/libF77/d_cnjg.c b/gnu/usr.bin/gcc/f/runtime/libF77/d_cnjg.c index c778c38758c..1afa3bc4061 100644 --- a/gnu/usr.bin/gcc/f/runtime/libF77/d_cnjg.c +++ b/gnu/usr.bin/gcc/f/runtime/libF77/d_cnjg.c @@ -2,11 +2,16 @@ VOID #ifdef KR_headers -d_cnjg(r, z) doublecomplex *r, *z; +d_cnjg(resx, z) doublecomplex *resx, *z; #else -d_cnjg(doublecomplex *r, doublecomplex *z) +d_cnjg(doublecomplex *resx, doublecomplex *z) #endif { -r->r = z->r; -r->i = - z->i; +doublecomplex res; + +res.r = z->r; +res.i = - z->i; + +resx->r = res.r; +resx->i = res.i; } diff --git a/gnu/usr.bin/gcc/f/runtime/libF77/makefile b/gnu/usr.bin/gcc/f/runtime/libF77/makefile new file mode 100644 index 00000000000..30de0ee759a --- /dev/null +++ b/gnu/usr.bin/gcc/f/runtime/libF77/makefile @@ -0,0 +1,84 @@ +.SUFFIXES: .c .o +CC = cc +SHELL = /bin/sh +CFLAGS = -O + +# If your system lacks onexit() and you are not using an +# ANSI C compiler, then you should add -DNO_ONEXIT to CFLAGS, +# e.g., by changing the above "CFLAGS =" line to +# CFLAGS = -O -DNO_ONEXIT + +# On at least some Sun systems, it is more appropriate to change the +# "CFLAGS =" line to +# CFLAGS = -O -Donexit=on_exit + +# compile, then strip unnecessary symbols +.c.o: + $(CC) -c -DSkip_f2c_Undefs $(CFLAGS) $*.c + ld -r -x -o $*.xxx $*.o + mv $*.xxx $*.o +## Under Solaris, omit -x in the ld line above. + +MISC = F77_aloc.o Version.o main.o s_rnge.o abort_.o getarg_.o iargc_.o \ + getenv_.o signal_.o s_stop.o s_paus.o system_.o cabs.o\ + derf_.o derfc_.o erf_.o erfc_.o sig_die.o exit.o +POW = pow_ci.o pow_dd.o pow_di.o pow_hh.o pow_ii.o pow_ri.o pow_zi.o pow_zz.o +CX = c_abs.o c_cos.o c_div.o c_exp.o c_log.o c_sin.o c_sqrt.o +DCX = z_abs.o z_cos.o z_div.o z_exp.o z_log.o z_sin.o z_sqrt.o +REAL = r_abs.o r_acos.o r_asin.o r_atan.o r_atn2.o r_cnjg.o r_cos.o\ + r_cosh.o r_dim.o r_exp.o r_imag.o r_int.o\ + r_lg10.o r_log.o r_mod.o r_nint.o r_sign.o\ + r_sin.o r_sinh.o r_sqrt.o r_tan.o r_tanh.o +DBL = d_abs.o d_acos.o d_asin.o d_atan.o d_atn2.o\ + d_cnjg.o d_cos.o d_cosh.o d_dim.o d_exp.o\ + d_imag.o d_int.o d_lg10.o d_log.o d_mod.o\ + d_nint.o d_prod.o d_sign.o d_sin.o d_sinh.o\ + d_sqrt.o d_tan.o d_tanh.o +INT = i_abs.o i_dim.o i_dnnt.o i_indx.o i_len.o i_mod.o i_nint.o i_sign.o +HALF = h_abs.o h_dim.o h_dnnt.o h_indx.o h_len.o h_mod.o h_nint.o h_sign.o +CMP = l_ge.o l_gt.o l_le.o l_lt.o hl_ge.o hl_gt.o hl_le.o hl_lt.o +EFL = ef1asc_.o ef1cmc_.o +CHAR = s_cat.o s_cmp.o s_copy.o +F90BIT = lbitbits.o lbitshft.o + +libF77.a : $(MISC) $(POW) $(CX) $(DCX) $(REAL) $(DBL) $(INT) \ + $(HALF) $(CMP) $(EFL) $(CHAR) $(F90BIT) + ar r libF77.a $? + -ranlib libF77.a + +### If your system lacks ranlib, you don't need it; see README. + +Version.o: Version.c + $(CC) -c Version.c + +# To compile with C++, first "make f2c.h" +f2c.h: f2ch.add + cat /usr/include/f2c.h f2ch.add >f2c.h + +install: libF77.a + mv libF77.a /usr/lib + ranlib /usr/lib/libF77.a + +clean: + rm -f libF77.a *.o + +check: + xsum F77_aloc.c Notice README Version.c abort_.c c_abs.c c_cos.c \ + c_div.c c_exp.c c_log.c c_sin.c c_sqrt.c cabs.c d_abs.c d_acos.c \ + d_asin.c d_atan.c d_atn2.c d_cnjg.c d_cos.c d_cosh.c d_dim.c \ + d_exp.c d_imag.c d_int.c d_lg10.c d_log.c d_mod.c d_nint.c \ + d_prod.c d_sign.c d_sin.c d_sinh.c d_sqrt.c d_tan.c d_tanh.c \ + derf_.c derfc_.c ef1asc_.c ef1cmc_.c erf_.c erfc_.c exit.c f2ch.add \ + getarg_.c getenv_.c h_abs.c h_dim.c h_dnnt.c h_indx.c h_len.c \ + h_mod.c h_nint.c h_sign.c hl_ge.c hl_gt.c hl_le.c hl_lt.c \ + i_abs.c i_dim.c i_dnnt.c i_indx.c i_len.c i_mod.c i_nint.c \ + i_sign.c iargc_.c l_ge.c l_gt.c l_le.c l_lt.c lbitbits.c lbitshft.c \ + main.c makefile pow_ci.c pow_dd.c pow_di.c pow_hh.c pow_ii.c \ + pow_qq.c pow_ri.c pow_zi.c pow_zz.c qbitbits.c qbitshft.c \ + r_abs.c r_acos.c r_asin.c r_atan.c r_atn2.c \ + r_cnjg.c r_cos.c r_cosh.c r_dim.c r_exp.c r_imag.c r_int.c r_lg10.c \ + r_log.c r_mod.c r_nint.c r_sign.c r_sin.c r_sinh.c r_sqrt.c \ + r_tan.c r_tanh.c s_cat.c s_cmp.c s_copy.c \ + s_paus.c s_rnge.c s_stop.c sig_die.c signal_.c system_.c \ + z_abs.c z_cos.c z_div.c z_exp.c z_log.c z_sin.c z_sqrt.c >zap + cmp zap libF77.xsum && rm zap || diff libF77.xsum zap diff --git a/gnu/usr.bin/gcc/f/runtime/libF77/pow_zi.c b/gnu/usr.bin/gcc/f/runtime/libF77/pow_zi.c index 167e6acbc6a..898ea6be917 100644 --- a/gnu/usr.bin/gcc/f/runtime/libF77/pow_zi.c +++ b/gnu/usr.bin/gcc/f/runtime/libF77/pow_zi.c @@ -1,25 +1,32 @@ #include "f2c.h" #ifdef KR_headers -VOID pow_zi(p, a, b) /* p = a**b */ - doublecomplex *p, *a; integer *b; +VOID pow_zi(resx, a, b) /* p = a**b */ + doublecomplex *resx, *a; integer *b; #else extern void z_div(doublecomplex*, doublecomplex*, doublecomplex*); -void pow_zi(doublecomplex *p, doublecomplex *a, integer *b) /* p = a**b */ +void pow_zi(doublecomplex *resx, doublecomplex *a, integer *b) /* p = a**b */ #endif { integer n; unsigned long u; double t; doublecomplex x; +doublecomplex res; static doublecomplex one = {1.0, 0.0}; n = *b; -p->r = 1; -p->i = 0; if(n == 0) + { + resx->r = 1; + resx->i = 0; return; + } + +res.r = 1; +res.i = 0; + if(n < 0) { n = -n; @@ -35,9 +42,9 @@ for(u = n; ; ) { if(u & 01) { - t = p->r * x.r - p->i * x.i; - p->i = p->r * x.i + p->i * x.r; - p->r = t; + t = res.r * x.r - res.i * x.i; + res.i = res.r * x.i + res.i * x.r; + res.r = t; } if(u >>= 1) { @@ -48,4 +55,7 @@ for(u = n; ; ) else break; } + +resx->r = res.r; +resx->i = res.i; } diff --git a/gnu/usr.bin/gcc/f/runtime/libF77/r_cnjg.c b/gnu/usr.bin/gcc/f/runtime/libF77/r_cnjg.c index e127ca969c4..b6175eedfd7 100644 --- a/gnu/usr.bin/gcc/f/runtime/libF77/r_cnjg.c +++ b/gnu/usr.bin/gcc/f/runtime/libF77/r_cnjg.c @@ -1,11 +1,16 @@ #include "f2c.h" #ifdef KR_headers -VOID r_cnjg(r, z) complex *r, *z; +VOID r_cnjg(resx, z) complex *resx, *z; #else -VOID r_cnjg(complex *r, complex *z) +VOID r_cnjg(complex *resx, complex *z) #endif { -r->r = z->r; -r->i = - z->i; +complex res; + +res.r = z->r; +res.i = - z->i; + +resx->r = res.r; +resx->i = res.i; } diff --git a/gnu/usr.bin/gcc/f/runtime/libF77/s_cat.c b/gnu/usr.bin/gcc/f/runtime/libF77/s_cat.c index 7bfb11eb881..90a89be4b0c 100644 --- a/gnu/usr.bin/gcc/f/runtime/libF77/s_cat.c +++ b/gnu/usr.bin/gcc/f/runtime/libF77/s_cat.c @@ -12,6 +12,8 @@ extern void free(); extern void exit_(); #else +#undef min +#undef max #include <stdlib.h> extern char *F77_aloc(ftnlen, char*); #endif diff --git a/gnu/usr.bin/gcc/f/runtime/libF77/s_paus.c b/gnu/usr.bin/gcc/f/runtime/libF77/s_paus.c index 6a2e86e1262..e78fa27a5a0 100644 --- a/gnu/usr.bin/gcc/f/runtime/libF77/s_paus.c +++ b/gnu/usr.bin/gcc/f/runtime/libF77/s_paus.c @@ -60,7 +60,7 @@ s_paus(char *s, ftnlen n) if( isatty(fileno(stdin)) ) s_1paus(stdin); else { -#if defined (MSDOS) && !defined (GO32) +#if (defined (MSDOS) && !defined (GO32)) || defined(__CYGWIN32__) FILE *fin; fin = fopen("con", "r"); if (!fin) { diff --git a/gnu/usr.bin/gcc/f/runtime/libF77/signal_.c b/gnu/usr.bin/gcc/f/runtime/libF77/signal_.c index d848bf564d6..ce58d71b257 100644 --- a/gnu/usr.bin/gcc/f/runtime/libF77/signal_.c +++ b/gnu/usr.bin/gcc/f/runtime/libF77/signal_.c @@ -25,5 +25,4 @@ ftnint signal_(integer *sigp, sig_proc proc) sig = (int)*sigp; return (ftnint)signal(sig, (sig_type)proc); - return 0; } diff --git a/gnu/usr.bin/gcc/f/runtime/libF77/z_cos.c b/gnu/usr.bin/gcc/f/runtime/libF77/z_cos.c index ef02be4c38c..a811bbecc65 100644 --- a/gnu/usr.bin/gcc/f/runtime/libF77/z_cos.c +++ b/gnu/usr.bin/gcc/f/runtime/libF77/z_cos.c @@ -2,13 +2,18 @@ #ifdef KR_headers double sin(), cos(), sinh(), cosh(); -VOID z_cos(r, z) doublecomplex *r, *z; +VOID z_cos(resx, z) doublecomplex *resx, *z; #else #undef abs #include <math.h> -void z_cos(doublecomplex *r, doublecomplex *z) +void z_cos(doublecomplex *resx, doublecomplex *z) #endif { -r->r = cos(z->r) * cosh(z->i); -r->i = - sin(z->r) * sinh(z->i); +doublecomplex res; + +res.r = cos(z->r) * cosh(z->i); +res.i = - sin(z->r) * sinh(z->i); + +resx->r = res.r; +resx->i = res.i; } diff --git a/gnu/usr.bin/gcc/f/runtime/libF77/z_div.c b/gnu/usr.bin/gcc/f/runtime/libF77/z_div.c index fd53733e882..88487210ef5 100644 --- a/gnu/usr.bin/gcc/f/runtime/libF77/z_div.c +++ b/gnu/usr.bin/gcc/f/runtime/libF77/z_div.c @@ -2,14 +2,15 @@ #ifdef KR_headers extern void sig_die(); -VOID z_div(c, a, b) doublecomplex *a, *b, *c; +VOID z_div(resx, a, b) doublecomplex *a, *b, *resx; #else extern void sig_die(char*, int); -void z_div(doublecomplex *c, doublecomplex *a, doublecomplex *b) +void z_div(doublecomplex *resx, doublecomplex *a, doublecomplex *b) #endif { double ratio, den; double abr, abi; +doublecomplex res; if( (abr = b->r) < 0.) abr = - abr; @@ -21,16 +22,18 @@ if( abr <= abi ) sig_die("complex division by zero", 1); ratio = b->r / b->i ; den = b->i * (1 + ratio*ratio); - c->r = (a->r*ratio + a->i) / den; - c->i = (a->i*ratio - a->r) / den; + res.r = (a->r*ratio + a->i) / den; + res.i = (a->i*ratio - a->r) / den; } else { ratio = b->i / b->r ; den = b->r * (1 + ratio*ratio); - c->r = (a->r + a->i*ratio) / den; - c->i = (a->i - a->r*ratio) / den; + res.r = (a->r + a->i*ratio) / den; + res.i = (a->i - a->r*ratio) / den; } +resx->r = res.r; +resx->i = res.i; } diff --git a/gnu/usr.bin/gcc/f/runtime/libF77/z_exp.c b/gnu/usr.bin/gcc/f/runtime/libF77/z_exp.c index 4e94a14b4cc..85fb63e4209 100644 --- a/gnu/usr.bin/gcc/f/runtime/libF77/z_exp.c +++ b/gnu/usr.bin/gcc/f/runtime/libF77/z_exp.c @@ -2,16 +2,20 @@ #ifdef KR_headers double exp(), cos(), sin(); -VOID z_exp(r, z) doublecomplex *r, *z; +VOID z_exp(resx, z) doublecomplex *resx, *z; #else #undef abs #include <math.h> -void z_exp(doublecomplex *r, doublecomplex *z) +void z_exp(doublecomplex *resx, doublecomplex *z) #endif { double expx; +doublecomplex res; expx = exp(z->r); -r->r = expx * cos(z->i); -r->i = expx * sin(z->i); +res.r = expx * cos(z->i); +res.i = expx * sin(z->i); + +resx->r = res.r; +resx->i = res.i; } diff --git a/gnu/usr.bin/gcc/f/runtime/libF77/z_log.c b/gnu/usr.bin/gcc/f/runtime/libF77/z_log.c index 097c0a1b120..48afca63d6d 100644 --- a/gnu/usr.bin/gcc/f/runtime/libF77/z_log.c +++ b/gnu/usr.bin/gcc/f/runtime/libF77/z_log.c @@ -2,15 +2,19 @@ #ifdef KR_headers double log(), f__cabs(), atan2(); -VOID z_log(r, z) doublecomplex *r, *z; +VOID z_log(resx, z) doublecomplex *resx, *z; #else #undef abs #include <math.h> extern double f__cabs(double, double); -void z_log(doublecomplex *r, doublecomplex *z) +void z_log(doublecomplex *resx, doublecomplex *z) #endif { +doublecomplex res; -r->i = atan2(z->i, z->r); -r->r = log( f__cabs( z->r, z->i ) ); +res.i = atan2(z->i, z->r); +res.r = log( f__cabs( z->r, z->i ) ); + +resx->r = res.r; +resx->i = res.i; } diff --git a/gnu/usr.bin/gcc/f/runtime/libF77/z_sin.c b/gnu/usr.bin/gcc/f/runtime/libF77/z_sin.c index dece95e5c60..94456c9c30a 100644 --- a/gnu/usr.bin/gcc/f/runtime/libF77/z_sin.c +++ b/gnu/usr.bin/gcc/f/runtime/libF77/z_sin.c @@ -2,13 +2,18 @@ #ifdef KR_headers double sin(), cos(), sinh(), cosh(); -VOID z_sin(r, z) doublecomplex *r, *z; +VOID z_sin(resx, z) doublecomplex *resx, *z; #else #undef abs #include <math.h> -void z_sin(doublecomplex *r, doublecomplex *z) +void z_sin(doublecomplex *resx, doublecomplex *z) #endif { -r->r = sin(z->r) * cosh(z->i); -r->i = cos(z->r) * sinh(z->i); +doublecomplex res; + +res.r = sin(z->r) * cosh(z->i); +res.i = cos(z->r) * sinh(z->i); + +resx->r = res.r; +resx->i = res.i; } diff --git a/gnu/usr.bin/gcc/f/runtime/libF77/z_sqrt.c b/gnu/usr.bin/gcc/f/runtime/libF77/z_sqrt.c index a469703129b..f5db5651991 100644 --- a/gnu/usr.bin/gcc/f/runtime/libF77/z_sqrt.c +++ b/gnu/usr.bin/gcc/f/runtime/libF77/z_sqrt.c @@ -2,28 +2,32 @@ #ifdef KR_headers double sqrt(), f__cabs(); -VOID z_sqrt(r, z) doublecomplex *r, *z; +VOID z_sqrt(resx, z) doublecomplex *resx, *z; #else #undef abs #include <math.h> extern double f__cabs(double, double); -void z_sqrt(doublecomplex *r, doublecomplex *z) +void z_sqrt(doublecomplex *resx, doublecomplex *z) #endif { double mag; +doublecomplex res; if( (mag = f__cabs(z->r, z->i)) == 0.) - r->r = r->i = 0.; + res.r = res.i = 0.; else if(z->r > 0) { - r->r = sqrt(0.5 * (mag + z->r) ); - r->i = z->i / r->r / 2; + res.r = sqrt(0.5 * (mag + z->r) ); + res.i = z->i / res.r / 2; } else { - r->i = sqrt(0.5 * (mag - z->r) ); + res.i = sqrt(0.5 * (mag - z->r) ); if(z->i < 0) - r->i = - r->i; - r->r = z->i / r->i / 2; + res.i = - res.i; + res.r = z->i / res.i / 2; } + +resx->r = res.r; +resx->i = res.i; } diff --git a/gnu/usr.bin/gcc/f/runtime/libI77/Makefile.in b/gnu/usr.bin/gcc/f/runtime/libI77/Makefile.in index 9dde6519245..34bc5fa3997 100644 --- a/gnu/usr.bin/gcc/f/runtime/libI77/Makefile.in +++ b/gnu/usr.bin/gcc/f/runtime/libI77/Makefile.in @@ -38,7 +38,7 @@ DEFS = @DEFS@ CGFLAGS = -g0 # f2c.h should already be installed in xgcc's include directory but add that # to -I anyhow in case not using xgcc. -ALL_CFLAGS = -I$(srcdir) -I../../../include $(CPPFLAGS) $(DEFS) $(CFLAGS) +ALL_CFLAGS = -I. -I$(srcdir) -I../../../include $(CPPFLAGS) $(DEFS) $(CFLAGS) AR = @AR@ AR_FLAGS = rc RANLIB = @RANLIB@ @@ -50,10 +50,6 @@ CROSS = @CROSS@ .c.o: $(CC) -c -DSkip_f2c_Undefs -DAllow_TYQUAD $(ALL_CFLAGS) $(CGFLAGS) $< -# Next two lines were removed because Solaris doesn't like `ld -x', and -# it seems there's no real benefit to doing this anyway. -# ld -r -x -o $@x $@ -# mv $@x $@ OBJ = VersionI.o backspace.o close.o dfe.o dolio.o due.o endfile.o err.o \ fmt.o fmtlib.o iio.o ilnw.o inquire.o lread.o lwrite.o open.o \ @@ -61,33 +57,18 @@ OBJ = VersionI.o backspace.o close.o dfe.o dolio.o due.o endfile.o err.o \ util.o wref.o wrtfmt.o wsfe.o wsle.o wsne.o xwsne.o \ ftell_.o -lib = ../../../libf2c.a +F2C_H = ../../../include/f2c.h -F2C_H = ../../include/f2c.h - -all: $(F2C_H) $(lib) - -$(lib): force $(OBJ) -# Don't worry if ar fails, that can happen when a root-like user installs a -# system built by a user to which the installer has insufficient access -# to modify libf2c.a. Probably a better solution to this should be -# found, but this should do for now. -- burley 951226 - -$(AR) $(AR_FLAGS) $(lib) $(OBJ) - if $(RANLIB_TEST); then $(RANLIB) $(lib); \ - else true; fi - -uninstall: -install: +all: $(OBJ) VersionI.o: Version.c $(CC) -c $(CGFLAGS) -o $@ $(srcdir)/Version.c -# Next two lines were removed because Solaris doesn't like `ld -x', and -# it seems there's no real benefit to doing this anyway. -# ld -r -x -o $@x $@ -# mv $@x $@ -clean: - rm -f $(OBJ) +mostlyclean clean: + -rm -f $(OBJ) + +distclean maintainer-clean: mostlyclean + -rm -f stage? include Makefile backspace.o: fio.h close.o: fio.h @@ -145,4 +126,4 @@ xwsne.o: fmt.h # May be pessimistic: $(OBJ): $(F2C_H) -force: +.PHONY: mostlyclean clean distclean maintainer-clean all diff --git a/gnu/usr.bin/gcc/f/runtime/libI77/README b/gnu/usr.bin/gcc/f/runtime/libI77/README index 3e822f8c506..daa6f6d2be1 100644 --- a/gnu/usr.bin/gcc/f/runtime/libI77/README +++ b/gnu/usr.bin/gcc/f/runtime/libI77/README @@ -32,6 +32,9 @@ number of characters transmitted -- then insert the line at the end of fmt.h . This is necessary with at least some versions of Sun and DEC software. +In particular, if you get a warning about an improper +pointer/integer combination in compiling wref.c, then +you need to compile with -DUSE_STRLEN . If your system's fopen does not like the ANSI binary reading and writing modes "rb" and "wb", then you should diff --git a/gnu/usr.bin/gcc/f/runtime/libI77/Version.c b/gnu/usr.bin/gcc/f/runtime/libI77/Version.c index f59a17679db..d65c937b2bc 100644 --- a/gnu/usr.bin/gcc/f/runtime/libI77/Version.c +++ b/gnu/usr.bin/gcc/f/runtime/libI77/Version.c @@ -1,9 +1,9 @@ -static char junk[] = "\n@(#) LIBI77 VERSION pjw,dmg-mods 19960925\n"; +static char junk[] = "\n@(#) LIBI77 VERSION pjw,dmg-mods 19961209\n"; /* */ -char __G77_LIBI77_VERSION__[] = "0.5.19"; +char __G77_LIBI77_VERSION__[] = "0.5.20"; /* 2.01 $ format added @@ -242,11 +242,15 @@ wrtfmt.c: integer*1 values trouble you when using a K&R C compiler, switch to an ANSI compiler or use a compiler flag that makes characters signed. */ +/* 9 Dec. 1996: d[fu]e.c, err.c: complain about non-positive rec= + in direct read and write statements. + ftell_.c: change param "unit" to "Unit" for -DKR_headers. */ #include <stdio.h> void -g77_libi77_version () +g77__ivers__ () { - fprintf (stderr, "__G77_LIBI77_VERSION__: %s\n", __G77_LIBI77_VERSION__); + fprintf (stderr, "__G77_LIBI77_VERSION__: %s", __G77_LIBI77_VERSION__); + fputs (junk, stderr); } diff --git a/gnu/usr.bin/gcc/f/runtime/libI77/backspace.c b/gnu/usr.bin/gcc/f/runtime/libI77/backspace.c index f995db22ed9..d8e0b63bcfd 100644 --- a/gnu/usr.bin/gcc/f/runtime/libI77/backspace.c +++ b/gnu/usr.bin/gcc/f/runtime/libI77/backspace.c @@ -15,9 +15,9 @@ integer f_back(alist *a) long x, y; char buf[32]; if(a->aunit >= MXUNIT || a->aunit < 0) - err(a->aerr,101,"backspace") + err(a->aerr,101,"backspace"); b= &f__units[a->aunit]; - if(b->useek==0) err(a->aerr,106,"backspace") + if(b->useek==0) err(a->aerr,106,"backspace"); if(b->ufd==NULL) { fk_open(1, 1, a->aunit); return(0); @@ -29,7 +29,7 @@ integer f_back(alist *a) if(b->uwrt) { (void) t_runc(a); if (f__nowreading(b)) - err(a->aerr,errno,"backspace") + err(a->aerr,errno,"backspace"); } if(b->url>0) { @@ -93,7 +93,7 @@ integer f_back(alist *a) (void) fseek(b->ufd, 0L, SEEK_SET); return(0); } - else if(n<=0) err(a->aerr,(EOF),"backspace") + else if(n<=0) err(a->aerr,(EOF),"backspace"); (void) fseek(b->ufd, x, SEEK_SET); } } diff --git a/gnu/usr.bin/gcc/f/runtime/libI77/dfe.c b/gnu/usr.bin/gcc/f/runtime/libI77/dfe.c index 86fbe8ebb28..334c1dc9004 100644 --- a/gnu/usr.bin/gcc/f/runtime/libI77/dfe.c +++ b/gnu/usr.bin/gcc/f/runtime/libI77/dfe.c @@ -93,9 +93,11 @@ c_dfe(cilist *a) if(f__curunit->ufd==NULL && fk_open(DIR,FMT,a->ciunit)) err(a->cierr,104,"dfe"); f__cf=f__curunit->ufd; - if(!f__curunit->ufmt) err(a->cierr,102,"dfe") - if(!f__curunit->useek) err(a->cierr,104,"dfe") + if(!f__curunit->ufmt) err(a->cierr,102,"dfe"); + if(!f__curunit->useek) err(a->cierr,104,"dfe"); f__fmtbuf=a->cifmt; + if(a->cirec <= 0) + err(a->cierr,130,"dfe"); (void) fseek(f__cf,(long)f__curunit->url * (a->cirec-1),SEEK_SET); f__curunit->uend = 0; return(0); @@ -108,8 +110,8 @@ integer s_rdfe(cilist *a) { int n; if(!f__init) f_init(); - if(n=c_dfe(a))return(n); f__reading=1; + if(n=c_dfe(a))return(n); if(f__curunit->uwrt && f__nowreading(f__curunit)) err(a->cierr,errno,"read start"); f__getn = y_getc; @@ -130,8 +132,8 @@ integer s_wdfe(cilist *a) { int n; if(!f__init) f_init(); - if(n=c_dfe(a)) return(n); f__reading=0; + if(n=c_dfe(a)) return(n); if(f__curunit->uwrt != 1 && f__nowwriting(f__curunit)) err(a->cierr,errno,"startwrt"); f__putn = y_putc; diff --git a/gnu/usr.bin/gcc/f/runtime/libI77/due.c b/gnu/usr.bin/gcc/f/runtime/libI77/due.c index d5ade7ac057..f32e44af2f7 100644 --- a/gnu/usr.bin/gcc/f/runtime/libI77/due.c +++ b/gnu/usr.bin/gcc/f/runtime/libI77/due.c @@ -16,9 +16,11 @@ c_due(cilist *a) f__elist=a; if(f__curunit->ufd==NULL && fk_open(DIR,UNF,a->ciunit) ) err(a->cierr,104,"due"); f__cf=f__curunit->ufd; - if(f__curunit->ufmt) err(a->cierr,102,"cdue") - if(!f__curunit->useek) err(a->cierr,104,"cdue") - if(f__curunit->ufd==NULL) err(a->cierr,114,"cdue") + if(f__curunit->ufmt) err(a->cierr,102,"cdue"); + if(!f__curunit->useek) err(a->cierr,104,"cdue"); + if(f__curunit->ufd==NULL) err(a->cierr,114,"cdue"); + if(a->cirec <= 0) + err(a->cierr,130,"due"); (void) fseek(f__cf,(long)(a->cirec-1)*f__curunit->url,SEEK_SET); f__curunit->uend = 0; return(0); @@ -30,8 +32,8 @@ integer s_rdue(cilist *a) #endif { int n; - if(n=c_due(a)) return(n); f__reading=1; + if(n=c_due(a)) return(n); if(f__curunit->uwrt && f__nowreading(f__curunit)) err(a->cierr,errno,"read start"); return(0); @@ -43,8 +45,8 @@ integer s_wdue(cilist *a) #endif { int n; - if(n=c_due(a)) return(n); f__reading=0; + if(n=c_due(a)) return(n); if(f__curunit->uwrt != 1 && f__nowwriting(f__curunit)) err(a->cierr,errno,"write start"); return(0); diff --git a/gnu/usr.bin/gcc/f/runtime/libI77/err.c b/gnu/usr.bin/gcc/f/runtime/libI77/err.c index 171cb97f145..4f785cac1f4 100644 --- a/gnu/usr.bin/gcc/f/runtime/libI77/err.c +++ b/gnu/usr.bin/gcc/f/runtime/libI77/err.c @@ -6,7 +6,7 @@ #include "fio.h" #include "fmt.h" /* for struct syl */ #include "rawio.h" /* for fcntl.h, fdopen */ -#ifdef NON_UNIX_STDIO +#if defined (NON_UNIX_STDIO) || defined (MISSING_FILE_ELEMS) #ifdef KR_headers extern char *malloc(); #else @@ -75,7 +75,8 @@ char *F_err[] = "can't read file", /* 126 */ "can't write file", /* 127 */ "'new' file exists", /* 128 */ - "can't append to file" /* 129 */ + "can't append to file", /* 129 */ + "non-positive record number" /* 130 */ }; #define MAXERR (sizeof(F_err)/sizeof(char *)+100) diff --git a/gnu/usr.bin/gcc/f/runtime/libI77/fio.h b/gnu/usr.bin/gcc/f/runtime/libI77/fio.h index d3b8c275c8e..26354e44360 100644 --- a/gnu/usr.bin/gcc/f/runtime/libI77/fio.h +++ b/gnu/usr.bin/gcc/f/runtime/libI77/fio.h @@ -80,8 +80,8 @@ extern int (*f__doend)(Void); extern FILE *f__cf; /*current file*/ extern unit *f__curunit; /*current unit*/ extern unit f__units[]; -#define err(f,m,s) {if(f) errno= m; else f__fatal(m,s); return(m);} -#define errfl(f,m,s) return err__fl((int)f,m,s) +#define err(f,m,s) do {if(f) errno= m; else f__fatal(m,s); return(m);} while(0) +#define errfl(f,m,s) do {return err__fl((int)f,m,s);} while(0) /*Table sizes*/ #define MXUNIT 100 diff --git a/gnu/usr.bin/gcc/f/runtime/libI77/fmtlib.c b/gnu/usr.bin/gcc/f/runtime/libI77/fmtlib.c index 1c6801e68b5..91483fc5290 100644 --- a/gnu/usr.bin/gcc/f/runtime/libI77/fmtlib.c +++ b/gnu/usr.bin/gcc/f/runtime/libI77/fmtlib.c @@ -5,6 +5,8 @@ #ifndef Allow_TYQUAD #undef longint #define longint long +#undef ulongint +#define ulongint unsigned long #endif #ifdef KR_headers @@ -13,13 +15,17 @@ char *f__icvt(value,ndigit,sign, base) longint value; int *ndigit,*sign; #else char *f__icvt(longint value, int *ndigit, int *sign, int base) #endif -{ static char buf[MAXINTLENGTH+1]; +{ + static char buf[MAXINTLENGTH+1]; register int i; + ulongint uvalue; - if(value > 0) + if(value > 0) { + uvalue = value; *sign = 0; + } else if (value < 0) { - value = -value; + uvalue = -value; *sign = 1; } else { @@ -30,10 +36,10 @@ char *f__icvt(longint value, int *ndigit, int *sign, int base) } i = MAXINTLENGTH; do { - buf[--i] = (value%base) + '0'; - value /= base; + buf[--i] = (uvalue%base) + '0'; + uvalue /= base; } - while(value > 0); + while(uvalue > 0); *ndigit = MAXINTLENGTH - i; return &buf[i]; } diff --git a/gnu/usr.bin/gcc/f/runtime/libI77/ftell_.c b/gnu/usr.bin/gcc/f/runtime/libI77/ftell_.c index 8e5b825326d..f3a69738d3d 100644 --- a/gnu/usr.bin/gcc/f/runtime/libI77/ftell_.c +++ b/gnu/usr.bin/gcc/f/runtime/libI77/ftell_.c @@ -3,32 +3,32 @@ static FILE * #ifdef KR_headers -unit_chk(unit, who) integer unit; char *who; +unit_chk(Unit, who) integer Unit; char *who; #else -unit_chk(integer unit, char *who) +unit_chk(integer Unit, char *who) #endif { - if (unit >= MXUNIT || unit < 0) + if (Unit >= MXUNIT || Unit < 0) f__fatal(101, who); - return f__units[unit].ufd; + return f__units[Unit].ufd; } integer #ifdef KR_headers -ftell_(unit) integer *unit; +ftell_(Unit) integer *Unit; #else -ftell_(integer *unit) +ftell_(integer *Unit) #endif { FILE *f; - return (f = unit_chk(*unit, "ftell")) ? ftell(f) : -1L; + return (f = unit_chk(*Unit, "ftell")) ? ftell(f) : -1L; } int #ifdef KR_headers -fseek_(unit, offset, xwhence) integer *unit, *offset, *xwhence; +fseek_(Unit, offset, xwhence) integer *Unit, *offset, *xwhence; #else -fseek_(integer *unit, integer *offset, integer *xwhence) +fseek_(integer *Unit, integer *offset, integer *xwhence) #endif { int whence; @@ -49,6 +49,6 @@ fseek_(integer *unit, integer *offset, integer *xwhence) break; } - return !(f = unit_chk(*unit, "fseek")) + return !(f = unit_chk(*Unit, "fseek")) || fseek(f, *offset, whence) ? 1 : 0; } diff --git a/gnu/usr.bin/gcc/f/runtime/libI77/lread.c b/gnu/usr.bin/gcc/f/runtime/libI77/lread.c index b987a5f18ab..5ed2bb53dab 100644 --- a/gnu/usr.bin/gcc/f/runtime/libI77/lread.c +++ b/gnu/usr.bin/gcc/f/runtime/libI77/lread.c @@ -500,7 +500,7 @@ c_le(cilist *a) if(f__curunit->ufd==NULL && fk_open(SEQ,FMT,a->ciunit)) err(a->cierr,102,"lio"); f__cf=f__curunit->ufd; - if(!f__curunit->ufmt) err(a->cierr,103,"lio") + if(!f__curunit->ufmt) err(a->cierr,103,"lio"); return(0); } #ifdef KR_headers @@ -517,14 +517,14 @@ l_read(ftnint *number, char *ptr, ftnlen len, ftnint type) { if(f__lquit) return(0); if(l_eof) - err(f__elist->ciend, EOF, "list in") + err(f__elist->ciend, EOF, "list in"); if(f__lcount == 0) { f__ltype = 0; for(;;) { GETC(ch); switch(ch) { case EOF: - err(f__elist->ciend,(EOF),"list in") + err(f__elist->ciend,(EOF),"list in"); case ' ': case '\t': case '\n': diff --git a/gnu/usr.bin/gcc/f/runtime/libI77/makefile b/gnu/usr.bin/gcc/f/runtime/libI77/makefile new file mode 100644 index 00000000000..3e9b516863c --- /dev/null +++ b/gnu/usr.bin/gcc/f/runtime/libI77/makefile @@ -0,0 +1,101 @@ +.SUFFIXES: .c .o +CC = cc +CFLAGS = -O +SHELL = /bin/sh + +# compile, then strip unnecessary symbols +.c.o: + $(CC) -c -DSkip_f2c_Undefs $(CFLAGS) $*.c + ld -r -x -o $*.xxx $*.o + mv $*.xxx $*.o +## Under Solaris, omit -x in the ld line above. + +OBJ = Version.o backspace.o close.o dfe.o dolio.o due.o endfile.o err.o \ + fmt.o fmtlib.o ftell_.o iio.o ilnw.o inquire.o lread.o lwrite.o \ + open.o rdfmt.o rewind.o rsfe.o rsli.o rsne.o sfe.o sue.o typesize.o \ + uio.o util.o wref.o wrtfmt.o wsfe.o wsle.o wsne.o xwsne.o +libI77.a: $(OBJ) + ar r libI77.a $? + -ranlib libI77.a + +### If your system lacks ranlib, you don't need it; see README. + +install: libI77.a + cp libI77.a /usr/lib/libI77.a + ranlib /usr/lib/libI77.a + +Version.o: Version.c + $(CC) -c Version.c + +# To compile with C++, first "make f2c.h" +f2c.h: f2ch.add + cat /usr/include/f2c.h f2ch.add >f2c.h + + +clean: + rm -f $(OBJ) libI77.a + +clobber: clean + rm -f libI77.a + +backspace.o: fio.h +close.o: fio.h +dfe.o: fio.h +dfe.o: fmt.h +due.o: fio.h +endfile.o: fio.h rawio.h +err.o: fio.h rawio.h +fmt.o: fio.h +fmt.o: fmt.h +ftell_.o: fio.h +iio.o: fio.h +iio.o: fmt.h +ilnw.o: fio.h +ilnw.o: lio.h +inquire.o: fio.h +lread.o: fio.h +lread.o: fmt.h +lread.o: lio.h +lread.o: fp.h +lwrite.o: fio.h +lwrite.o: fmt.h +lwrite.o: lio.h +open.o: fio.h rawio.h +rdfmt.o: fio.h +rdfmt.o: fmt.h +rdfmt.o: fp.h +rewind.o: fio.h +rsfe.o: fio.h +rsfe.o: fmt.h +rsli.o: fio.h +rsli.o: lio.h +rsne.o: fio.h +rsne.o: lio.h +sfe.o: fio.h +sue.o: fio.h +uio.o: fio.h +util.o: fio.h +wref.o: fio.h +wref.o: fmt.h +wref.o: fp.h +wrtfmt.o: fio.h +wrtfmt.o: fmt.h +wsfe.o: fio.h +wsfe.o: fmt.h +wsle.o: fio.h +wsle.o: fmt.h +wsle.o: lio.h +wsne.o: fio.h +wsne.o: lio.h +xwsne.o: fio.h +xwsne.o: lio.h +xwsne.o: fmt.h + +check: + xsum Notice README Version.c backspace.c close.c dfe.c dolio.c \ + due.c endfile.c err.c f2ch.add fio.h fmt.c fmt.h fmtlib.c fp.h \ + ftell_.c iio.c ilnw.c inquire.c lio.h lread.c lwrite.c makefile \ + open.c rawio.h rdfmt.c rewind.c rsfe.c rsli.c rsne.c sfe.c sue.c \ + typesize.c uio.c util.c wref.c wrtfmt.c wsfe.c wsle.c wsne.c \ + xwsne.c >zap + cmp zap libI77.xsum && rm zap || diff libI77.xsum zap diff --git a/gnu/usr.bin/gcc/f/runtime/libI77/open.c b/gnu/usr.bin/gcc/f/runtime/libI77/open.c index 14f1c7815a7..4ef02df94d3 100644 --- a/gnu/usr.bin/gcc/f/runtime/libI77/open.c +++ b/gnu/usr.bin/gcc/f/runtime/libI77/open.c @@ -82,7 +82,7 @@ integer f_open(olist *a) struct stat stb; #endif if(a->ounit>=MXUNIT || a->ounit<0) - err(a->oerr,101,"open") + err(a->oerr,101,"open"); if (!f__init) f_init(); f__curunit = b = &f__units[a->ounit]; @@ -125,7 +125,7 @@ integer f_open(olist *a) if (a->ofnm) { g_char(a->ofnm,a->ofnmlen,buf); if (!buf[0]) - err(a->oerr,107,"open") + err(a->oerr,107,"open"); } else sprintf(buf, "fort.%ld", a->ounit); @@ -139,7 +139,7 @@ integer f_open(olist *a) #else if(stat(buf,&stb)) #endif - err(a->oerr,errno,"open") + err(a->oerr,errno,"open"); break; case 's': case 'S': @@ -158,7 +158,7 @@ integer f_open(olist *a) #else if(!stat(buf,&stb)) #endif - err(a->oerr,128,"open") + err(a->oerr,128,"open"); /* no break */ case 'r': /* Fortran 90 replace option */ case 'R': @@ -182,7 +182,7 @@ integer f_open(olist *a) #endif if(f__isdev(buf)) { b->ufd = fopen(buf,f__r_mode[ufmt]); - if(b->ufd==NULL) err(a->oerr,errno,buf) + if(b->ufd==NULL) err(a->oerr,errno,buf); } else { if(!(b->ufd = fopen(buf, f__r_mode[ufmt]))) { @@ -208,7 +208,7 @@ integer f_open(olist *a) b->useek=f__canseek(b->ufd); #ifndef NON_UNIX_STDIO if((b->uinode=f__inode(buf,&b->udev))==-1) - err(a->oerr,108,"open") + err(a->oerr,108,"open"); #endif if(b->useek) if (a->orl) diff --git a/gnu/usr.bin/gcc/f/runtime/libI77/rewind.c b/gnu/usr.bin/gcc/f/runtime/libI77/rewind.c index e58daad7b8a..1095ed9b520 100644 --- a/gnu/usr.bin/gcc/f/runtime/libI77/rewind.c +++ b/gnu/usr.bin/gcc/f/runtime/libI77/rewind.c @@ -13,7 +13,7 @@ integer f_rew(alist *a) if(b->ufd == NULL || b->uwrt == 3) return(0); if(!b->useek) - err(a->aerr,106,"rewind") + err(a->aerr,106,"rewind"); if(b->uwrt) { (void) t_runc(a); b->uwrt = 3; diff --git a/gnu/usr.bin/gcc/f/runtime/libI77/rsne.c b/gnu/usr.bin/gcc/f/runtime/libI77/rsne.c index 9e2acad3d7d..6915fe87ad6 100644 --- a/gnu/usr.bin/gcc/f/runtime/libI77/rsne.c +++ b/gnu/usr.bin/gcc/f/runtime/libI77/rsne.c @@ -29,7 +29,7 @@ typedef struct hashtab hashtab; static hashtab *nl_cache; - static n_nlcache; + static int n_nlcache; static hashentry **zot; static int colonseen; extern ftnlen f__typesize[]; diff --git a/gnu/usr.bin/gcc/f/runtime/libI77/sfe.c b/gnu/usr.bin/gcc/f/runtime/libI77/sfe.c index eea9078eee4..355e2700f42 100644 --- a/gnu/usr.bin/gcc/f/runtime/libI77/sfe.c +++ b/gnu/usr.bin/gcc/f/runtime/libI77/sfe.c @@ -23,8 +23,8 @@ c_sfe(cilist *a) /* check */ if(a->ciunit >= MXUNIT || a->ciunit<0) err(a->cierr,101,"startio"); p = &f__units[a->ciunit]; - if(p->ufd==NULL && fk_open(SEQ,FMT,a->ciunit)) err(a->cierr,114,"sfe") - if(!p->ufmt) err(a->cierr,102,"sfe") + if(p->ufd==NULL && fk_open(SEQ,FMT,a->ciunit)) err(a->cierr,114,"sfe"); + if(!p->ufmt) err(a->cierr,102,"sfe"); return(0); } integer e_wsfe(Void) diff --git a/gnu/usr.bin/gcc/f/runtime/libI77/sue.c b/gnu/usr.bin/gcc/f/runtime/libI77/sue.c index b1b8bc38548..90f4e3139f1 100644 --- a/gnu/usr.bin/gcc/f/runtime/libI77/sue.c +++ b/gnu/usr.bin/gcc/f/runtime/libI77/sue.c @@ -18,8 +18,8 @@ c_sue(cilist *a) if(f__curunit->ufd==NULL && fk_open(SEQ,UNF,a->ciunit)) err(a->cierr,114,"sue"); f__cf=f__curunit->ufd; - if(f__curunit->ufmt) err(a->cierr,103,"sue") - if(!f__curunit->useek) err(a->cierr,103,"sue") + if(f__curunit->ufmt) err(a->cierr,103,"sue"); + if(!f__curunit->useek) err(a->cierr,103,"sue"); return(0); } #ifdef KR_headers diff --git a/gnu/usr.bin/gcc/f/runtime/libI77/uio.c b/gnu/usr.bin/gcc/f/runtime/libI77/uio.c index 645392d7af5..daefcd94f20 100644 --- a/gnu/usr.bin/gcc/f/runtime/libI77/uio.c +++ b/gnu/usr.bin/gcc/f/runtime/libI77/uio.c @@ -44,7 +44,7 @@ integer do_ud(ftnint *number, char *ptr, ftnlen len) #endif if (!(i = fread(ptr,(size_t)len,(size_t)(*number),f__cf)) && !(f__recpos - *number*len)) - err(f__elist->cierr,EOF,"do_ud") + err(f__elist->cierr,EOF,"do_ud"); if (i < *number) memset(ptr + i*len, 0, (*number - i)*len); return 0; diff --git a/gnu/usr.bin/gcc/f/runtime/libI77/wrtfmt.c b/gnu/usr.bin/gcc/f/runtime/libI77/wrtfmt.c index a47af4da1bb..74b85769769 100644 --- a/gnu/usr.bin/gcc/f/runtime/libI77/wrtfmt.c +++ b/gnu/usr.bin/gcc/f/runtime/libI77/wrtfmt.c @@ -92,7 +92,7 @@ wrt_Z(Uint *n, int w, int minlen, ftnlen len) #endif { register char *s, *se; - register i, w1; + register int i, w1; static int one = 1; static char hex[] = "0123456789ABCDEF"; s = (char *)n; diff --git a/gnu/usr.bin/gcc/f/src.h b/gnu/usr.bin/gcc/f/src.h index b5d7dfa8b50..02279154d28 100644 --- a/gnu/usr.bin/gcc/f/src.h +++ b/gnu/usr.bin/gcc/f/src.h @@ -87,9 +87,9 @@ extern bool ffesrc_ok_match_noninit_lower_; characters for which ffelex_is_firstnamechar returns TRUE. */ #define ffesrc_is_name_init(c) \ - ((isalpha ((c))) || (!ffe_is_90 () && ((c) == '_'))) + ((isalpha ((c))) || (!(1 || ffe_is_90 ()) && ((c) == '_'))) #define ffesrc_is_name_noninit(c) \ - ((isalnum ((c))) || (!ffe_is_90 () && ((c) == '_'))) + ((isalnum ((c))) || (!(1 || ffe_is_90 ()) && ((c) == '_'))) /* Test if source-translated character matches given alphabetic character (passed in both uppercase and lowercase, to allow for custom speedup diff --git a/gnu/usr.bin/gcc/f/sta.c b/gnu/usr.bin/gcc/f/sta.c index 79073f205f4..2c1672f832d 100644 --- a/gnu/usr.bin/gcc/f/sta.c +++ b/gnu/usr.bin/gcc/f/sta.c @@ -1,5 +1,5 @@ /* sta.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995-1997 Free Software Foundation, Inc. Contributed by James Craig Burley (burley@gnu.ai.mit.edu). This file is part of GNU Fortran. @@ -78,7 +78,7 @@ bool ffesta_line_has_semicolons = FALSE; the confirmed stmt and forget the rest. */ -#define FFESTA_maxPOSSIBLES_ 100/* Never more than this # of possibles. */ +#define FFESTA_maxPOSSIBLES_ 8/* Never more than this # of possibles. */ /* Internal typedefs. */ @@ -94,6 +94,7 @@ struct _ffesta_possible_ ffestaPossible_ next; ffestaPossible_ previous; ffelexHandler handler; + bool named; }; struct _ffesta_possible_root_ @@ -109,7 +110,7 @@ static bool ffesta_is_inhibited_ = FALSE; static ffelexToken ffesta_token_0_; /* For use by ffest possibility handling. */ static ffestaPossible_ ffesta_possibles_[FFESTA_maxPOSSIBLES_]; -static int ffesta_num_possibles_ = 0; /* Next possibility to use. */ +static int ffesta_num_possibles_ = 0; /* Number of possibilities. */ static struct _ffesta_possible_root_ ffesta_possible_nonexecs_; static struct _ffesta_possible_root_ ffesta_possible_execs_; static ffestaPossible_ ffesta_current_possible_; @@ -129,8 +130,7 @@ static bool ffesta_inhibit_confirmation_ = FALSE; /* Static functions (internal). */ -static void ffesta_add_possible_exec_ (ffelexHandler fn); -static void ffesta_add_possible_nonexec_ (ffelexHandler fn); +static void ffesta_add_possible_ (ffelexHandler fn, bool exec, bool named); static bool ffesta_inhibited_exec_transition_ (void); static void ffesta_reset_possibles_ (void); static ffelexHandler ffesta_save_ (ffelexToken t); @@ -140,45 +140,16 @@ static ffelexHandler ffesta_send_two_ (ffelexToken t); #endif /* Internal macros. */ - - -/* ffesta_add_possible_exec_ -- Add possible executable statement to list - - ffelexHandler ffestb_some_executable_stmt_handler_; - ffesta_add_possible_exec_(ffestb_some_executable_stmt_handler_); - - Adds a possible statement to the list of executable statements, with the - specified statement handler as the recipient of the first token in the - statement. */ - -static void -ffesta_add_possible_exec_ (ffelexHandler fn) -{ - ffestaPossible_ p; - - assert (ffesta_num_possibles_ < FFESTA_maxPOSSIBLES_); - - p = ffesta_possibles_[ffesta_num_possibles_++]; - - p->next = (ffestaPossible_) &ffesta_possible_execs_.first; - p->previous = ffesta_possible_execs_.last; - p->next->previous = p; - p->previous->next = p; - p->handler = fn; -} - -/* ffesta_add_possible_nonexec_ -- Add possible nonexecutable statement to list - - ffelexHandler ffestb_some_nonexecutable_stmt_handler_; - ffesta_add_possible_nonexec_(ffestb_some_nonexecutable_stmt_handler_); - - Adds a possible statement to the list of nonexecutable statements, with the - specified statement handler as the recipient of the first token in the - statement. */ +#define ffesta_add_possible_exec_(fn) (ffesta_add_possible_ (fn, TRUE, TRUE)) +#define ffesta_add_possible_nonexec_(fn) (ffesta_add_possible_ (fn, FALSE, TRUE)) +#define ffesta_add_possible_unnamed_exec_(fn) (ffesta_add_possible_ (fn, TRUE, FALSE)) +#define ffesta_add_possible_unnamed_nonexec_(fn) (ffesta_add_possible_ (fn, FALSE, FALSE)) + +/* Add possible statement to appropriate list. */ static void -ffesta_add_possible_nonexec_ (ffelexHandler fn) +ffesta_add_possible_ (ffelexHandler fn, bool exec, bool named) { ffestaPossible_ p; @@ -186,12 +157,21 @@ ffesta_add_possible_nonexec_ (ffelexHandler fn) p = ffesta_possibles_[ffesta_num_possibles_++]; - p->next = (ffestaPossible_) &ffesta_possible_nonexecs_.first; - p->previous = ffesta_possible_nonexecs_.last; + if (exec) + { + p->next = (ffestaPossible_) &ffesta_possible_execs_.first; + p->previous = ffesta_possible_execs_.last; + } + else + { + p->next = (ffestaPossible_) &ffesta_possible_nonexecs_.first; + p->previous = ffesta_possible_nonexecs_.last; + } p->next->previous = p; p->previous->next = p; p->handler = fn; + p->named = named; } /* ffesta_inhibited_exec_transition_ -- Do exec transition while inhibited @@ -390,15 +370,44 @@ ffesta_save_ (ffelexToken t) ffesta_tokens[0] = ffesta_token_0_; if (ffesta_confirmed_possible_ == NULL) { /* No confirmed success, just use first - possible. */ - ffesta_current_possible_ = ffesta_possible_nonexecs_.first; - ffesta_current_handler_ = ffesta_current_possible_->handler; - if (ffesta_current_handler_ == NULL) + named possible, or first possible if + no named possibles. */ + ffestaPossible_ possible = ffesta_possible_nonexecs_.first; + ffestaPossible_ first = NULL; + ffestaPossible_ first_named = NULL; + ffestaPossible_ first_exec = NULL; + + for (;;) { - ffesta_current_possible_ = ffesta_possible_execs_.first; - ffesta_current_handler_ = ffesta_current_possible_->handler; - assert (ffesta_current_handler_ != NULL); + if (possible->handler == NULL) + { + if (possible == (ffestaPossible_) &ffesta_possible_nonexecs_) + { + possible = first_exec = ffesta_possible_execs_.first; + continue; + } + else + break; + } + if (first == NULL) + first = possible; + if (possible->named + && (first_named == NULL)) + first_named = possible; + + possible = possible->next; } + + if (first_named != NULL) + ffesta_current_possible_ = first_named; + else if (ffesta_seen_first_exec + && (first_exec != NULL)) + ffesta_current_possible_ = first_exec; + else + ffesta_current_possible_ = first; + + ffesta_current_handler_ = ffesta_current_possible_->handler; + assert (ffesta_current_handler_ != NULL); } else { /* Confirmed success, use it. */ @@ -569,7 +578,6 @@ static ffelexHandler ffesta_second_ (ffelexToken t) { ffelexHandler next; - bool include_only = FALSE; /* Initially valid INCLUDE form when TRUE. */ ffesymbol s; assert (ffelex_token_type (t) != FFELEX_typeNAMES); @@ -584,6 +592,12 @@ ffesta_second_ (ffelexToken t) switch (ffesta_first_kw) { +#if FFESTR_VXT + case FFESTR_firstACCEPT: + ffesta_add_possible_exec_ ((ffelexHandler) ffestb_V019); + break; +#endif + #if FFESTR_F90 case FFESTR_firstALLOCATABLE: ffestb_args.dimlist.len = FFESTR_firstlALLOCATABLE; @@ -601,12 +615,50 @@ ffesta_second_ (ffelexToken t) break; #endif + case FFESTR_firstASSIGN: + ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R838); + break; + case FFESTR_firstBACKSPACE: ffestb_args.beru.len = FFESTR_firstlBACKSPACE; ffestb_args.beru.badname = "BACKSPACE"; ffesta_add_possible_exec_ ((ffelexHandler) ffestb_beru); break; + case FFESTR_firstBLOCK: + ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_block); + break; + + case FFESTR_firstBLOCKDATA: + ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_blockdata); + break; + + case FFESTR_firstBYTE: + ffestb_args.decl.len = FFESTR_firstlBYTE; + ffestb_args.decl.type = FFESTP_typeBYTE; + ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_gentype); + break; + + case FFESTR_firstCALL: + ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R1212); + break; + + case FFESTR_firstCASE: + ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R810); + break; + + case FFESTR_firstCHRCTR: + ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_chartype); + break; + + case FFESTR_firstCLOSE: + ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R907); + break; + + case FFESTR_firstCOMMON: + ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R547); + break; + case FFESTR_firstCMPLX: ffestb_args.decl.len = FFESTR_firstlCMPLX; ffestb_args.decl.type = FFESTP_typeCOMPLEX; @@ -614,6 +666,27 @@ ffesta_second_ (ffelexToken t) break; #if FFESTR_F90 + case FFESTR_firstCONTAINS: + ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R1228); + break; +#endif + + case FFESTR_firstCONTINUE: + ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R841); + break; + + case FFESTR_firstCYCLE: + ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R834); + break; + + case FFESTR_firstDATA: + if (ffe_is_pedantic_not_90 ()) + ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R528); + else + ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R528); + break; + +#if FFESTR_F90 case FFESTR_firstDEALLOCATE: ffestb_args.heap.len = FFESTR_firstlDEALLOCATE; ffestb_args.heap.badname = "DEALLOCATE"; @@ -630,12 +703,29 @@ ffesta_second_ (ffelexToken t) break; #endif +#if FFESTR_VXT + case FFESTR_firstDEFINEFILE: + ffesta_add_possible_exec_ ((ffelexHandler) ffestb_V025); + break; + + case FFESTR_firstDELETE: + ffesta_add_possible_exec_ ((ffelexHandler) ffestb_V021); + break; +#endif case FFESTR_firstDIMENSION: ffestb_args.R524.len = FFESTR_firstlDIMENSION; ffestb_args.R524.badname = "DIMENSION"; ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R524); break; + case FFESTR_firstDO: + ffesta_add_possible_exec_ ((ffelexHandler) ffestb_do); + break; + + case FFESTR_firstDBL: + ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_double); + break; + case FFESTR_firstDBLCMPLX: ffestb_args.decl.len = FFESTR_firstlDBLCMPLX; ffestb_args.decl.type = FFESTP_typeDBLCMPLX; @@ -648,6 +738,14 @@ ffesta_second_ (ffelexToken t) ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_dbltype); break; + case FFESTR_firstDOWHILE: + ffesta_add_possible_exec_ ((ffelexHandler) ffestb_dowhile); + break; + + case FFESTR_firstELSE: + ffesta_add_possible_exec_ ((ffelexHandler) ffestb_else); + break; + case FFESTR_firstELSEIF: ffestb_args.elsexyz.second = FFESTR_secondIF; ffesta_add_possible_exec_ ((ffelexHandler) ffestb_elsexyz); @@ -818,12 +916,26 @@ ffesta_second_ (ffelexToken t) ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_dummy); break; + case FFESTR_firstEQUIVALENCE: + ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R544); + break; + + case FFESTR_firstEXIT: + ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R835); + break; + case FFESTR_firstEXTERNAL: ffestb_args.varlist.len = FFESTR_firstlEXTERNAL; ffestb_args.varlist.badname = "EXTERNAL"; ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_varlist); break; +#if FFESTR_VXT + case FFESTR_firstFIND: + ffesta_add_possible_exec_ ((ffelexHandler) ffestb_V026); + break; +#endif + /* WARNING: don't put anything that might cause an item to precede FORMAT in the list of possible statements (it's added below) without making sure FORMAT still is first. It has to run with @@ -841,6 +953,19 @@ ffesta_second_ (ffelexToken t) ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_dummy); break; + case FFESTR_firstGOTO: + ffesta_add_possible_exec_ ((ffelexHandler) ffestb_goto); + break; + + case FFESTR_firstIF: + ffesta_add_possible_exec_ ((ffelexHandler) ffestb_if); + ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R840); + break; + + case FFESTR_firstIMPLICIT: + ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_R539); + break; + case FFESTR_firstINCLUDE: ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_S3P4); switch (ffelex_token_type (t)) @@ -849,7 +974,6 @@ ffesta_second_ (ffelexToken t) case FFELEX_typeNAME: case FFELEX_typeAPOSTROPHE: case FFELEX_typeQUOTE: - include_only = TRUE; break; default: @@ -857,24 +981,16 @@ ffesta_second_ (ffelexToken t) } break; + case FFESTR_firstINQUIRE: + ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R923); + break; + case FFESTR_firstINTGR: ffestb_args.decl.len = FFESTR_firstlINTGR; ffestb_args.decl.type = FFESTP_typeINTEGER; ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_gentype); break; - case FFESTR_firstBYTE: - ffestb_args.decl.len = FFESTR_firstlBYTE; - ffestb_args.decl.type = FFESTP_typeBYTE; - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_gentype); - break; - - case FFESTR_firstWORD: - ffestb_args.decl.len = FFESTR_firstlWORD; - ffestb_args.decl.type = FFESTP_typeWORD; - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_gentype); - break; - #if FFESTR_F90 case FFESTR_firstINTENT: ffestb_args.varlist.len = FFESTR_firstlINTENT; @@ -883,6 +999,12 @@ ffesta_second_ (ffelexToken t) break; #endif +#if FFESTR_F90 + case FFESTR_firstINTERFACE: + ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R1202); + break; +#endif + case FFESTR_firstINTRINSIC: ffestb_args.varlist.len = FFESTR_firstlINTRINSIC; ffestb_args.varlist.badname = "INTRINSIC"; @@ -895,6 +1017,32 @@ ffesta_second_ (ffelexToken t) ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_gentype); break; +#if FFESTR_VXT + case FFESTR_firstMAP: + ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_V012); + break; +#endif + +#if FFESTR_F90 + case FFESTR_firstMODULE: + ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_module); + break; +#endif + + case FFESTR_firstNAMELIST: + ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R542); + break; + +#if FFESTR_F90 + case FFESTR_firstNULLIFY: + ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R624); + break; +#endif + + case FFESTR_firstOPEN: + ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R904); + break; + #if FFESTR_F90 case FFESTR_firstOPTIONAL: ffestb_args.varlist.len = FFESTR_firstlOPTIONAL; @@ -903,6 +1051,11 @@ ffesta_second_ (ffelexToken t) break; #endif + case FFESTR_firstPARAMETER: + ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R537); + ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_V027); + break; + case FFESTR_firstPAUSE: ffestb_args.halt.len = FFESTR_firstlPAUSE; ffesta_add_possible_exec_ ((ffelexHandler) ffestb_halt); @@ -916,13 +1069,23 @@ ffesta_second_ (ffelexToken t) break; #endif + case FFESTR_firstPRINT: + ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R911); + break; + #if HARD_F90 case FFESTR_firstPRIVATE: ffestb_args.varlist.len = FFESTR_firstlPRIVATE; ffestb_args.varlist.badname = "ACCESS"; ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_varlist); break; +#endif + case FFESTR_firstPROGRAM: + ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R1102); + break; + +#if HARD_F90 case FFESTR_firstPUBLIC: ffestb_args.varlist.len = FFESTR_firstlPUBLIC; ffestb_args.varlist.badname = "ACCESS"; @@ -930,23 +1093,73 @@ ffesta_second_ (ffelexToken t) break; #endif + case FFESTR_firstREAD: + ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R909); + break; + case FFESTR_firstREAL: ffestb_args.decl.len = FFESTR_firstlREAL; ffestb_args.decl.type = FFESTP_typeREAL; ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_gentype); break; +#if FFESTR_VXT + case FFESTR_firstRECORD: + ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_V016); + break; +#endif + +#if FFESTR_F90 + case FFESTR_firstRECURSIVE: + ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_recursive); + break; +#endif + + case FFESTR_firstRETURN: + ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R1227); + break; + case FFESTR_firstREWIND: ffestb_args.beru.len = FFESTR_firstlREWIND; ffestb_args.beru.badname = "REWIND"; ffesta_add_possible_exec_ ((ffelexHandler) ffestb_beru); break; +#if FFESTR_VXT + case FFESTR_firstREWRITE: + ffesta_add_possible_exec_ ((ffelexHandler) ffestb_V018); + break; +#endif + + case FFESTR_firstSAVE: + ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R522); + break; + + case FFESTR_firstSELECT: + ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R809); + break; + + case FFESTR_firstSELECTCASE: + ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R809); + break; + +#if HARD_F90 + case FFESTR_firstSEQUENCE: + ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R423B); + break; +#endif + case FFESTR_firstSTOP: ffestb_args.halt.len = FFESTR_firstlSTOP; ffesta_add_possible_exec_ ((ffelexHandler) ffestb_halt); break; +#if FFESTR_VXT + case FFESTR_firstSTRUCTURE: + ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_V003); + break; +#endif + case FFESTR_firstSUBROUTINE: ffestb_args.dummy.len = FFESTR_firstlSUBROUTINE; ffestb_args.dummy.badname = "SUBROUTINE"; @@ -962,6 +1175,22 @@ ffesta_second_ (ffelexToken t) break; #endif + case FFESTR_firstTYPE: + ffesta_add_possible_exec_ ((ffelexHandler) ffestb_V020); + break; + +#if FFESTR_F90 + case FFESTR_firstTYPE: + ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_type); + break; +#endif + +#if HARD_F90 + case FFESTR_firstTYPE: + ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_typetype); + break; +#endif + #if FFESTR_VXT case FFESTR_firstUNLOCK: ffestb_args.beru.len = FFESTR_firstlUNLOCK; @@ -970,109 +1199,47 @@ ffesta_second_ (ffelexToken t) break; #endif +#if FFESTR_VXT + case FFESTR_firstUNION: + ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_V009); + break; +#endif + +#if FFESTR_F90 + case FFESTR_firstUSE: + ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R1107); + break; +#endif + case FFESTR_firstVIRTUAL: ffestb_args.R524.len = FFESTR_firstlVIRTUAL; ffestb_args.R524.badname = "VIRTUAL"; ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R524); break; - default: - - /* For now, a decent error message for an unconfirmed stmt, rather than - just whatever is at the top of the list. */ - - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_unimplemented); + case FFESTR_firstVOLATILE: + ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_V014); break; - } - if (!include_only) - { - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_block); /* BLOCK. */ - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_blockdata); /* BLOCKDATA. */ - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_chartype); /* CHARACTER. */ - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_do); /* DO. */ - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_double); /* DOUBLE. */ - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_dowhile); /* DOWHILE. */ - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_else); /* ELSE. */ - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_goto); /* GOTO. */ - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_if); /* IF. */ -#if FFESTR_F90 - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_module); /* MODULE. */ -#endif -#if FFESTR_F90 - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_recursive); /* RECURSIVE. */ -#endif -#if FFESTR_F90 - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_type); /* TYPE. */ -#endif #if HARD_F90 - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_typetype); /* TYPE(). */ - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_where); /* WHERE. */ - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R423B); /* SEQUENCE. */ -#endif - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R522); /* SAVE. */ - if (ffe_is_pedantic_not_90 ()) - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R528); /* DATA. */ - else - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R528); /* DATA. */ - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R537); /* PARAMETER. */ - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_R539); /* IMPLICIT. */ - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R542); /* NAMELIST. */ - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R544); /* EQUIVALENCE. */ - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R547); /* COMMON. */ -#if FFESTR_F90 - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R624); /* NULLIFY. */ -#endif - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R809); /* SELECTCASE. */ - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R810); /* CASE. */ - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R834); /* CYCLE. */ - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R835); /* EXIT. */ - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R838); /* ASSIGN. */ - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R840); /* Arithmetic IF. */ - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R841); /* CONTINUE. */ - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R904); /* OPEN. */ - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R907); /* CLOSE. */ - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R909); /* READ. */ - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R910); /* WRITE. */ - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R911); /* PRINT. */ - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R923); /* INQUIRE. */ - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R1102); /* PROGRAM. */ -#if FFESTR_F90 - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R1107); /* USE. */ -#endif -#if FFESTR_F90 - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R1202); /* INTERFACE. */ -#endif - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R1212); /* CALL. */ - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R1227); /* RETURN. */ -#if FFESTR_F90 - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R1228); /* CONTAINS. */ -#endif -#if FFESTR_VXT - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_V003); /* STRUCTURE. */ -#endif -#if FFESTR_VXT - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_V009); /* UNION. */ -#endif -#if FFESTR_VXT - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_V012); /* MAP. */ -#endif - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_V014); /* VOLATILE. */ -#if FFESTR_VXT - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_V016); /* RECORD. */ - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_V018); /* REWRITE. */ - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_V019); /* ACCEPT. */ -#endif - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_V020); /* TYPE. */ -#if FFESTR_VXT - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_V021); /* DELETE. */ - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_V025); /* DEFINEFILE. */ - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_V026); /* FIND. */ + case FFESTR_firstWHERE: + ffesta_add_possible_exec_ ((ffelexHandler) ffestb_where); + break; #endif - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_V027); /* VXT PARAMETER. */ + + case FFESTR_firstWORD: + ffestb_args.decl.len = FFESTR_firstlWORD; + ffestb_args.decl.type = FFESTP_typeWORD; + ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_gentype); + break; + + case FFESTR_firstWRITE: + ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R910); + break; + + default: + break; } - else - include_only = FALSE; /* Now check the default cases, which are always "live" (meaning that no other possibility can override them). These are where the second token @@ -1085,7 +1252,7 @@ ffesta_second_ (ffelexToken t) if (((s == NULL) || (ffesymbol_dims (s) == NULL)) && !ffesta_seen_first_exec) { /* Not known as array; may be stmt function. */ - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R1229); + ffesta_add_possible_unnamed_nonexec_ ((ffelexHandler) ffestb_R1229); /* If the symbol is (or will be due to implicit typing) of CHARACTER type, then the statement might be an assignment @@ -1099,11 +1266,11 @@ ffesta_second_ (ffelexToken t) if (ffeimplic_peek_symbol_type (s, ffelex_token_text (ffesta_token_0_)) == FFEINFO_basictypeCHARACTER) - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_let); + ffesta_add_possible_unnamed_exec_ ((ffelexHandler) ffestb_let); } else /* Not statement function if known as an array. */ - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_let); + ffesta_add_possible_unnamed_exec_ ((ffelexHandler) ffestb_let); break; #if FFESTR_F90 @@ -1113,7 +1280,7 @@ ffesta_second_ (ffelexToken t) #if FFESTR_F90 case FFELEX_typePOINTS: #endif - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_let); + ffesta_add_possible_unnamed_exec_ ((ffelexHandler) ffestb_let); break; case FFELEX_typeCOLON: @@ -1163,6 +1330,7 @@ ffesta_second_ (ffelexToken t) assert (ffesta_current_handler_ != NULL); if (!ffesta_seen_first_exec) { /* Need to do exec transition now. */ + ffesta_tokens[0] = ffesta_token_0_; if (!ffestc_exec_transition ()) goto no_stmts; /* :::::::::::::::::::: */ } diff --git a/gnu/usr.bin/gcc/f/stb.c b/gnu/usr.bin/gcc/f/stb.c index ac03ae7685b..09bf59b20eb 100644 --- a/gnu/usr.bin/gcc/f/stb.c +++ b/gnu/usr.bin/gcc/f/stb.c @@ -1,5 +1,5 @@ /* stb.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995, 1996 Free Software Foundation, Inc. Contributed by James Craig Burley (burley@gnu.ai.mit.edu). This file is part of GNU Fortran. @@ -1849,19 +1849,6 @@ ffestb_subr_label_list_1_ (ffelexToken t) } } -/* ffestb_unimplemented -- Report a not-implemented error for stmt - - return ffestb_unimplemented; // to lexer after seeing EOS - - Issue an error via ffest_ffebad_start and return via ffesta_zero. */ - -ffelexHandler -ffestb_unimplemented (ffelexToken t) -{ - ffesta_ffebad_1t (FFEBAD_UNIMPL_STMT, ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - /* ffestb_do -- Parse the DO statement return ffestb_do; // to lexer @@ -9076,14 +9063,12 @@ ffestb_R10012_ (ffelexToken t) return (ffelexHandler) ffestb_R10014_ (t); case FFELEX_typeCOMMA: - ffesta_confirmed (); ffebad_start (FFEBAD_FORMAT_EXTRA_COMMA); ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); ffebad_finish (); return (ffelexHandler) ffestb_R10012_; case FFELEX_typeCLOSE_PAREN: - ffesta_confirmed (); ffebad_start (FFEBAD_FORMAT_EXTRA_COMMA); ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); ffebad_finish (); @@ -9119,7 +9104,7 @@ ffestb_R10012_ (ffelexToken t) return (ffelexHandler) ffestb_R100114_ (t); case FFELEX_typeQUOTE: - if (ffe_is_vxt_not_90 ()) + if (ffe_is_vxt ()) break; /* Error, probably something like FORMAT("17) = X. */ ffelex_set_expecting_hollerith (-1, '\"', @@ -9367,7 +9352,7 @@ ffestb_R10014_ (ffelexToken t) return (ffelexHandler) ffestb_R100111_; case FFELEX_typeQUOTE: - if (ffe_is_vxt_not_90 ()) + if (ffe_is_vxt ()) break; /* A totally bad character in a VXT FORMAT. */ ffebad_start (FFEBAD_FORMAT_SPURIOUS_NUMBER); ffebad_here (0, ffelex_token_where_line (ffestb_local_.format.pre.t), @@ -18002,13 +17987,13 @@ ffestb_V0201_ (ffelexToken ft, ffebld expr, ffelexToken t) { case FFELEX_typeEOS: case FFELEX_typeSEMICOLON: - if (!ffe_is_vxt_not_90 () && (expr != NULL) + if (!ffe_is_vxt () && (expr != NULL) && (ffebld_op (expr) == FFEBLD_opSYMTER)) break; comma = FALSE; /* Fall through. */ case FFELEX_typeCOMMA: - if (!ffe_is_vxt_not_90 () && comma && (expr != NULL) + if (!ffe_is_vxt () && comma && (expr != NULL) && (ffebld_op (expr) == FFEBLD_opPAREN) && (ffebld_op (ffebld_left (expr)) == FFEBLD_opSYMTER)) break; @@ -20379,13 +20364,9 @@ ffestb_R1229 (ffelexToken t) return (ffelexHandler) ffestb_subr_name_list_; bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "statement-function-definition", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "statement-function-definition", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ + ffesta_ffebad_2t (FFEBAD_UNREC_STMT, ffesta_tokens[0], t); + return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); } /* ffestb_R12291_ -- "STMTFUNCTION" OPEN_PAREN dummy-name-list CLOSE_PAREN @@ -20421,7 +20402,7 @@ ffestb_R12291_ (ffelexToken t) } bad: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "statement-function-definition", t); + ffesta_ffebad_2t (FFEBAD_UNREC_STMT, ffesta_tokens[0], t); ffelex_token_kill (ffestb_subrargs_.name_list.close_paren); ffestt_tokenlist_kill (ffestb_subrargs_.name_list.args); return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); diff --git a/gnu/usr.bin/gcc/f/stb.h b/gnu/usr.bin/gcc/f/stb.h index 79bed32cfc2..a3385d9a596 100644 --- a/gnu/usr.bin/gcc/f/stb.h +++ b/gnu/usr.bin/gcc/f/stb.h @@ -1,5 +1,5 @@ /* stb.h -- Private #include File (module.h template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995, 1996 Free Software Foundation, Inc. Contributed by James Craig Burley (burley@gnu.ai.mit.edu). This file is part of GNU Fortran. @@ -132,7 +132,6 @@ extern struct _ffestb_args_ ffestb_args; /* Declare functions with prototypes. */ -ffelexHandler ffestb_unimplemented (ffelexToken t); ffelexHandler ffestb_beru (ffelexToken t); ffelexHandler ffestb_block (ffelexToken t); ffelexHandler ffestb_blockdata (ffelexToken t); diff --git a/gnu/usr.bin/gcc/f/stc.c b/gnu/usr.bin/gcc/f/stc.c index 5512bcbab6b..bc803e67e82 100644 --- a/gnu/usr.bin/gcc/f/stc.c +++ b/gnu/usr.bin/gcc/f/stc.c @@ -1,5 +1,5 @@ /* stc.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995-1997 Free Software Foundation, Inc. Contributed by James Craig Burley (burley@gnu.ai.mit.edu). This file is part of GNU Fortran. @@ -2686,16 +2686,16 @@ ffestc_order_entry_ () goto recurse; /* :::::::::::::::::::: */ case FFESTV_stateSUBROUTINE0: - case FFESTV_stateSUBROUTINE1: - ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE2); + ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE1); break; case FFESTV_stateFUNCTION0: - case FFESTV_stateFUNCTION1: - ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION2); + ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION1); break; + case FFESTV_stateSUBROUTINE1: case FFESTV_stateSUBROUTINE2: + case FFESTV_stateFUNCTION1: case FFESTV_stateFUNCTION2: case FFESTV_stateSUBROUTINE3: case FFESTV_stateFUNCTION3: @@ -2848,25 +2848,25 @@ ffestc_order_format_ () goto recurse; /* :::::::::::::::::::: */ case FFESTV_statePROGRAM0: - case FFESTV_statePROGRAM1: ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM2); + ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM1); return FFESTC_orderOK_; case FFESTV_stateSUBROUTINE0: - case FFESTV_stateSUBROUTINE1: ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE2); + ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE1); return FFESTC_orderOK_; case FFESTV_stateFUNCTION0: - case FFESTV_stateFUNCTION1: ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION2); + ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION1); return FFESTC_orderOK_; + case FFESTV_statePROGRAM1: case FFESTV_statePROGRAM2: + case FFESTV_stateSUBROUTINE1: case FFESTV_stateSUBROUTINE2: + case FFESTV_stateFUNCTION1: case FFESTV_stateFUNCTION2: case FFESTV_statePROGRAM3: case FFESTV_stateSUBROUTINE3: @@ -6309,6 +6309,7 @@ ffestc_R501_item (ffelexToken name, ffebld kind, ffelexToken kindt, ffestpDimtype nd; bool is_init = (init != NULL) || clist; bool is_assumed; + bool is_ugly_assumed; ffeinfoRank rank; ffestc_check_item_ (); @@ -6335,7 +6336,11 @@ ffestc_R501_item (ffelexToken name, ffebld kind, ffelexToken kindt, if (is_assumed) na |= FFESYMBOL_attrsANYLEN; - nd = ffestt_dimlist_type (dims); + is_ugly_assumed = (ffe_is_ugly_assumed () + && ((sa & FFESYMBOL_attrsDUMMY) + || (ffesymbol_where (s) == FFEINFO_whereDUMMY))); + + nd = ffestt_dimlist_type (dims, is_ugly_assumed); switch (nd) { case FFESTP_dimtypeNONE: @@ -6456,7 +6461,8 @@ ffestc_R501_item (ffelexToken name, ffebld kind, ffelexToken kindt, { ffesymbol_set_dims (s, ffestt_dimlist_as_expr (dims, &rank, &array_size, - &extents)); + &extents, + is_ugly_assumed)); ffesymbol_set_arraysize (s, array_size); ffesymbol_set_extents (s, extents); if (!(0 && ffe_is_90 ()) @@ -7206,6 +7212,7 @@ ffestc_R524_item (ffelexToken name, ffesttDimList dims) ffesymbolAttrs na; ffestpDimtype nd; ffeinfoRank rank; + bool is_ugly_assumed; ffestc_check_item_ (); assert (name != NULL); @@ -7221,7 +7228,11 @@ ffestc_R524_item (ffelexToken name, ffesttDimList dims) /* First figure out what kind of object this is based solely on the current object situation (dimension list). */ - nd = ffestt_dimlist_type (dims); + is_ugly_assumed = (ffe_is_ugly_assumed () + && ((sa & FFESYMBOL_attrsDUMMY) + || (ffesymbol_where (s) == FFEINFO_whereDUMMY))); + + nd = ffestt_dimlist_type (dims, is_ugly_assumed); switch (nd) { case FFESTP_dimtypeKNOWN: @@ -7290,7 +7301,8 @@ ffestc_R524_item (ffelexToken name, ffesttDimList dims) ffesymbol_set_state (s, FFESYMBOL_stateSEEN); ffesymbol_set_dims (s, ffestt_dimlist_as_expr (dims, &rank, &array_size, - &extents)); + &extents, + is_ugly_assumed)); ffesymbol_set_arraysize (s, array_size); ffesymbol_set_extents (s, extents); if (!(0 && ffe_is_90 ()) @@ -8221,6 +8233,7 @@ ffestc_R547_item_object (ffelexToken name, ffesttDimList dims) ffestpDimtype nd; ffebld e; ffeinfoRank rank; + bool is_ugly_assumed; if (ffestc_parent_ok_ && (ffestc_local_.common.symbol == NULL)) ffestc_R547_item_cblock (NULL); /* As if "COMMON [//] ...". */ @@ -8239,7 +8252,11 @@ ffestc_R547_item_object (ffelexToken name, ffesttDimList dims) /* First figure out what kind of object this is based solely on the current object situation (dimension list). */ - nd = ffestt_dimlist_type (dims); + is_ugly_assumed = (ffe_is_ugly_assumed () + && ((sa & FFESYMBOL_attrsDUMMY) + || (ffesymbol_where (s) == FFEINFO_whereDUMMY))); + + nd = ffestt_dimlist_type (dims, is_ugly_assumed); switch (nd) { case FFESTP_dimtypeNONE: @@ -8325,7 +8342,8 @@ ffestc_R547_item_object (ffelexToken name, ffesttDimList dims) { ffesymbol_set_dims (s, ffestt_dimlist_as_expr (dims, &rank, &array_size, - &extents)); + &extents, + is_ugly_assumed)); ffesymbol_set_arraysize (s, array_size); ffesymbol_set_extents (s, extents); if (!(0 && ffe_is_90 ()) @@ -11811,6 +11829,7 @@ ffestc_R1207_item (ffelexToken name) ffesymbol_set_attrs (s, na); ffesymbol_set_state (s, FFESYMBOL_stateSEEN); ffesymbol_set_explicitwhere (s, TRUE); + ffesymbol_globalize (s); ffesymbol_signal_unreported (s); } @@ -11870,7 +11889,6 @@ ffestc_R1208_item (ffelexToken name) ffeintrinGen gen; ffeintrinSpec spec; ffeintrinImp imp; - ffeinfoKind kind; ffestc_check_item_ (); assert (name != NULL); @@ -11890,7 +11908,7 @@ ffestc_R1208_item (ffelexToken name) else if (!(sa & ~FFESYMBOL_attrsTYPE)) { if (ffeintrin_is_intrinsic (ffelex_token_text (name), name, TRUE, - &gen, &spec, &imp, &kind) + &gen, &spec, &imp) && ((imp == FFEINTRIN_impNONE) #if 0 /* Don't bother with this for now. */ || ((ffeintrin_basictype (spec) @@ -11902,13 +11920,6 @@ ffestc_R1208_item (ffelexToken name) #endif || !(sa & FFESYMBOL_attrsTYPE))) na = sa | FFESYMBOL_attrsINTRINSIC; - else if (kind == FFEINFO_kindANY) - { /* Already diagnosed. */ - na = sa | FFESYMBOL_attrsINTRINSIC | FFESYMBOL_attrsANY; - ffesymbol_set_attrs (s, na); - ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); - ffesymbol_set_info (s, ffeinfo_new_any ()); - } else na = FFESYMBOL_attrsetNONE; } @@ -11932,7 +11943,7 @@ ffestc_R1208_item (ffelexToken name) ffeinfo_new (FFEINFO_basictypeNONE, FFEINFO_kindtypeNONE, 0, - kind, + FFEINFO_kindNONE, FFEINFO_whereINTRINSIC, FFETARGET_charactersizeNONE)); ffesymbol_set_explicitwhere (s, TRUE); @@ -12352,6 +12363,7 @@ ffestc_R1226 (ffelexToken entryname, ffesttTokenList args, switch (ffestw_state (ffestw_stack_top ())) { + case FFESTV_stateFUNCTION1: case FFESTV_stateFUNCTION2: case FFESTV_stateFUNCTION3: in_func = TRUE; @@ -12363,6 +12375,7 @@ ffestc_R1226 (ffelexToken entryname, ffesttTokenList args, in_spec = FALSE; break; + case FFESTV_stateSUBROUTINE1: case FFESTV_stateSUBROUTINE2: case FFESTV_stateSUBROUTINE3: in_func = FALSE; diff --git a/gnu/usr.bin/gcc/f/std.c b/gnu/usr.bin/gcc/f/std.c index 303317fcd84..ea497425d9c 100644 --- a/gnu/usr.bin/gcc/f/std.c +++ b/gnu/usr.bin/gcc/f/std.c @@ -1,5 +1,5 @@ /* std.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995, 1996 Free Software Foundation, Inc. Contributed by James Craig Burley (burley@gnu.ai.mit.edu). This file is part of GNU Fortran. diff --git a/gnu/usr.bin/gcc/f/ste.c b/gnu/usr.bin/gcc/f/ste.c index 3ad03bf12bc..e1f6b36c079 100644 --- a/gnu/usr.bin/gcc/f/ste.c +++ b/gnu/usr.bin/gcc/f/ste.c @@ -1,5 +1,5 @@ /* ste.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995, 1996 Free Software Foundation, Inc. Contributed by James Craig Burley (burley@gnu.ai.mit.edu). This file is part of GNU Fortran. @@ -2351,16 +2351,25 @@ ffeste_R809 (ffestw block, ffebld expr) else { texpr = ffecom_expr (expr); - assert (ffeinfo_basictype (ffebld_info (expr)) - != FFEINFO_basictypeCHARACTER); - expand_start_case (1, texpr, TREE_TYPE (texpr), - "SELECT CASE statement"); - ffestw_set_select_texpr (block, texpr); - ffestw_set_select_break (block, FALSE); - push_momentary (); + if (ffeinfo_basictype (ffebld_info (expr)) + != FFEINFO_basictypeCHARACTER) + { + expand_start_case (1, texpr, TREE_TYPE (texpr), + "SELECT CASE statement"); + ffestw_set_select_texpr (block, texpr); + ffestw_set_select_break (block, FALSE); + push_momentary (); + } + else + { + ffebad_start_msg ("SELECT CASE on CHARACTER type (at %0) not supported -- sorry", + FFEBAD_severityFATAL); + ffebad_here (0, ffestw_line (block), ffestw_col (block)); + ffebad_finish (); + ffestw_set_select_texpr (block, error_mark_node); + } } - } /* ~~~handle character and special-case - character*1 */ + } ffecom_pop_calltemps (); #else diff --git a/gnu/usr.bin/gcc/f/storag.c b/gnu/usr.bin/gcc/f/storag.c index 9b30b5e8638..67126197610 100644 --- a/gnu/usr.bin/gcc/f/storag.c +++ b/gnu/usr.bin/gcc/f/storag.c @@ -1,5 +1,5 @@ /* storag.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995, 1996 Free Software Foundation, Inc. Contributed by James Craig Burley (burley@gnu.ai.mit.edu). This file is part of GNU Fortran. diff --git a/gnu/usr.bin/gcc/f/storag.h b/gnu/usr.bin/gcc/f/storag.h index 74a0065e779..89c5f95b726 100644 --- a/gnu/usr.bin/gcc/f/storag.h +++ b/gnu/usr.bin/gcc/f/storag.h @@ -1,5 +1,5 @@ /* storag.h -- Public #include File (module.h template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995, 1996 Free Software Foundation, Inc. Contributed by James Craig Burley (burley@gnu.ai.mit.edu). This file is part of GNU Fortran. diff --git a/gnu/usr.bin/gcc/f/stt.c b/gnu/usr.bin/gcc/f/stt.c index 0995daad23c..d0fd582355b 100644 --- a/gnu/usr.bin/gcc/f/stt.c +++ b/gnu/usr.bin/gcc/f/stt.c @@ -1,5 +1,5 @@ /* stt.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995, 1997 Free Software Foundation, Inc. Contributed by James Craig Burley (burley@gnu.ai.mit.edu). This file is part of GNU Fortran. @@ -189,7 +189,7 @@ ffestt_dimlist_append (ffesttDimList list, ffebld lower, ffebld upper, new->t = t; } -/* ffestt_dimlist_as_expr -- Convert list of dims into ffebld format +/* Convert list of dims into ffebld format. ffesttDimList list; ffeinfoRank rank; @@ -199,11 +199,15 @@ ffestt_dimlist_append (ffesttDimList list, ffebld lower, ffebld upper, The dims in the list are converted to a list of ITEMs; the rank of the array, an expression representing the array size, a list of extent - expressions, and the list of ITEMs are returned. */ + expressions, and the list of ITEMs are returned. + + If is_ugly_assumed, treat a final dimension with no lower bound + and an upper bound of 1 as a * bound. */ ffebld ffestt_dimlist_as_expr (ffesttDimList list, ffeinfoRank *rank, - ffebld *array_size, ffebld *extents) + ffebld *array_size, ffebld *extents, + bool is_ugly_assumed) { ffesttDimList next; ffebld expr; @@ -239,9 +243,10 @@ ffestt_dimlist_as_expr (ffesttDimList list, ffeinfoRank *rank, > high) zero = TRUE; if ((next->next == list) - && ffe_is_ugly_assumed () + && is_ugly_assumed && (next->lower == NULL) - && (high == 1)) + && (high == 1) + && (ffebld_conter_orig (next->upper) == NULL)) { star = TRUE; ffebld_append_item (&bottom, @@ -473,16 +478,18 @@ ffestt_dimlist_kill (ffesttDimList list) } } -/* ffestt_dimlist_type -- Determine type of list of dims +/* Determine type of list of dimensions. - ffesttDimList list; - ffestpDimtype type; - type = ffestt_dimlist_type(list); + Return KNOWN for all-constant bounds, ADJUSTABLE for constant + and variable but no * bounds, ASSUMED for constant and * but + not variable bounds, ADJUSTABLEASSUMED for constant and variable + and * bounds. - The dims in the list are dumped with commas separating them. */ + If is_ugly_assumed, treat a final dimension with no lower bound + and an upper bound of 1 as a * bound. */ ffestpDimtype -ffestt_dimlist_type (ffesttDimList list) +ffestt_dimlist_type (ffesttDimList list, bool is_ugly_assumed) { ffesttDimList next; ffestpDimtype type; @@ -493,18 +500,38 @@ ffestt_dimlist_type (ffesttDimList list) type = FFESTP_dimtypeKNOWN; for (next = list->next; next != list; next = next->next) { + bool ugly_assumed = FALSE; + + if ((next->next == list) + && is_ugly_assumed + && (next->lower == NULL) + && (next->upper != NULL) + && (ffebld_op (next->upper) == FFEBLD_opCONTER) + && (ffebld_constant_integerdefault (ffebld_conter (next->upper)) + == 1) + && (ffebld_conter_orig (next->upper) == NULL)) + ugly_assumed = TRUE; + if (next->lower != NULL) { if (ffebld_op (next->lower) != FFEBLD_opCONTER) - type = FFESTP_dimtypeADJUSTABLE; + { + if (type == FFESTP_dimtypeASSUMED) + type = FFESTP_dimtypeADJUSTABLEASSUMED; + else + type = FFESTP_dimtypeADJUSTABLE; + } } if (next->upper != NULL) { - if (ffebld_op (next->upper) == FFEBLD_opSTAR) - if (type == FFESTP_dimtypeKNOWN) - type = FFESTP_dimtypeASSUMED; - else - type = FFESTP_dimtypeADJUSTABLEASSUMED; + if (ugly_assumed + || (ffebld_op (next->upper) == FFEBLD_opSTAR)) + { + if (type == FFESTP_dimtypeADJUSTABLE) + type = FFESTP_dimtypeADJUSTABLEASSUMED; + else + type = FFESTP_dimtypeASSUMED; + } else if (ffebld_op (next->upper) != FFEBLD_opCONTER) type = FFESTP_dimtypeADJUSTABLE; } diff --git a/gnu/usr.bin/gcc/f/stt.h b/gnu/usr.bin/gcc/f/stt.h index b199d195316..827841ea983 100644 --- a/gnu/usr.bin/gcc/f/stt.h +++ b/gnu/usr.bin/gcc/f/stt.h @@ -169,11 +169,12 @@ void ffestt_caselist_kill (ffesttCaseList list); void ffestt_dimlist_append (ffesttDimList list, ffebld lower, ffebld upper, ffelexToken t); ffebld ffestt_dimlist_as_expr (ffesttDimList list, ffeinfoRank *rank, - ffebld *array_size, ffebld *extents); + ffebld *array_size, ffebld *extents, + bool is_ugly_assumed); ffesttDimList ffestt_dimlist_create (void); void ffestt_dimlist_dump (ffesttDimList list); void ffestt_dimlist_kill (ffesttDimList list); -ffestpDimtype ffestt_dimlist_type (ffesttDimList dims); +ffestpDimtype ffestt_dimlist_type (ffesttDimList dims, bool is_ugly_assumed); void ffestt_exprlist_append (ffesttExprList list, ffebld expr, ffelexToken t); ffesttExprList ffestt_exprlist_create (void); void ffestt_exprlist_drive (ffesttExprList list, void (*fn) ()); diff --git a/gnu/usr.bin/gcc/f/stu.c b/gnu/usr.bin/gcc/f/stu.c index 8138dc74605..ae3b5a44479 100644 --- a/gnu/usr.bin/gcc/f/stu.c +++ b/gnu/usr.bin/gcc/f/stu.c @@ -1,5 +1,5 @@ /* stu.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995, 1996 Free Software Foundation, Inc. Contributed by James Craig Burley (burley@gnu.ai.mit.edu). This file is part of GNU Fortran. @@ -300,6 +300,8 @@ ffestu_sym_end_transition (ffesymbol s) ffesymbol_resolve_intrin (s); s = ffecom_sym_learned (s); ffestorag_end_layout (s); + if (nwh == FFEINFO_whereGLOBAL) + ffesymbol_globalize (s); ffesymbol_signal_unreported (s); /* For debugging purposes. */ } @@ -702,7 +704,7 @@ ffestu_sym_exec_transition (ffesymbol s) resolve_intrin = FALSE; } else if (ffeintrin_is_intrinsic (ffesymbol_text (s), NULL, FALSE, - &gen, &spec, &imp, &nkd)) + &gen, &spec, &imp)) { ffesymbol_signal_change (s); ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); @@ -713,7 +715,7 @@ ffestu_sym_exec_transition (ffesymbol s) ffeinfo_new (FFEINFO_basictypeNONE, FFEINFO_kindtypeNONE, 0, - nkd, + FFEINFO_kindNONE, FFEINFO_whereINTRINSIC, FFETARGET_charactersizeNONE)); ffesymbol_resolve_intrin (s); @@ -820,6 +822,8 @@ ffestu_sym_exec_transition (ffesymbol s) else if (resolve_intrin) ffesymbol_resolve_intrin (s); ffestorag_exec_layout (s); + if (nwh == FFEINFO_whereGLOBAL) + ffesymbol_globalize (s); ffesymbol_signal_unreported (s); /* For debugging purposes. */ } diff --git a/gnu/usr.bin/gcc/f/symbol.c b/gnu/usr.bin/gcc/f/symbol.c index f4978a0dc24..8b6595dcddd 100644 --- a/gnu/usr.bin/gcc/f/symbol.c +++ b/gnu/usr.bin/gcc/f/symbol.c @@ -1,5 +1,5 @@ /* Implementation of Fortran symbol manager - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995, 1996 Free Software Foundation, Inc. Contributed by James Craig Burley (burley@gnu.ai.mit.edu). This file is part of GNU Fortran. @@ -359,7 +359,6 @@ ffesymbol_check (ffesymbol s, ffelexToken t, bool maybe_intrin) ffeintrinGen gen; ffeintrinSpec spec; ffeintrinImp imp; - ffeinfoKind kind; if (!ffesrc_check_symbol () || ((s->check_state != FFESYMBOL_checkstateNONE_) @@ -377,7 +376,7 @@ ffesymbol_check (ffesymbol s, ffelexToken t, bool maybe_intrin) if (maybe_intrin && ffeintrin_is_intrinsic (ffelex_token_text (t), NULL, FALSE, - &gen, &spec, &imp, &kind)) + &gen, &spec, &imp)) { s->check_state = FFESYMBOL_checkstatePENDING_; s->check_token = ffelex_token_use (t); @@ -864,6 +863,13 @@ ffesymbol_error (ffesymbol s, ffelexToken t) } void +ffesymbol_globalize (ffesymbol s) +{ + if (ffesymbol_global (s) == NULL) + ffesymbol_set_global (s, ffeglobal_promoted (s)); +} + +void ffesymbol_init_0 () { ffesymbolAttrs attrs = FFESYMBOL_attrsetNONE; diff --git a/gnu/usr.bin/gcc/f/symbol.def b/gnu/usr.bin/gcc/f/symbol.def index 1bb47345783..ad100d4ebbe 100644 --- a/gnu/usr.bin/gcc/f/symbol.def +++ b/gnu/usr.bin/gcc/f/symbol.def @@ -1,5 +1,5 @@ /* Definitions and documentations for attributes used in GNU F77 compiler - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995, 1996 Free Software Foundation, Inc. Contributed by James Craig Burley (burley@gnu.ai.mit.edu). This file is part of GNU Fortran. diff --git a/gnu/usr.bin/gcc/f/symbol.h b/gnu/usr.bin/gcc/f/symbol.h index f2c95c80210..0a5188e9464 100644 --- a/gnu/usr.bin/gcc/f/symbol.h +++ b/gnu/usr.bin/gcc/f/symbol.h @@ -1,5 +1,5 @@ /* Interface definitions for Fortran symbol manager - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995, 1996 Free Software Foundation, Inc. Contributed by James Craig Burley (burley@gnu.ai.mit.edu). This file is part of GNU Fortran. @@ -79,7 +79,6 @@ enum _ffesymbol_checkstate_ typedef enum _ffesymbol_checkstate_ ffesymbolCheckState_; #define ffesymbolCheckState_f_ "" -#include "bad.h" #include "bld.h" #include "com.h" #include "equiv.h" @@ -191,6 +190,7 @@ void ffesymbol_error (ffesymbol s, ffelexToken t); #define ffesymbol_funcresult(s) ((s)->func_result) #define ffesymbol_generic(s) ((s)->generic) #define ffesymbol_global(s) ((s)->global) +void ffesymbol_globalize (ffesymbol s); #define ffesymbol_hook(s) ((s)->hook) #define ffesymbol_implementation(s) ((s)->implementation) #define ffesymbol_info(s) ((s)->info) @@ -211,6 +211,7 @@ void ffesymbol_init_4 (void); #define ffesymbol_kind(s) ffeinfo_kind((s)->info) ffesymbol ffesymbol_lookup_local (ffelexToken t); #define ffesymbol_maxentrynum(s) ((s)->max_entry_num) +#define ffesymbol_name(s) ((s)->name) #define ffesymbol_namelist(s) ((s)->namelist) #define ffesymbol_namelisted(s) ((s)->namelisted) #define ffesymbol_numentries(s) ((s)->num_entries) diff --git a/gnu/usr.bin/gcc/f/target.c b/gnu/usr.bin/gcc/f/target.c index 308771569d5..828e7adcf75 100644 --- a/gnu/usr.bin/gcc/f/target.c +++ b/gnu/usr.bin/gcc/f/target.c @@ -1,5 +1,5 @@ /* target.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995-1997 Free Software Foundation, Inc. Contributed by James Craig Burley (burley@gnu.ai.mit.edu). This file is part of GNU Fortran. diff --git a/gnu/usr.bin/gcc/f/target.h b/gnu/usr.bin/gcc/f/target.h index d68f49235db..216d7704bd3 100644 --- a/gnu/usr.bin/gcc/f/target.h +++ b/gnu/usr.bin/gcc/f/target.h @@ -1,5 +1,5 @@ /* target.h -- Public #include File (module.h template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995, 1996 Free Software Foundation, Inc. Contributed by James Craig Burley (burley@gnu.ai.mit.edu). This file is part of GNU Fortran. @@ -45,7 +45,7 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA #if !defined (REAL_ARITHMETIC) \ && ((TARGET_FLOAT_FORMAT != HOST_FLOAT_FORMAT) \ || (FLOAT_WORDS_BIG_ENDIAN != HOST_FLOAT_WORDS_BIG_ENDIAN)) -#error g77 requires ability to access exact FP representation of target machine +#error "g77 requires ability to access exact FP representation of target machine" #endif /* Simple definitions and enumerations. */ @@ -82,9 +82,6 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA #ifndef FFETARGET_defaultIS_PEDANTIC #define FFETARGET_defaultIS_PEDANTIC 0 #endif -#ifndef FFETARGET_defaultIS_VXT_NOT_90 -#define FFETARGET_defaultIS_VXT_NOT_90 0 -#endif #ifndef FFETARGET_defaultCASE_INTRIN #define FFETARGET_defaultCASE_INTRIN FFE_caseLOWER #endif @@ -97,24 +94,6 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA #ifndef FFETARGET_defaultCASE_SYMBOL #define FFETARGET_defaultCASE_SYMBOL FFE_caseNONE #endif -#ifndef FFETARGET_defaultSTATE_DCP -#define FFETARGET_defaultSTATE_DCP FFE_intrinsicstateENABLED -#endif -#ifndef FFETARGET_defaultSTATE_F2C -#define FFETARGET_defaultSTATE_F2C FFE_intrinsicstateENABLED -#endif -#ifndef FFETARGET_defaultSTATE_F90 -#define FFETARGET_defaultSTATE_F90 FFE_intrinsicstateDELETED -#endif -#ifndef FFETARGET_defaultSTATE_MIL -#define FFETARGET_defaultSTATE_MIL FFE_intrinsicstateENABLED -#endif -#ifndef FFETARGET_defaultSTATE_UNIX -#define FFETARGET_defaultSTATE_UNIX FFE_intrinsicstateENABLED -#endif -#ifndef FFETARGET_defaultSTATE_VXT -#define FFETARGET_defaultSTATE_VXT FFE_intrinsicstateDELETED -#endif #ifndef FFETARGET_defaultFIXED_LINE_LENGTH #define FFETARGET_defaultFIXED_LINE_LENGTH 72 @@ -268,8 +247,13 @@ typedef long long ffetargetOffset; #define ffetargetOffset_f "ll" #if FFETARGET_okINTEGER1 +#ifndef __alpha__ typedef long int ffetargetInteger1; #define ffetargetInteger1_f "l" +#else +typedef int ffetargetInteger1; +#define ffetargetInteger1_f "" +#endif #endif #if FFETARGET_okINTEGER2 typedef signed char ffetargetInteger2; @@ -304,8 +288,13 @@ typedef ? ffetargetInteger8; ? #endif #if FFETARGET_okLOGICAL1 +#ifndef __alpha__ typedef long int ffetargetLogical1; #define ffetargetLogical1_f "l" +#else +typedef int ffetargetLogical1; +#define ffetargetLogical1_f "" +#endif #endif #if FFETARGET_okLOGICAL2 typedef signed char ffetargetLogical2; @@ -341,19 +330,59 @@ typedef ? ffetargetLogical8; #endif #if FFETARGET_okREAL1 #ifdef REAL_ARITHMETIC -typedef HOST_WIDE_INT ffetargetReal1; +#ifndef __alpha__ +typedef long int ffetargetReal1; +#define ffetargetReal1_f "l" +#define ffetarget_cvt_r1_to_rv_ REAL_VALUE_UNTO_TARGET_SINGLE +#define ffetarget_cvt_rv_to_r1_ REAL_VALUE_TO_TARGET_SINGLE #else +typedef int ffetargetReal1; +#define ffetargetReal1_f "" +#define ffetarget_cvt_r1_to_rv_(in) \ + ({ REAL_VALUE_TYPE _rv; \ + _rv = REAL_VALUE_UNTO_TARGET_SINGLE ((long) (in)); \ + _rv; }) +#define ffetarget_cvt_rv_to_r1_(in, out) \ + ({ long _tmp; \ + REAL_VALUE_TO_TARGET_SINGLE ((in), _tmp); \ + (out) = (ffetargetReal1) _tmp; }) +#endif +#else /* REAL_ARITHMETIC */ typedef float ffetargetReal1; #define ffetargetReal1_f "" -#endif +#endif /* REAL_ARITHMETIC */ #endif #if FFETARGET_okREAL2 #ifdef REAL_ARITHMETIC +#ifndef __alpha__ typedef struct { - HOST_WIDE_INT v[2]; + long int v[2]; } ffetargetReal2; +#define ffetargetReal2_f "l" +#define ffetarget_cvt_r2_to_rv_ REAL_VALUE_UNTO_TARGET_DOUBLE +#define ffetarget_cvt_rv_to_r2_ REAL_VALUE_TO_TARGET_DOUBLE +#else +typedef struct + { + int v[2]; + } +ffetargetReal2; +#define ffetargetReal2_f "" +#define ffetarget_cvt_r2_to_rv_(in) \ + ({ REAL_VALUE_TYPE _rv; \ + long _tmp[2]; \ + _tmp[0] = (in)[0]; \ + _tmp[1] = (in)[1]; \ + _rv = REAL_VALUE_UNTO_TARGET_DOUBLE (_tmp); \ + _rv; }) +#define ffetarget_cvt_rv_to_r2_(in, out) \ + ({ long _tmp[2]; \ + REAL_VALUE_TO_TARGET_DOUBLE ((in), _tmp); \ + (out)[0] = (int) (_tmp[0]); \ + (out)[1] = (int) (_tmp[1]); }) +#endif #else typedef double ffetargetReal2; #define ffetargetReal2_f "" @@ -827,28 +856,36 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len); /* Define macros. */ +#if BUILT_FOR_280 +#define FFETARGET_REAL_VALUE_FROM_INT_(resr, lf, kt) \ + REAL_VALUE_FROM_INT (resr, (long) lf, (long) ((lf < 0) ? -1 : 0), ((kt == 1) ? SFmode : DFmode)) +#else +#define FFETARGET_REAL_VALUE_FROM_INT_(resr, lf, kt) \ + REAL_VALUE_FROM_INT (resr, (long) lf, (long) ((lf < 0) ? -1 : 0)) +#endif + #ifdef REAL_ARITHMETIC #define ffetarget_add_complex1(res,l,r) \ ({ REAL_VALUE_TYPE lr, li, rr, ri, resr, resi; \ - lr = REAL_VALUE_FROM_TARGET_SINGLE ((l).real); \ - li = REAL_VALUE_FROM_TARGET_SINGLE ((l).imaginary); \ - rr = REAL_VALUE_FROM_TARGET_SINGLE ((r).real); \ - ri = REAL_VALUE_FROM_TARGET_SINGLE ((r).imaginary); \ + lr = ffetarget_cvt_r1_to_rv_ ((l).real); \ + li = ffetarget_cvt_r1_to_rv_ ((l).imaginary); \ + rr = ffetarget_cvt_r1_to_rv_ ((r).real); \ + ri = ffetarget_cvt_r1_to_rv_ ((r).imaginary); \ REAL_ARITHMETIC (resr, PLUS_EXPR, lr, rr); \ REAL_ARITHMETIC (resi, PLUS_EXPR, li, ri); \ - REAL_VALUE_TO_TARGET_SINGLE (resr, (res)->real); \ - REAL_VALUE_TO_TARGET_SINGLE (resi, (res)->imaginary); \ + ffetarget_cvt_rv_to_r1_ (resr, (res)->real); \ + ffetarget_cvt_rv_to_r1_ (resi, (res)->imaginary); \ FFEBAD; }) #define ffetarget_add_complex2(res,l,r) \ ({ REAL_VALUE_TYPE lr, li, rr, ri, resr, resi; \ - lr = REAL_VALUE_FROM_TARGET_DOUBLE (&((l).real.v[0])); \ - li = REAL_VALUE_FROM_TARGET_DOUBLE (&((l).imaginary.v[0])); \ - rr = REAL_VALUE_FROM_TARGET_DOUBLE (&((r).real.v[0])); \ - ri = REAL_VALUE_FROM_TARGET_DOUBLE (&((r).imaginary.v[0])); \ + lr = ffetarget_cvt_r2_to_rv_ (&((l).real.v[0])); \ + li = ffetarget_cvt_r2_to_rv_ (&((l).imaginary.v[0])); \ + rr = ffetarget_cvt_r2_to_rv_ (&((r).real.v[0])); \ + ri = ffetarget_cvt_r2_to_rv_ (&((r).imaginary.v[0])); \ REAL_ARITHMETIC (resr, PLUS_EXPR, lr, rr); \ REAL_ARITHMETIC (resi, PLUS_EXPR, li, ri); \ - REAL_VALUE_TO_TARGET_DOUBLE (resr, (long *) &((res)->real.v[0])); \ - REAL_VALUE_TO_TARGET_DOUBLE (resi, (long *) &((res)->imaginary.v[0])); \ + ffetarget_cvt_rv_to_r2_ (resr, &((res)->real.v[0])); \ + ffetarget_cvt_rv_to_r2_ (resi, &((res)->imaginary.v[0])); \ FFEBAD; }) #else #define ffetarget_add_complex1(res,l,r) \ @@ -865,17 +902,17 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len); #ifdef REAL_ARITHMETIC #define ffetarget_add_real1(res,l,r) \ ({ REAL_VALUE_TYPE lr, rr, resr; \ - lr = REAL_VALUE_FROM_TARGET_SINGLE ((l)); \ - rr = REAL_VALUE_FROM_TARGET_SINGLE ((r)); \ + lr = ffetarget_cvt_r1_to_rv_ ((l)); \ + rr = ffetarget_cvt_r1_to_rv_ ((r)); \ REAL_ARITHMETIC (resr, PLUS_EXPR, lr, rr); \ - REAL_VALUE_TO_TARGET_SINGLE (resr, *(res)); \ + ffetarget_cvt_rv_to_r1_ (resr, *(res)); \ FFEBAD; }) #define ffetarget_add_real2(res,l,r) \ ({ REAL_VALUE_TYPE lr, rr, resr; \ - lr = REAL_VALUE_FROM_TARGET_DOUBLE (&((l).v[0])); \ - rr = REAL_VALUE_FROM_TARGET_DOUBLE (&((r).v[0])); \ + lr = ffetarget_cvt_r2_to_rv_ (&((l).v[0])); \ + rr = ffetarget_cvt_r2_to_rv_ (&((r).v[0])); \ REAL_ARITHMETIC (resr, PLUS_EXPR, lr, rr); \ - REAL_VALUE_TO_TARGET_DOUBLE (resr, (long *) &((res)->v[0])); \ + ffetarget_cvt_rv_to_r2_ (resr, &((res)->v[0])); \ FFEBAD; }) #else #define ffetarget_add_real1(res,l,r) (*(res) = (l) + (r), FFEBAD) @@ -927,10 +964,10 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len); #ifdef REAL_ARITHMETIC #define ffetarget_convert_complex1_complex2(res,l) \ ({ REAL_VALUE_TYPE lr, li; \ - lr = REAL_VALUE_FROM_TARGET_DOUBLE (&((l).real.v[0])); \ - li = REAL_VALUE_FROM_TARGET_DOUBLE (&((l).imaginary.v[0])); \ - REAL_VALUE_TO_TARGET_SINGLE (lr, (res)->real); \ - REAL_VALUE_TO_TARGET_SINGLE (li, (res)->imaginary), \ + lr = ffetarget_cvt_r2_to_rv_ (&((l).real.v[0])); \ + li = ffetarget_cvt_r2_to_rv_ (&((l).imaginary.v[0])); \ + ffetarget_cvt_rv_to_r1_ (lr, (res)->real); \ + ffetarget_cvt_rv_to_r1_ (li, (res)->imaginary), \ FFEBAD; }) #else #define ffetarget_convert_complex1_complex2(res,l) \ @@ -940,10 +977,10 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len); #define ffetarget_convert_complex1_integer(res,l) \ ({ REAL_VALUE_TYPE resi, resr; \ ffetargetInteger1 lf = (l); \ - REAL_VALUE_FROM_INT (resr, (long) lf, (long) ((lf < 0) ? -1 : 0)); \ + FFETARGET_REAL_VALUE_FROM_INT_ (resr, lf, 1); \ resi = dconst0; \ - REAL_VALUE_TO_TARGET_SINGLE (resr, (res)->real); \ - REAL_VALUE_TO_TARGET_SINGLE (resi, (res)->imaginary); \ + ffetarget_cvt_rv_to_r1_ (resr, (res)->real); \ + ffetarget_cvt_rv_to_r1_ (resi, (res)->imaginary); \ FFEBAD; }) #else #define ffetarget_convert_complex1_integer(res,l) \ @@ -956,13 +993,13 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len); #ifdef REAL_ARITHMETIC #define ffetarget_convert_complex1_real1(res,l) \ ((res)->real = (l), \ - REAL_VALUE_TO_TARGET_SINGLE (dconst0, (res)->imaginary), \ + ffetarget_cvt_rv_to_r1_ (dconst0, (res)->imaginary), \ FFEBAD) #define ffetarget_convert_complex1_real2(res,l) \ ({ REAL_VALUE_TYPE lr; \ - lr = REAL_VALUE_FROM_TARGET_DOUBLE (&((l).v[0])); \ - REAL_VALUE_TO_TARGET_SINGLE (lr, (res)->real); \ - REAL_VALUE_TO_TARGET_SINGLE (dconst0, (res)->imaginary), \ + lr = ffetarget_cvt_r2_to_rv_ (&((l).v[0])); \ + ffetarget_cvt_rv_to_r1_ (lr, (res)->real); \ + ffetarget_cvt_rv_to_r1_ (dconst0, (res)->imaginary), \ FFEBAD; }) #else #define ffetarget_convert_complex1_real1(res,l) \ @@ -979,10 +1016,10 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len); #ifdef REAL_ARITHMETIC #define ffetarget_convert_complex2_complex1(res,l) \ ({ REAL_VALUE_TYPE lr, li; \ - lr = REAL_VALUE_FROM_TARGET_SINGLE ((l).real); \ - li = REAL_VALUE_FROM_TARGET_SINGLE ((l).imaginary); \ - REAL_VALUE_TO_TARGET_DOUBLE (lr, (long *) &((res)->real.v[0])); \ - REAL_VALUE_TO_TARGET_DOUBLE (li, (long *) &((res)->imaginary.v[0])), \ + lr = ffetarget_cvt_r1_to_rv_ ((l).real); \ + li = ffetarget_cvt_r1_to_rv_ ((l).imaginary); \ + ffetarget_cvt_rv_to_r2_ (lr, &((res)->real.v[0])); \ + ffetarget_cvt_rv_to_r2_ (li, &((res)->imaginary.v[0])), \ FFEBAD; }) #else #define ffetarget_convert_complex2_complex1(res,l) \ @@ -992,10 +1029,10 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len); #define ffetarget_convert_complex2_integer(res,l) \ ({ REAL_VALUE_TYPE resi, resr; \ ffetargetInteger1 lf = (l); \ - REAL_VALUE_FROM_INT (resr, (long) lf, (long) ((lf < 0) ? -1 : 0)); \ + FFETARGET_REAL_VALUE_FROM_INT_ (resr, lf, 2); \ resi = dconst0; \ - REAL_VALUE_TO_TARGET_DOUBLE (resr, (long *) &((res)->real.v[0])); \ - REAL_VALUE_TO_TARGET_DOUBLE (resi, (long *) &((res)->imaginary.v[0])); \ + ffetarget_cvt_rv_to_r2_ (resr, &((res)->real.v[0])); \ + ffetarget_cvt_rv_to_r2_ (resi, &((res)->imaginary.v[0])); \ FFEBAD; }) #else #define ffetarget_convert_complex2_integer(res,l) \ @@ -1008,13 +1045,13 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len); #ifdef REAL_ARITHMETIC #define ffetarget_convert_complex2_real1(res,l) \ ({ REAL_VALUE_TYPE lr; \ - lr = REAL_VALUE_FROM_TARGET_SINGLE (l); \ - REAL_VALUE_TO_TARGET_DOUBLE (lr, (long *) &((res)->real.v[0])); \ - REAL_VALUE_TO_TARGET_DOUBLE (dconst0, (long *) &((res)->imaginary.v[0])), \ + lr = ffetarget_cvt_r1_to_rv_ (l); \ + ffetarget_cvt_rv_to_r2_ (lr, &((res)->real.v[0])); \ + ffetarget_cvt_rv_to_r2_ (dconst0, &((res)->imaginary.v[0])), \ FFEBAD; }) #define ffetarget_convert_complex2_real2(res,l) \ ((res)->real = (l), \ - REAL_VALUE_TO_TARGET_DOUBLE (dconst0, (long *) &((res)->imaginary.v[0])), \ + ffetarget_cvt_rv_to_r2_ (dconst0, &((res)->imaginary.v[0])), \ FFEBAD) #else #define ffetarget_convert_complex2_real1(res,l) \ @@ -1165,25 +1202,25 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len); #ifdef REAL_ARITHMETIC #define ffetarget_convert_integer1_real1(res,l) \ ({ REAL_VALUE_TYPE lr; \ - lr = REAL_VALUE_FROM_TARGET_SINGLE (l); \ + lr = ffetarget_cvt_r1_to_rv_ (l); \ REAL_VALUE_TO_INT (&ffetarget_long_val_, &ffetarget_long_junk_, lr); \ *(res) = ffetarget_long_val_; \ FFEBAD; }) #define ffetarget_convert_integer1_real2(res,l) \ ({ REAL_VALUE_TYPE lr; \ - lr = REAL_VALUE_FROM_TARGET_DOUBLE (&((l).v[0])); \ + lr = ffetarget_cvt_r2_to_rv_ (&((l).v[0])); \ REAL_VALUE_TO_INT (&ffetarget_long_val_, &ffetarget_long_junk_, lr); \ *(res) = ffetarget_long_val_; \ FFEBAD; }) #define ffetarget_convert_integer1_complex1(res,l) \ ({ REAL_VALUE_TYPE lr; \ - lr = REAL_VALUE_FROM_TARGET_SINGLE ((l).real); \ + lr = ffetarget_cvt_r1_to_rv_ ((l).real); \ REAL_VALUE_TO_INT (&ffetarget_long_val_, &ffetarget_long_junk_, lr); \ *(res) = ffetarget_long_val_; \ FFEBAD; }) #define ffetarget_convert_integer1_complex2(res,l) \ ({ REAL_VALUE_TYPE lr; \ - lr = REAL_VALUE_FROM_TARGET_DOUBLE (&((l).real.v[0])); \ + lr = ffetarget_cvt_r2_to_rv_ (&((l).real.v[0])); \ REAL_VALUE_TO_INT (&ffetarget_long_val_, &ffetarget_long_junk_, lr); \ *(res) = ffetarget_long_val_; \ FFEBAD; }) @@ -1212,8 +1249,8 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len); #define ffetarget_convert_real1_integer1(res,l) \ ({ REAL_VALUE_TYPE resr; \ ffetargetInteger1 lf = (l); \ - REAL_VALUE_FROM_INT (resr, (long) lf, (long) ((lf < 0) ? -1 : 0)); \ - REAL_VALUE_TO_TARGET_SINGLE (resr, *(res)); \ + FFETARGET_REAL_VALUE_FROM_INT_ (resr, lf, 1); \ + ffetarget_cvt_rv_to_r1_ (resr, *(res)); \ FFEBAD; }) #else #define ffetarget_convert_real1_integer1(res,l) (*(res) = (l), FFEBAD) @@ -1221,8 +1258,8 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len); #ifdef REAL_ARITHMETIC #define ffetarget_convert_real1_real2(res,l) \ ({ REAL_VALUE_TYPE lr; \ - lr = REAL_VALUE_FROM_TARGET_DOUBLE (&((l).v[0])); \ - REAL_VALUE_TO_TARGET_SINGLE (lr, *(res)); \ + lr = ffetarget_cvt_r2_to_rv_ (&((l).v[0])); \ + ffetarget_cvt_rv_to_r1_ (lr, *(res)); \ FFEBAD; }) #else #define ffetarget_convert_real1_real2(res,l) (*(res) = (l), FFEBAD) @@ -1246,8 +1283,8 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len); #define ffetarget_convert_real2_integer(res,l) \ ({ REAL_VALUE_TYPE resr; \ ffetargetInteger1 lf = (l); \ - REAL_VALUE_FROM_INT (resr, (long) lf, (long) ((lf < 0) ? -1 : 0)); \ - REAL_VALUE_TO_TARGET_DOUBLE (resr, (long *) &((res)->v[0])); \ + FFETARGET_REAL_VALUE_FROM_INT_ (resr, lf, 2); \ + ffetarget_cvt_rv_to_r2_ (resr, &((res)->v[0])); \ FFEBAD; }) #define ffetarget_convert_real2_integer1 ffetarget_convert_real2_integer #else @@ -1256,8 +1293,8 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len); #ifdef REAL_ARITHMETIC #define ffetarget_convert_real2_real1(res,l) \ ({ REAL_VALUE_TYPE lr; \ - lr = REAL_VALUE_FROM_TARGET_SINGLE ((l)); \ - REAL_VALUE_TO_TARGET_DOUBLE (lr, (long *) &((res)->v[0])); \ + lr = ffetarget_cvt_r1_to_rv_ ((l)); \ + ffetarget_cvt_rv_to_r2_ (lr, &((res)->v[0])); \ FFEBAD; }) #else #define ffetarget_convert_real2_real1(res,l) (*(res) = (l), FFEBAD) @@ -1274,27 +1311,27 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len); #ifdef REAL_ARITHMETIC #define ffetarget_divide_real1(res,l,r) \ ({ REAL_VALUE_TYPE lr, rr, resr; \ - lr = REAL_VALUE_FROM_TARGET_SINGLE ((l)); \ - rr = REAL_VALUE_FROM_TARGET_SINGLE ((r)); \ + lr = ffetarget_cvt_r1_to_rv_ ((l)); \ + rr = ffetarget_cvt_r1_to_rv_ ((r)); \ REAL_VALUES_EQUAL (rr, dconst0) \ - ? ({ REAL_VALUE_TO_TARGET_SINGLE (dconst0, *(res)); \ + ? ({ ffetarget_cvt_rv_to_r1_ (dconst0, *(res)); \ FFEBAD_DIV_BY_ZERO; \ }) \ : ({ REAL_ARITHMETIC (resr, RDIV_EXPR, lr, rr); \ - REAL_VALUE_TO_TARGET_SINGLE (resr, *(res)); \ + ffetarget_cvt_rv_to_r1_ (resr, *(res)); \ FFEBAD; \ }); \ }) #define ffetarget_divide_real2(res,l,r) \ ({ REAL_VALUE_TYPE lr, rr, resr; \ - lr = REAL_VALUE_FROM_TARGET_DOUBLE (&((l).v[0])); \ - rr = REAL_VALUE_FROM_TARGET_DOUBLE (&((r).v[0])); \ + lr = ffetarget_cvt_r2_to_rv_ (&((l).v[0])); \ + rr = ffetarget_cvt_r2_to_rv_ (&((r).v[0])); \ REAL_VALUES_EQUAL (rr, dconst0) \ - ? ({ REAL_VALUE_TO_TARGET_DOUBLE (dconst0, (long *) &((res)->v[0])); \ + ? ({ ffetarget_cvt_rv_to_r2_ (dconst0, &((res)->v[0])); \ FFEBAD_DIV_BY_ZERO; \ }) \ : ({ REAL_ARITHMETIC (resr, RDIV_EXPR, lr, rr); \ - REAL_VALUE_TO_TARGET_DOUBLE (resr, (long *) &((res)->v[0])); \ + ffetarget_cvt_rv_to_r2_ (resr, &((res)->v[0])); \ FFEBAD; \ }); \ }) @@ -1309,19 +1346,19 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len); #ifdef REAL_ARITHMETIC #define ffetarget_eq_complex1(res,l,r) \ ({ REAL_VALUE_TYPE lr, li, rr, ri; \ - lr = REAL_VALUE_FROM_TARGET_SINGLE ((l).real); \ - li = REAL_VALUE_FROM_TARGET_SINGLE ((l).imaginary); \ - rr = REAL_VALUE_FROM_TARGET_SINGLE ((r).real); \ - ri = REAL_VALUE_FROM_TARGET_SINGLE ((r).imaginary); \ + lr = ffetarget_cvt_r1_to_rv_ ((l).real); \ + li = ffetarget_cvt_r1_to_rv_ ((l).imaginary); \ + rr = ffetarget_cvt_r1_to_rv_ ((r).real); \ + ri = ffetarget_cvt_r1_to_rv_ ((r).imaginary); \ *(res) = (REAL_VALUES_EQUAL (lr, rr) && REAL_VALUES_EQUAL (li, ri)) \ ? TRUE : FALSE; \ FFEBAD; }) #define ffetarget_eq_complex2(res,l,r) \ ({ REAL_VALUE_TYPE lr, li, rr, ri; \ - lr = REAL_VALUE_FROM_TARGET_DOUBLE (&((l).real.v[0])); \ - li = REAL_VALUE_FROM_TARGET_DOUBLE (&((l).imaginary.v[0])); \ - rr = REAL_VALUE_FROM_TARGET_DOUBLE (&((r).real.v[0])); \ - ri = REAL_VALUE_FROM_TARGET_DOUBLE (&((r).imaginary.v[0])); \ + lr = ffetarget_cvt_r2_to_rv_ (&((l).real.v[0])); \ + li = ffetarget_cvt_r2_to_rv_ (&((l).imaginary.v[0])); \ + rr = ffetarget_cvt_r2_to_rv_ (&((r).real.v[0])); \ + ri = ffetarget_cvt_r2_to_rv_ (&((r).imaginary.v[0])); \ *(res) = (REAL_VALUES_EQUAL (lr, rr) && REAL_VALUES_EQUAL (li, ri)) \ ? TRUE : FALSE; \ FFEBAD; }) @@ -1344,14 +1381,14 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len); #ifdef REAL_ARITHMETIC #define ffetarget_eq_real1(res,l,r) \ ({ REAL_VALUE_TYPE lr, rr; \ - lr = REAL_VALUE_FROM_TARGET_SINGLE ((l)); \ - rr = REAL_VALUE_FROM_TARGET_SINGLE ((r)); \ + lr = ffetarget_cvt_r1_to_rv_ ((l)); \ + rr = ffetarget_cvt_r1_to_rv_ ((r)); \ *(res) = REAL_VALUES_EQUAL (lr, rr) ? TRUE : FALSE; \ FFEBAD; }) #define ffetarget_eq_real2(res,l,r) \ ({ REAL_VALUE_TYPE lr, rr; \ - lr = REAL_VALUE_FROM_TARGET_DOUBLE (&((l).v[0])); \ - rr = REAL_VALUE_FROM_TARGET_DOUBLE (&((r).v[0])); \ + lr = ffetarget_cvt_r2_to_rv_ (&((l).v[0])); \ + rr = ffetarget_cvt_r2_to_rv_ (&((r).v[0])); \ *(res) = REAL_VALUES_EQUAL (lr, rr) ? TRUE : FALSE; \ FFEBAD; }) #else @@ -1379,14 +1416,14 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len); #ifdef REAL_ARITHMETIC #define ffetarget_ge_real1(res,l,r) \ ({ REAL_VALUE_TYPE lr, rr; \ - lr = REAL_VALUE_FROM_TARGET_SINGLE ((l)); \ - rr = REAL_VALUE_FROM_TARGET_SINGLE ((r)); \ + lr = ffetarget_cvt_r1_to_rv_ ((l)); \ + rr = ffetarget_cvt_r1_to_rv_ ((r)); \ *(res) = REAL_VALUES_LESS (lr, rr) ? FALSE : TRUE; \ FFEBAD; }) #define ffetarget_ge_real2(res,l,r) \ ({ REAL_VALUE_TYPE lr, rr; \ - lr = REAL_VALUE_FROM_TARGET_DOUBLE (&((l).v[0])); \ - rr = REAL_VALUE_FROM_TARGET_DOUBLE (&((r).v[0])); \ + lr = ffetarget_cvt_r2_to_rv_ (&((l).v[0])); \ + rr = ffetarget_cvt_r2_to_rv_ (&((r).v[0])); \ *(res) = REAL_VALUES_LESS (lr, rr) ? FALSE : TRUE; \ FFEBAD; }) #else @@ -1406,15 +1443,15 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len); #ifdef REAL_ARITHMETIC #define ffetarget_gt_real1(res,l,r) \ ({ REAL_VALUE_TYPE lr, rr; \ - lr = REAL_VALUE_FROM_TARGET_SINGLE ((l)); \ - rr = REAL_VALUE_FROM_TARGET_SINGLE ((r)); \ + lr = ffetarget_cvt_r1_to_rv_ ((l)); \ + rr = ffetarget_cvt_r1_to_rv_ ((r)); \ *(res) = (REAL_VALUES_LESS (lr, rr) || REAL_VALUES_EQUAL (lr, rr)) \ ? FALSE : TRUE; \ FFEBAD; }) #define ffetarget_gt_real2(res,l,r) \ ({ REAL_VALUE_TYPE lr, rr; \ - lr = REAL_VALUE_FROM_TARGET_DOUBLE (&((l).v[0])); \ - rr = REAL_VALUE_FROM_TARGET_DOUBLE (&((r).v[0])); \ + lr = ffetarget_cvt_r2_to_rv_ (&((l).v[0])); \ + rr = ffetarget_cvt_r2_to_rv_ (&((r).v[0])); \ *(res) = (REAL_VALUES_LESS (lr, rr) || REAL_VALUES_EQUAL (lr, rr)) \ ? FALSE : TRUE; \ FFEBAD; }) @@ -1433,17 +1470,22 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len); #define ffetarget_init_2() #define ffetarget_init_3() #define ffetarget_init_4() +#ifndef __alpha__ #define ffetarget_integerdefault_is_magical(i) \ (((unsigned long int) i) == FFETARGET_integerBIG_MAGICAL) +#else +#define ffetarget_integerdefault_is_magical(i) \ + (((unsigned int) i) == FFETARGET_integerBIG_MAGICAL) +#endif #ifdef REAL_ARITHMETIC #define ffetarget_iszero_real1(l) \ ({ REAL_VALUE_TYPE lr; \ - lr = REAL_VALUE_FROM_TARGET_SINGLE ((l)); \ + lr = ffetarget_cvt_r1_to_rv_ ((l)); \ REAL_VALUES_EQUAL (lr, dconst0); \ }) #define ffetarget_iszero_real2(l) \ ({ REAL_VALUE_TYPE lr; \ - lr = REAL_VALUE_FROM_TARGET_DOUBLE (&((l).v[0])); \ + lr = ffetarget_cvt_r2_to_rv_ (&((l).v[0])); \ REAL_VALUES_EQUAL (lr, dconst0); \ }) #else @@ -1463,15 +1505,15 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len); #ifdef REAL_ARITHMETIC #define ffetarget_le_real1(res,l,r) \ ({ REAL_VALUE_TYPE lr, rr; \ - lr = REAL_VALUE_FROM_TARGET_SINGLE ((l)); \ - rr = REAL_VALUE_FROM_TARGET_SINGLE ((r)); \ + lr = ffetarget_cvt_r1_to_rv_ ((l)); \ + rr = ffetarget_cvt_r1_to_rv_ ((r)); \ *(res) = (REAL_VALUES_LESS (lr, rr) || REAL_VALUES_EQUAL (lr, rr)) \ ? TRUE : FALSE; \ FFEBAD; }) #define ffetarget_le_real2(res,l,r) \ ({ REAL_VALUE_TYPE lr, rr; \ - lr = REAL_VALUE_FROM_TARGET_DOUBLE (&((l).v[0])); \ - rr = REAL_VALUE_FROM_TARGET_DOUBLE (&((r).v[0])); \ + lr = ffetarget_cvt_r2_to_rv_ (&((l).v[0])); \ + rr = ffetarget_cvt_r2_to_rv_ (&((r).v[0])); \ *(res) = (REAL_VALUES_LESS (lr, rr) || REAL_VALUES_EQUAL (lr, rr)) \ ? TRUE : FALSE; \ FFEBAD; }) @@ -1492,14 +1534,14 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len); #ifdef REAL_ARITHMETIC #define ffetarget_lt_real1(res,l,r) \ ({ REAL_VALUE_TYPE lr, rr; \ - lr = REAL_VALUE_FROM_TARGET_SINGLE ((l)); \ - rr = REAL_VALUE_FROM_TARGET_SINGLE ((r)); \ + lr = ffetarget_cvt_r1_to_rv_ ((l)); \ + rr = ffetarget_cvt_r1_to_rv_ ((r)); \ *(res) = REAL_VALUES_LESS (lr, rr) ? TRUE : FALSE; \ FFEBAD; }) #define ffetarget_lt_real2(res,l,r) \ ({ REAL_VALUE_TYPE lr, rr; \ - lr = REAL_VALUE_FROM_TARGET_DOUBLE (&((l).v[0])); \ - rr = REAL_VALUE_FROM_TARGET_DOUBLE (&((r).v[0])); \ + lr = ffetarget_cvt_r2_to_rv_ (&((l).v[0])); \ + rr = ffetarget_cvt_r2_to_rv_ (&((r).v[0])); \ *(res) = REAL_VALUES_LESS (lr, rr) ? TRUE : FALSE; \ FFEBAD; }) #else @@ -1512,9 +1554,9 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len); #define ffetarget_length_characterdefault ffetarget_length_character1 #ifdef REAL_ARITHMETIC #define ffetarget_make_real1(res,lr) \ - REAL_VALUE_TO_TARGET_SINGLE ((lr), *(res)) + ffetarget_cvt_rv_to_r1_ ((lr), *(res)) #define ffetarget_make_real2(res,lr) \ - REAL_VALUE_TO_TARGET_DOUBLE ((lr), (long *) &((res)->v[0])) + ffetarget_cvt_rv_to_r2_ ((lr), &((res)->v[0])) #else #define ffetarget_make_real1(res,lr) (*(res) = (lr)) #define ffetarget_make_real2(res,lr) (*(res) = (lr)) @@ -1526,17 +1568,17 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len); #ifdef REAL_ARITHMETIC #define ffetarget_multiply_real1(res,l,r) \ ({ REAL_VALUE_TYPE lr, rr, resr; \ - lr = REAL_VALUE_FROM_TARGET_SINGLE ((l)); \ - rr = REAL_VALUE_FROM_TARGET_SINGLE ((r)); \ + lr = ffetarget_cvt_r1_to_rv_ ((l)); \ + rr = ffetarget_cvt_r1_to_rv_ ((r)); \ REAL_ARITHMETIC (resr, MULT_EXPR, lr, rr); \ - REAL_VALUE_TO_TARGET_SINGLE (resr, *(res)); \ + ffetarget_cvt_rv_to_r1_ (resr, *(res)); \ FFEBAD; }) #define ffetarget_multiply_real2(res,l,r) \ ({ REAL_VALUE_TYPE lr, rr, resr; \ - lr = REAL_VALUE_FROM_TARGET_DOUBLE (&((l).v[0])); \ - rr = REAL_VALUE_FROM_TARGET_DOUBLE (&((r).v[0])); \ + lr = ffetarget_cvt_r2_to_rv_ (&((l).v[0])); \ + rr = ffetarget_cvt_r2_to_rv_ (&((r).v[0])); \ REAL_ARITHMETIC (resr, MULT_EXPR, lr, rr); \ - REAL_VALUE_TO_TARGET_DOUBLE (resr, (long *) &((res)->v[0])); \ + ffetarget_cvt_rv_to_r2_ (resr, &((res)->v[0])); \ FFEBAD; }) #else #define ffetarget_multiply_real1(res,l,r) (*(res) = (l) * (r), FFEBAD) @@ -1545,19 +1587,19 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len); #ifdef REAL_ARITHMETIC #define ffetarget_ne_complex1(res,l,r) \ ({ REAL_VALUE_TYPE lr, li, rr, ri; \ - lr = REAL_VALUE_FROM_TARGET_SINGLE ((l).real); \ - li = REAL_VALUE_FROM_TARGET_SINGLE ((l).imaginary); \ - rr = REAL_VALUE_FROM_TARGET_SINGLE ((r).real); \ - ri = REAL_VALUE_FROM_TARGET_SINGLE ((r).imaginary); \ + lr = ffetarget_cvt_r1_to_rv_ ((l).real); \ + li = ffetarget_cvt_r1_to_rv_ ((l).imaginary); \ + rr = ffetarget_cvt_r1_to_rv_ ((r).real); \ + ri = ffetarget_cvt_r1_to_rv_ ((r).imaginary); \ *(res) = (REAL_VALUES_EQUAL (lr, rr) && REAL_VALUES_EQUAL (li, ri)) \ ? FALSE : TRUE; \ FFEBAD; }) #define ffetarget_ne_complex2(res,l,r) \ ({ REAL_VALUE_TYPE lr, li, rr, ri; \ - lr = REAL_VALUE_FROM_TARGET_DOUBLE (&((l).real.v[0])); \ - li = REAL_VALUE_FROM_TARGET_DOUBLE (&((l).imaginary.v[0])); \ - rr = REAL_VALUE_FROM_TARGET_DOUBLE (&((r).real.v[0])); \ - ri = REAL_VALUE_FROM_TARGET_DOUBLE (&((r).imaginary.v[0])); \ + lr = ffetarget_cvt_r2_to_rv_ (&((l).real.v[0])); \ + li = ffetarget_cvt_r2_to_rv_ (&((l).imaginary.v[0])); \ + rr = ffetarget_cvt_r2_to_rv_ (&((r).real.v[0])); \ + ri = ffetarget_cvt_r2_to_rv_ (&((r).imaginary.v[0])); \ *(res) = (REAL_VALUES_EQUAL (lr, rr) && REAL_VALUES_EQUAL (li, ri)) \ ? FALSE : TRUE; \ FFEBAD; }) @@ -1580,14 +1622,14 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len); #ifdef REAL_ARITHMETIC #define ffetarget_ne_real1(res,l,r) \ ({ REAL_VALUE_TYPE lr, rr; \ - lr = REAL_VALUE_FROM_TARGET_SINGLE ((l)); \ - rr = REAL_VALUE_FROM_TARGET_SINGLE ((r)); \ + lr = ffetarget_cvt_r1_to_rv_ ((l)); \ + rr = ffetarget_cvt_r1_to_rv_ ((r)); \ *(res) = REAL_VALUES_EQUAL (lr, rr) ? FALSE : TRUE; \ FFEBAD; }) #define ffetarget_ne_real2(res,l,r) \ ({ REAL_VALUE_TYPE lr, rr; \ - lr = REAL_VALUE_FROM_TARGET_DOUBLE (&((l).v[0])); \ - rr = REAL_VALUE_FROM_TARGET_DOUBLE (&((r).v[0])); \ + lr = ffetarget_cvt_r2_to_rv_ (&((l).v[0])); \ + rr = ffetarget_cvt_r2_to_rv_ (&((r).v[0])); \ *(res) = REAL_VALUES_EQUAL (lr, rr) ? FALSE : TRUE; \ FFEBAD; }) #else @@ -1654,13 +1696,13 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len); #ifdef REAL_ARITHMETIC #define ffetarget_print_real1(f,l) \ ({ REAL_VALUE_TYPE lr; \ - lr = REAL_VALUE_FROM_TARGET_SINGLE ((l)); \ + lr = ffetarget_cvt_r1_to_rv_ ((l)); \ REAL_VALUE_TO_DECIMAL (lr, bad_fmt_val??, ffetarget_string_); \ fputs (ffetarget_string_, (f)); \ }) #define ffetarget_print_real2(f,l) \ ({ REAL_VALUE_TYPE lr; \ - lr = REAL_VALUE_FROM_TARGET_DOUBLE (&((l).v[0])); \ + lr = ffetarget_cvt_r2_to_rv_ (&((l).v[0])); \ REAL_VALUE_TO_DECIMAL (lr, bad_fmt_val??, ffetarget_string_); \ fputs (ffetarget_string_, (f)); \ }) @@ -1671,22 +1713,22 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len); fprintf ((f), "%" ffetargetReal2_f "g", (v)) #endif #ifdef REAL_ARITHMETIC -#define ffetarget_real1_one(res) REAL_VALUE_TO_TARGET_SINGLE (dconst1, *(res)) -#define ffetarget_real2_one(res) REAL_VALUE_TO_TARGET_DOUBLE (dconst1, (long *) &((res)->v[0])) +#define ffetarget_real1_one(res) ffetarget_cvt_rv_to_r1_ (dconst1, *(res)) +#define ffetarget_real2_one(res) ffetarget_cvt_rv_to_r2_ (dconst1, &((res)->v[0])) #else #define ffetarget_real1_one(res) (*(res) = (float) 1.) #define ffetarget_real2_one(res) (*(res) = 1.) #endif #ifdef REAL_ARITHMETIC -#define ffetarget_real1_two(res) REAL_VALUE_TO_TARGET_SINGLE (dconst2, *(res)) -#define ffetarget_real2_two(res) REAL_VALUE_TO_TARGET_DOUBLE (dconst2, (long *) &((res)->v[0])) +#define ffetarget_real1_two(res) ffetarget_cvt_rv_to_r1_ (dconst2, *(res)) +#define ffetarget_real2_two(res) ffetarget_cvt_rv_to_r2_ (dconst2, &((res)->v[0])) #else #define ffetarget_real1_two(res) (*(res) = (float) 2.) #define ffetarget_real2_two(res) (*(res) = 2.) #endif #ifdef REAL_ARITHMETIC -#define ffetarget_real1_zero(res) REAL_VALUE_TO_TARGET_SINGLE (dconst0, *(res)) -#define ffetarget_real2_zero(res) REAL_VALUE_TO_TARGET_DOUBLE (dconst0, (long *) &((res)->v[0])) +#define ffetarget_real1_zero(res) ffetarget_cvt_rv_to_r1_ (dconst0, *(res)) +#define ffetarget_real2_zero(res) ffetarget_cvt_rv_to_r2_ (dconst0, &((res)->v[0])) #else #define ffetarget_real1_zero(res) (*(res) = (float) 0.) #define ffetarget_real2_zero(res) (*(res) = 0.) @@ -1698,25 +1740,25 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len); #ifdef REAL_ARITHMETIC #define ffetarget_subtract_complex1(res,l,r) \ ({ REAL_VALUE_TYPE lr, li, rr, ri, resr, resi; \ - lr = REAL_VALUE_FROM_TARGET_SINGLE ((l).real); \ - li = REAL_VALUE_FROM_TARGET_SINGLE ((l).imaginary); \ - rr = REAL_VALUE_FROM_TARGET_SINGLE ((r).real); \ - ri = REAL_VALUE_FROM_TARGET_SINGLE ((r).imaginary); \ + lr = ffetarget_cvt_r1_to_rv_ ((l).real); \ + li = ffetarget_cvt_r1_to_rv_ ((l).imaginary); \ + rr = ffetarget_cvt_r1_to_rv_ ((r).real); \ + ri = ffetarget_cvt_r1_to_rv_ ((r).imaginary); \ REAL_ARITHMETIC (resr, MINUS_EXPR, lr, rr); \ REAL_ARITHMETIC (resi, MINUS_EXPR, li, ri); \ - REAL_VALUE_TO_TARGET_SINGLE (resr, (res)->real); \ - REAL_VALUE_TO_TARGET_SINGLE (resi, (res)->imaginary); \ + ffetarget_cvt_rv_to_r1_ (resr, (res)->real); \ + ffetarget_cvt_rv_to_r1_ (resi, (res)->imaginary); \ FFEBAD; }) #define ffetarget_subtract_complex2(res,l,r) \ ({ REAL_VALUE_TYPE lr, li, rr, ri, resr, resi; \ - lr = REAL_VALUE_FROM_TARGET_DOUBLE (&((l).real.v[0])); \ - li = REAL_VALUE_FROM_TARGET_DOUBLE (&((l).imaginary.v[0])); \ - rr = REAL_VALUE_FROM_TARGET_DOUBLE (&((r).real.v[0])); \ - ri = REAL_VALUE_FROM_TARGET_DOUBLE (&((r).imaginary.v[0])); \ + lr = ffetarget_cvt_r2_to_rv_ (&((l).real.v[0])); \ + li = ffetarget_cvt_r2_to_rv_ (&((l).imaginary.v[0])); \ + rr = ffetarget_cvt_r2_to_rv_ (&((r).real.v[0])); \ + ri = ffetarget_cvt_r2_to_rv_ (&((r).imaginary.v[0])); \ REAL_ARITHMETIC (resr, MINUS_EXPR, lr, rr); \ REAL_ARITHMETIC (resi, MINUS_EXPR, li, ri); \ - REAL_VALUE_TO_TARGET_DOUBLE (resr, (long *) &((res)->real.v[0])); \ - REAL_VALUE_TO_TARGET_DOUBLE (resi, (long *) &((res)->imaginary.v[0])); \ + ffetarget_cvt_rv_to_r2_ (resr, &((res)->real.v[0])); \ + ffetarget_cvt_rv_to_r2_ (resi, &((res)->imaginary.v[0])); \ FFEBAD; }) #else #define ffetarget_subtract_complex1(res,l,r) \ @@ -1733,17 +1775,17 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len); #ifdef REAL_ARITHMETIC #define ffetarget_subtract_real1(res,l,r) \ ({ REAL_VALUE_TYPE lr, rr, resr; \ - lr = REAL_VALUE_FROM_TARGET_SINGLE ((l)); \ - rr = REAL_VALUE_FROM_TARGET_SINGLE ((r)); \ + lr = ffetarget_cvt_r1_to_rv_ ((l)); \ + rr = ffetarget_cvt_r1_to_rv_ ((r)); \ REAL_ARITHMETIC (resr, MINUS_EXPR, lr, rr); \ - REAL_VALUE_TO_TARGET_SINGLE (resr, *(res)); \ + ffetarget_cvt_rv_to_r1_ (resr, *(res)); \ FFEBAD; }) #define ffetarget_subtract_real2(res,l,r) \ ({ REAL_VALUE_TYPE lr, rr, resr; \ - lr = REAL_VALUE_FROM_TARGET_DOUBLE (&((l).v[0])); \ - rr = REAL_VALUE_FROM_TARGET_DOUBLE (&((r).v[0])); \ + lr = ffetarget_cvt_r2_to_rv_ (&((l).v[0])); \ + rr = ffetarget_cvt_r2_to_rv_ (&((r).v[0])); \ REAL_ARITHMETIC (resr, MINUS_EXPR, lr, rr); \ - REAL_VALUE_TO_TARGET_DOUBLE (resr, (long *) &((res)->v[0])); \ + ffetarget_cvt_rv_to_r2_ (resr, &((res)->v[0])); \ FFEBAD; }) #else #define ffetarget_subtract_real1(res,l,r) (*(res) = (l) - (r), FFEBAD) @@ -1759,21 +1801,21 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len); #ifdef REAL_ARITHMETIC #define ffetarget_uminus_complex1(res,l) \ ({ REAL_VALUE_TYPE lr, li, resr, resi; \ - lr = REAL_VALUE_FROM_TARGET_SINGLE ((l).real); \ - li = REAL_VALUE_FROM_TARGET_SINGLE ((l).imaginary); \ + lr = ffetarget_cvt_r1_to_rv_ ((l).real); \ + li = ffetarget_cvt_r1_to_rv_ ((l).imaginary); \ resr = REAL_VALUE_NEGATE (lr); \ resi = REAL_VALUE_NEGATE (li); \ - REAL_VALUE_TO_TARGET_SINGLE (resr, (res)->real); \ - REAL_VALUE_TO_TARGET_SINGLE (resi, (res)->imaginary); \ + ffetarget_cvt_rv_to_r1_ (resr, (res)->real); \ + ffetarget_cvt_rv_to_r1_ (resi, (res)->imaginary); \ FFEBAD; }) #define ffetarget_uminus_complex2(res,l) \ ({ REAL_VALUE_TYPE lr, li, resr, resi; \ - lr = REAL_VALUE_FROM_TARGET_DOUBLE (&((l).real.v[0])); \ - li = REAL_VALUE_FROM_TARGET_DOUBLE (&((l).imaginary.v[0])); \ + lr = ffetarget_cvt_r2_to_rv_ (&((l).real.v[0])); \ + li = ffetarget_cvt_r2_to_rv_ (&((l).imaginary.v[0])); \ resr = REAL_VALUE_NEGATE (lr); \ resi = REAL_VALUE_NEGATE (li); \ - REAL_VALUE_TO_TARGET_DOUBLE (resr, (long *) &((res)->real.v[0])); \ - REAL_VALUE_TO_TARGET_DOUBLE (resi, (long *) &((res)->imaginary.v[0])); \ + ffetarget_cvt_rv_to_r2_ (resr, &((res)->real.v[0])); \ + ffetarget_cvt_rv_to_r2_ (resi, &((res)->imaginary.v[0])); \ FFEBAD; }) #else #define ffetarget_uminus_complex1(res,l) \ @@ -1788,23 +1830,23 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len); #ifdef REAL_ARITHMETIC #define ffetarget_uminus_real1(res,l) \ ({ REAL_VALUE_TYPE lr, resr; \ - lr = REAL_VALUE_FROM_TARGET_SINGLE ((l)); \ + lr = ffetarget_cvt_r1_to_rv_ ((l)); \ resr = REAL_VALUE_NEGATE (lr); \ - REAL_VALUE_TO_TARGET_SINGLE (resr, *(res)); \ + ffetarget_cvt_rv_to_r1_ (resr, *(res)); \ FFEBAD; }) #define ffetarget_uminus_real2(res,l) \ ({ REAL_VALUE_TYPE lr, resr; \ - lr = REAL_VALUE_FROM_TARGET_DOUBLE (&((l).v[0])); \ + lr = ffetarget_cvt_r2_to_rv_ (&((l).v[0])); \ resr = REAL_VALUE_NEGATE (lr); \ - REAL_VALUE_TO_TARGET_DOUBLE (resr, (long *) &((res)->v[0])); \ + ffetarget_cvt_rv_to_r2_ (resr, &((res)->v[0])); \ FFEBAD; }) #else #define ffetarget_uminus_real1(res,l) (*(res) = -(l), FFEBAD) #define ffetarget_uminus_real2(res,l) (*(res) = -(l), FFEBAD) #endif #ifdef REAL_ARITHMETIC -#define ffetarget_value_real1(lr) REAL_VALUE_FROM_TARGET_SINGLE ((lr)) -#define ffetarget_value_real2(lr) REAL_VALUE_FROM_TARGET_DOUBLE (&((lr).v[0])) +#define ffetarget_value_real1(lr) ffetarget_cvt_r1_to_rv_ ((lr)) +#define ffetarget_value_real2(lr) ffetarget_cvt_r2_to_rv_ (&((lr).v[0])) #else #define ffetarget_value_real1 #define ffetarget_value_real2 diff --git a/gnu/usr.bin/gcc/f/top.c b/gnu/usr.bin/gcc/f/top.c index 6599de944fc..1d22cc9add3 100644 --- a/gnu/usr.bin/gcc/f/top.c +++ b/gnu/usr.bin/gcc/f/top.c @@ -1,5 +1,5 @@ /* top.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995-1997 Free Software Foundation, Inc. Contributed by James Craig Burley (burley@gnu.ai.mit.edu). This file is part of GNU Fortran. @@ -65,6 +65,7 @@ bool ffe_is_do_internal_checks_ = TRUE; bool ffe_is_90_ = FFETARGET_defaultIS_90; bool ffe_is_automatic_ = FFETARGET_defaultIS_AUTOMATIC; bool ffe_is_backslash_ = FFETARGET_defaultIS_BACKSLASH; +bool ffe_is_emulate_complex_ = TRUE; bool ffe_is_underscoring_ = FFETARGET_defaultEXTERNAL_UNDERSCORED || FFETARGET_defaultUNDERSCORED_EXTERNAL_UNDERSCORED; bool ffe_is_second_underscore_ = FFETARGET_defaultUNDERSCORED_EXTERNAL_UNDERSCORED; @@ -80,16 +81,18 @@ bool ffe_is_mainprog_; /* TRUE if current prog unit known to be main. */ bool ffe_is_onetrip_ = FALSE; bool ffe_is_silent_ = TRUE; -bool ffe_is_typeless_boz_ = TRUE; /* Will become FALSE as of 0.5.20 or so. */ +bool ffe_is_typeless_boz_ = FALSE; bool ffe_is_pedantic_ = FFETARGET_defaultIS_PEDANTIC; bool ffe_is_saveall_; /* TRUE if mainprog or SAVE (no args) seen. */ bool ffe_is_ugly_args_ = TRUE; +bool ffe_is_ugly_assign_ = FALSE; /* Try and store pointer to ASSIGN labels in INTEGER vars. */ bool ffe_is_ugly_assumed_ = FALSE; /* DIMENSION X([...,]1) => DIMENSION X([...,]*) */ bool ffe_is_ugly_comma_ = FALSE; +bool ffe_is_ugly_complex_ = FALSE; bool ffe_is_ugly_init_ = TRUE; bool ffe_is_ugly_logint_ = FALSE; bool ffe_is_version_ = FALSE; -bool ffe_is_vxt_not_90_ = FFETARGET_defaultIS_VXT_NOT_90; +bool ffe_is_vxt_ = FALSE; bool ffe_is_warn_implicit_ = FALSE; bool ffe_is_warn_surprising_ = FALSE; bool ffe_is_zeros_ = FALSE; @@ -97,12 +100,12 @@ ffeCase ffe_case_intrin_ = FFETARGET_defaultCASE_INTRIN; ffeCase ffe_case_match_ = FFETARGET_defaultCASE_MATCH; ffeCase ffe_case_source_ = FFETARGET_defaultCASE_SOURCE; ffeCase ffe_case_symbol_ = FFETARGET_defaultCASE_SYMBOL; -ffeIntrinsicState ffe_intrinsic_state_dcp_ = FFETARGET_defaultSTATE_DCP; -ffeIntrinsicState ffe_intrinsic_state_f2c_ = FFETARGET_defaultSTATE_F2C; -ffeIntrinsicState ffe_intrinsic_state_f90_ = FFETARGET_defaultSTATE_F90; -ffeIntrinsicState ffe_intrinsic_state_mil_ = FFETARGET_defaultSTATE_MIL; -ffeIntrinsicState ffe_intrinsic_state_unix_ = FFETARGET_defaultSTATE_UNIX; -ffeIntrinsicState ffe_intrinsic_state_vxt_ = FFETARGET_defaultSTATE_VXT; +ffeIntrinsicState ffe_intrinsic_state_gnu_ = FFE_intrinsicstateENABLED; +ffeIntrinsicState ffe_intrinsic_state_f2c_ = FFE_intrinsicstateENABLED; +ffeIntrinsicState ffe_intrinsic_state_f90_ = FFE_intrinsicstateENABLED; +ffeIntrinsicState ffe_intrinsic_state_mil_ = FFE_intrinsicstateENABLED; +ffeIntrinsicState ffe_intrinsic_state_unix_ = FFE_intrinsicstateENABLED; +ffeIntrinsicState ffe_intrinsic_state_vxt_ = FFE_intrinsicstateENABLED; int ffe_fixed_line_length_ = FFETARGET_defaultFIXED_LINE_LENGTH; mallocPool ffe_file_pool_ = NULL; mallocPool ffe_any_unit_pool_ = NULL; @@ -172,6 +175,7 @@ ffe_decode_option (char *opt) flag_move_all_movables = 1; flag_reduce_all_givs = 1; flag_rerun_loop_opt = 1; + flag_argument_noalias = 2; #endif } else if (strcmp (&opt[2], "ident") == 0) @@ -229,23 +233,33 @@ ffe_decode_option (char *opt) ffe_set_is_pedantic (TRUE); else if (strcmp (&opt[2], "no-pedantic") == 0) ffe_set_is_pedantic (FALSE); + else if (strcmp (&opt[2], "vxt") == 0) + ffe_set_is_vxt (TRUE); + else if (strcmp (&opt[2], "not-vxt") == 0) + ffe_set_is_vxt (FALSE); else if (strcmp (&opt[2], "vxt-not-f90") == 0) - ffe_set_is_vxt_not_90 (TRUE); + warning ("%s no longer supported -- try -fvxt", opt); else if (strcmp (&opt[2], "f90-not-vxt") == 0) - ffe_set_is_vxt_not_90 (FALSE); + warning ("%s no longer supported -- try -fno-vxt -ff90", opt); else if (strcmp (&opt[2], "ugly") == 0) { + warning ("%s is overloaded with meanings and likely to be removed;", opt); + warning ("use only the specific -fugly-* options you need"); ffe_set_is_ugly_args (TRUE); + ffe_set_is_ugly_assign (TRUE); ffe_set_is_ugly_assumed (TRUE); ffe_set_is_ugly_comma (TRUE); + ffe_set_is_ugly_complex (TRUE); ffe_set_is_ugly_init (TRUE); ffe_set_is_ugly_logint (TRUE); } else if (strcmp (&opt[2], "no-ugly") == 0) { ffe_set_is_ugly_args (FALSE); + ffe_set_is_ugly_assign (FALSE); ffe_set_is_ugly_assumed (FALSE); ffe_set_is_ugly_comma (FALSE); + ffe_set_is_ugly_complex (FALSE); ffe_set_is_ugly_init (FALSE); ffe_set_is_ugly_logint (FALSE); } @@ -253,6 +267,10 @@ ffe_decode_option (char *opt) ffe_set_is_ugly_args (TRUE); else if (strcmp (&opt[2], "no-ugly-args") == 0) ffe_set_is_ugly_args (FALSE); + else if (strcmp (&opt[2], "ugly-assign") == 0) + ffe_set_is_ugly_assign (TRUE); + else if (strcmp (&opt[2], "no-ugly-assign") == 0) + ffe_set_is_ugly_assign (FALSE); else if (strcmp (&opt[2], "ugly-assumed") == 0) ffe_set_is_ugly_assumed (TRUE); else if (strcmp (&opt[2], "no-ugly-assumed") == 0) @@ -261,6 +279,10 @@ ffe_decode_option (char *opt) ffe_set_is_ugly_comma (TRUE); else if (strcmp (&opt[2], "no-ugly-comma") == 0) ffe_set_is_ugly_comma (FALSE); + else if (strcmp (&opt[2], "ugly-complex") == 0) + ffe_set_is_ugly_complex (TRUE); + else if (strcmp (&opt[2], "no-ugly-complex") == 0) + ffe_set_is_ugly_complex (FALSE); else if (strcmp (&opt[2], "ugly-init") == 0) ffe_set_is_ugly_init (TRUE); else if (strcmp (&opt[2], "no-ugly-init") == 0) @@ -277,6 +299,10 @@ ffe_decode_option (char *opt) ffe_set_is_init_local_zero (TRUE); else if (strcmp (&opt[2], "no-init-local-zero") == 0) ffe_set_is_init_local_zero (FALSE); + else if (strcmp (&opt[2], "emulate-complex") == 0) + ffe_set_is_emulate_complex (TRUE); + else if (strcmp (&opt[2], "no-emulate-complex") == 0) + ffe_set_is_emulate_complex (FALSE); else if (strcmp (&opt[2], "backslash") == 0) ffe_set_is_backslash (TRUE); else if (strcmp (&opt[2], "no-backslash") == 0) @@ -381,14 +407,14 @@ ffe_decode_option (char *opt) ffe_set_case_source (FFE_caseNONE); ffe_set_case_symbol (FFE_caseNONE); } - else if (strcmp (&opt[2], "dcp-intrinsics-delete") == 0) - ffe_set_intrinsic_state_dcp (FFE_intrinsicstateDELETED); - else if (strcmp (&opt[2], "dcp-intrinsics-hide") == 0) - ffe_set_intrinsic_state_dcp (FFE_intrinsicstateHIDDEN); - else if (strcmp (&opt[2], "dcp-intrinsics-disable") == 0) - ffe_set_intrinsic_state_dcp (FFE_intrinsicstateDISABLED); - else if (strcmp (&opt[2], "dcp-intrinsics-enable") == 0) - ffe_set_intrinsic_state_dcp (FFE_intrinsicstateENABLED); + else if (strcmp (&opt[2], "gnu-intrinsics-delete") == 0) + ffe_set_intrinsic_state_gnu (FFE_intrinsicstateDELETED); + else if (strcmp (&opt[2], "gnu-intrinsics-hide") == 0) + ffe_set_intrinsic_state_gnu (FFE_intrinsicstateHIDDEN); + else if (strcmp (&opt[2], "gnu-intrinsics-disable") == 0) + ffe_set_intrinsic_state_gnu (FFE_intrinsicstateDISABLED); + else if (strcmp (&opt[2], "gnu-intrinsics-enable") == 0) + ffe_set_intrinsic_state_gnu (FFE_intrinsicstateENABLED); else if (strcmp (&opt[2], "f2c-intrinsics-delete") == 0) ffe_set_intrinsic_state_f2c (FFE_intrinsicstateDELETED); else if (strcmp (&opt[2], "f2c-intrinsics-hide") == 0) diff --git a/gnu/usr.bin/gcc/f/top.h b/gnu/usr.bin/gcc/f/top.h index 99685932773..cc6d84bc8a3 100644 --- a/gnu/usr.bin/gcc/f/top.h +++ b/gnu/usr.bin/gcc/f/top.h @@ -1,5 +1,5 @@ /* top.h -- Public #include File (module.h template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995-1997 Free Software Foundation, Inc. Contributed by James Craig Burley (burley@gnu.ai.mit.edu). This file is part of GNU Fortran. @@ -82,6 +82,7 @@ extern bool ffe_is_do_internal_checks_; extern bool ffe_is_90_; extern bool ffe_is_automatic_; extern bool ffe_is_backslash_; +extern bool ffe_is_emulate_complex_; extern bool ffe_is_underscoring_; extern bool ffe_is_second_underscore_; extern bool ffe_is_debug_kludge_; @@ -99,12 +100,14 @@ extern bool ffe_is_typeless_boz_; extern bool ffe_is_pedantic_; extern bool ffe_is_saveall_; extern bool ffe_is_ugly_args_; +extern bool ffe_is_ugly_assign_; extern bool ffe_is_ugly_assumed_; extern bool ffe_is_ugly_comma_; +extern bool ffe_is_ugly_complex_; extern bool ffe_is_ugly_init_; extern bool ffe_is_ugly_logint_; extern bool ffe_is_version_; -extern bool ffe_is_vxt_not_90_; +extern bool ffe_is_vxt_; extern bool ffe_is_warn_implicit_; extern bool ffe_is_warn_surprising_; extern bool ffe_is_zeros_; @@ -112,7 +115,7 @@ extern ffeCase ffe_case_intrin_; extern ffeCase ffe_case_match_; extern ffeCase ffe_case_source_; extern ffeCase ffe_case_symbol_; -extern ffeIntrinsicState ffe_intrinsic_state_dcp_; +extern ffeIntrinsicState ffe_intrinsic_state_gnu_; extern ffeIntrinsicState ffe_intrinsic_state_f2c_; extern ffeIntrinsicState ffe_intrinsic_state_f90_; extern ffeIntrinsicState ffe_intrinsic_state_mil_; @@ -154,9 +157,9 @@ void ffe_terminate_4 (void); #define ffe_case_match() ffe_case_match_ #define ffe_case_source() ffe_case_source_ #define ffe_case_symbol() ffe_case_symbol_ -#define ffe_intrinsic_state_dcp() ffe_intrinsic_state_dcp_ #define ffe_intrinsic_state_f2c() ffe_intrinsic_state_f2c_ #define ffe_intrinsic_state_f90() ffe_intrinsic_state_f90_ +#define ffe_intrinsic_state_gnu() ffe_intrinsic_state_gnu_ #define ffe_intrinsic_state_mil() ffe_intrinsic_state_mil_ #define ffe_intrinsic_state_unix() ffe_intrinsic_state_unix_ #define ffe_intrinsic_state_vxt() ffe_intrinsic_state_vxt_ @@ -166,6 +169,7 @@ void ffe_terminate_4 (void); #define ffe_is_debug_kludge() ffe_is_debug_kludge_ #define ffe_is_do_internal_checks() ffe_is_do_internal_checks_ #define ffe_is_dollar_ok() ffe_is_dollar_ok_ +#define ffe_is_emulate_complex() ffe_is_emulate_complex_ #define ffe_is_f2c() ffe_is_f2c_ #define ffe_is_f2c_library() ffe_is_f2c_library_ #define ffe_is_ffedebug() ffe_is_ffedebug_ @@ -181,13 +185,15 @@ void ffe_terminate_4 (void); #define ffe_is_silent() ffe_is_silent_ #define ffe_is_typeless_boz() ffe_is_typeless_boz_ #define ffe_is_ugly_args() ffe_is_ugly_args_ +#define ffe_is_ugly_assign() ffe_is_ugly_assign_ #define ffe_is_ugly_assumed() ffe_is_ugly_assumed_ #define ffe_is_ugly_comma() ffe_is_ugly_comma_ +#define ffe_is_ugly_complex() ffe_is_ugly_complex_ #define ffe_is_ugly_init() ffe_is_ugly_init_ #define ffe_is_ugly_logint() ffe_is_ugly_logint_ #define ffe_is_underscoring() ffe_is_underscoring_ #define ffe_is_version() ffe_is_version_ -#define ffe_is_vxt_not_90() ffe_is_vxt_not_90_ +#define ffe_is_vxt() ffe_is_vxt_ #define ffe_is_warn_implicit() ffe_is_warn_implicit_ #define ffe_is_warn_surprising() ffe_is_warn_surprising_ #define ffe_is_zeros() ffe_is_zeros_ @@ -199,9 +205,9 @@ void ffe_terminate_4 (void); #define ffe_set_case_match(f) (ffe_case_match_ = (f)) #define ffe_set_case_source(f) (ffe_case_source_ = (f)) #define ffe_set_case_symbol(f) (ffe_case_symbol_ = (f)) -#define ffe_set_intrinsic_state_dcp(s) (ffe_intrinsic_state_dcp_ = (s)) #define ffe_set_intrinsic_state_f2c(s) (ffe_intrinsic_state_f2c_ = (s)) #define ffe_set_intrinsic_state_f90(s) (ffe_intrinsic_state_f90_ = (s)) +#define ffe_set_intrinsic_state_gnu(s) (ffe_intrinsic_state_gnu_ = (s)) #define ffe_set_intrinsic_state_mil(s) (ffe_intrinsic_state_mil_ = (s)) #define ffe_set_intrinsic_state_unix(s) (ffe_intrinsic_state_unix_ = (s)) #define ffe_set_intrinsic_state_vxt(s) (ffe_intrinsic_state_vxt_ = (s)) @@ -211,6 +217,7 @@ void ffe_terminate_4 (void); #define ffe_set_is_debug_kludge(f) (ffe_is_debug_kludge_ = (f)) #define ffe_set_is_do_internal_checks(f) (ffe_set_is_do_internal_checks_ = (f)) #define ffe_set_is_dollar_ok(f) (ffe_is_dollar_ok_ = (f)) +#define ffe_set_is_emulate_complex(f) (ffe_is_emulate_complex_ = (f)) #define ffe_set_is_f2c(f) (ffe_is_f2c_ = (f)) #define ffe_set_is_f2c_library(f) (ffe_is_f2c_library_ = (f)) #define ffe_set_is_ffedebug(f) (ffe_is_ffedebug_ = (f)) @@ -225,13 +232,15 @@ void ffe_terminate_4 (void); #define ffe_set_is_silent(f) (ffe_is_silent_ = (f)) #define ffe_set_is_typeless_boz(f) (ffe_is_typeless_boz_ = (f)) #define ffe_set_is_ugly_args(f) (ffe_is_ugly_args_ = (f)) +#define ffe_set_is_ugly_assign(f) (ffe_is_ugly_assign_ = (f)) #define ffe_set_is_ugly_assumed(f) (ffe_is_ugly_assumed_ = (f)) #define ffe_set_is_ugly_comma(f) (ffe_is_ugly_comma_ = (f)) +#define ffe_set_is_ugly_complex(f) (ffe_is_ugly_complex_ = (f)) #define ffe_set_is_ugly_init(f) (ffe_is_ugly_init_ = (f)) #define ffe_set_is_ugly_logint(f) (ffe_is_ugly_logint_ = (f)) #define ffe_set_is_underscoring(f) (ffe_is_underscoring_ = (f)) #define ffe_set_is_version(f) (ffe_is_version_ = (f)) -#define ffe_set_is_vxt_not_90(f) (ffe_is_vxt_not_90_ = (f)) +#define ffe_set_is_vxt(f) (ffe_is_vxt_ = (f)) #define ffe_set_is_warn_implicit(f) (ffe_is_warn_implicit_ = (f)) #define ffe_set_is_warn_surprising(f) (ffe_is_warn_surprising_ = (f)) #define ffe_set_is_zeros(f) (ffe_is_zeros_ = (f)) diff --git a/gnu/usr.bin/gcc/f/type.c b/gnu/usr.bin/gcc/f/type.c index cc15f8bfd33..48da8d785f6 100644 --- a/gnu/usr.bin/gcc/f/type.c +++ b/gnu/usr.bin/gcc/f/type.c @@ -37,7 +37,8 @@ ffetype_lookup_kind (ffetype base_type, int kind) return base_type->kinds_->type_[kind]; } -ffetype ffetype_lookup_star (ffetype base_type, int star) +ffetype +ffetype_lookup_star (ffetype base_type, int star) { if ((base_type->stars_ == NULL) || (star < 0) @@ -47,7 +48,8 @@ ffetype ffetype_lookup_star (ffetype base_type, int star) return base_type->stars_->type_[star]; } -ffetype ffetype_new (void) +ffetype +ffetype_new (void) { ffetype type; @@ -62,7 +64,8 @@ ffetype ffetype_new (void) return type; } -void ffetype_set_kind (ffetype base_type, int kind, ffetype type) +void +ffetype_set_kind (ffetype base_type, int kind, ffetype type) { if (base_type->kinds_ == NULL) { @@ -81,7 +84,8 @@ void ffetype_set_kind (ffetype base_type, int kind, ffetype type) base_type->kinds_->type_[kind] = type; } -void ffetype_set_star (ffetype base_type, int star, ffetype type) +void +ffetype_set_star (ffetype base_type, int star, ffetype type) { if (base_type->stars_ == NULL) { diff --git a/gnu/usr.bin/gcc/f/zzz.c b/gnu/usr.bin/gcc/f/zzz.c index 55ea8226c3f..29bc188c4f8 100644 --- a/gnu/usr.bin/gcc/f/zzz.c +++ b/gnu/usr.bin/gcc/f/zzz.c @@ -51,6 +51,6 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA #endif /* !defined (__TIME__) */ #endif /* !defined (FFEZZZ_TIME) */ -char *ffezzz_version_string = "0.5.19.1"; +char *ffezzz_version_string = "0.5.20"; char *ffezzz_date = FFEZZZ_DATE; char *ffezzz_time = FFEZZZ_TIME; diff --git a/gnu/usr.bin/gcc/flags.h b/gnu/usr.bin/gcc/flags.h index 4f35ee2c1da..a3845fa0acf 100644 --- a/gnu/usr.bin/gcc/flags.h +++ b/gnu/usr.bin/gcc/flags.h @@ -352,6 +352,19 @@ extern int flag_gnu_linker; /* Tag all structures with __attribute__(packed) */ extern int flag_pack_struct; + +/* 1 if alias checking is enabled: symbols do not alias each other + and parameters do not alias the current stack frame. */ +extern int flag_alias_check; + +/* This flag is only tested if alias checking is enabled. + 0 if pointer arguments may alias each other. True in C. + 1 if pointer arguments may not alias each other but may alias + global variables. + 2 if pointer arguments may not alias each other and may not + alias global variables. True in Fortran. + The value is ignored if flag_alias_check is 0. */ +extern int flag_argument_noalias; /* Other basic status info about current function. */ diff --git a/gnu/usr.bin/gcc/fold-const.c b/gnu/usr.bin/gcc/fold-const.c index cf57a37d606..e256259b76b 100644 --- a/gnu/usr.bin/gcc/fold-const.c +++ b/gnu/usr.bin/gcc/fold-const.c @@ -79,6 +79,7 @@ static tree range_test PROTO((enum tree_code, tree, enum tree_code, static tree unextend PROTO((tree, int, int, tree)); static tree fold_truthop PROTO((enum tree_code, tree, tree, tree)); static tree strip_compound_expr PROTO((tree, tree)); +static int multiple_of_p PROTO((tree, tree, tree)); #ifndef BRANCH_COST #define BRANCH_COST 1 @@ -3064,6 +3065,106 @@ strip_compound_expr (t, s) return t; } +/* Determine if first argument is a multiple of second argument. + Return 0 if it is not, or is not easily determined to so be. + + An example of the sort of thing we care about (at this point -- + this routine could surely be made more general, and expanded + to do what the *_DIV_EXPR's fold() cases do now) is discovering + that + + SAVE_EXPR (I) * SAVE_EXPR (J * 8) + + is a multiple of + + SAVE_EXPR (J * 8) + + when we know that the two `SAVE_EXPR (J * 8)' nodes are the + same node (which means they will have the same value at run + time, even though we don't know when they'll be assigned). + + This code also handles discovering that + + SAVE_EXPR (I) * SAVE_EXPR (J * 8) + + is a multiple of + + 8 + + (of course) so we don't have to worry about dealing with a + possible remainder. + + Note that we _look_ inside a SAVE_EXPR only to determine + how it was calculated; it is not safe for fold() to do much + of anything else with the internals of a SAVE_EXPR, since + fold() cannot know when it will be evaluated at run time. + For example, the latter example above _cannot_ be implemented + as + + SAVE_EXPR (I) * J + + or any variant thereof, since the value of J at evaluation time + of the original SAVE_EXPR is not necessarily the same at the time + the new expression is evaluated. The only optimization of this + sort that would be valid is changing + + SAVE_EXPR (I) * SAVE_EXPR (SAVE_EXPR (J) * 8) + divided by + 8 + + to + + SAVE_EXPR (I) * SAVE_EXPR (J) + + (where the same SAVE_EXPR (J) is used in the original and the + transformed version). */ + +static int +multiple_of_p (type, top, bottom) + tree type; + tree top; + tree bottom; +{ + if (operand_equal_p (top, bottom, 0)) + return 1; + + if (TREE_CODE (type) != INTEGER_TYPE) + return 0; + + switch (TREE_CODE (top)) + { + case MULT_EXPR: + return (multiple_of_p (type, TREE_OPERAND (top, 0), bottom) + || multiple_of_p (type, TREE_OPERAND (top, 1), bottom)); + + case PLUS_EXPR: + case MINUS_EXPR: + return (multiple_of_p (type, TREE_OPERAND (top, 0), bottom) + && multiple_of_p (type, TREE_OPERAND (top, 1), bottom)); + + case NOP_EXPR: + /* Punt if conversion from non-integral or wider integral type. */ + if ((TREE_CODE (TREE_TYPE (TREE_OPERAND (top, 0))) != INTEGER_TYPE) + || (TYPE_PRECISION (type) + < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (top, 0))))) + return 0; + /* Fall through. */ + case SAVE_EXPR: + return multiple_of_p (type, TREE_OPERAND (top, 0), bottom); + + case INTEGER_CST: + if ((TREE_CODE (bottom) != INTEGER_CST) + || (tree_int_cst_sgn (top) < 0) + || (tree_int_cst_sgn (bottom) < 0)) + return 0; + return integer_zerop (const_binop (TRUNC_MOD_EXPR, + top, bottom, 0)); + + default: + return 0; + } +} + /* Perform constant folding and related simplification of EXPR. The related simplifications include x*1 => x, x*0 => 0, etc., and application of the associative law. @@ -4009,6 +4110,13 @@ fold (expr) case ROUND_DIV_EXPR: case FLOOR_DIV_EXPR: case CEIL_DIV_EXPR: + if (integer_onep (arg1)) + return non_lvalue (convert (type, arg0)); + /* If arg0 is a multiple of arg1, then rewrite to the fastest div + operation, EXACT_DIV_EXPR. Otherwise, handle folding of + general divide. */ + if (multiple_of_p (type, arg0, arg1)) + return fold (build (EXACT_DIV_EXPR, type, arg0, arg1)); case EXACT_DIV_EXPR: if (integer_onep (arg1)) return non_lvalue (convert (type, arg0)); diff --git a/gnu/usr.bin/gcc/gcc.texi b/gnu/usr.bin/gcc/gcc.texi index bfcf1997090..7f80c69c31b 100644 --- a/gnu/usr.bin/gcc/gcc.texi +++ b/gnu/usr.bin/gcc/gcc.texi @@ -148,7 +148,7 @@ original English. @center Richard M. Stallman @sp 3 @center Last updated 29 June 1996 -@center (Revised for GNU Fortran 1996-03-06) +@center (Revised for GNU Fortran 1997-01-10) @sp 1 @c The version number appears twice more in this file. diff --git a/gnu/usr.bin/gcc/glimits.h b/gnu/usr.bin/gcc/glimits.h index ff25a97ace3..685772c8cad 100644 --- a/gnu/usr.bin/gcc/glimits.h +++ b/gnu/usr.bin/gcc/glimits.h @@ -63,7 +63,11 @@ /* Minimum and maximum values a `signed long int' can hold. (Same as `int'). */ #ifndef __LONG_MAX__ -#define __LONG_MAX__ 2147483647L +# ifndef __alpha__ +# define __LONG_MAX__ 2147483647L +# else +# define __LONG_MAX__ 9223372036854775807LL +# endif /* __alpha__ */ #endif #undef LONG_MIN #define LONG_MIN (-LONG_MAX-1) diff --git a/gnu/usr.bin/gcc/invoke.texi b/gnu/usr.bin/gcc/invoke.texi index bf2ee7956cc..b8dc858b99d 100644 --- a/gnu/usr.bin/gcc/invoke.texi +++ b/gnu/usr.bin/gcc/invoke.texi @@ -1,4 +1,4 @@ -@c Copyright (C) 1988, 89, 92, 93, 94, 1995 Free Software Foundation, Inc. +@c Copyright (C) 1988, 89, 92-95, 1997 Free Software Foundation, Inc. @c This is part of the GCC manual. @c For copying conditions, see the file gcc.texi. @@ -331,6 +331,8 @@ in addition to the above: -freg-struct-return -fshared-data -fshort-enums -fshort-double -fvolatile -fvolatile-global -fverbose-asm -fpack-struct +e0 +e1 +-fargument-alias -fargument-noalias +-fargument-noalias-global @end smallexample @end table @@ -1957,6 +1959,10 @@ optimizations triggered by this option, and the options as well, were contributed by Toon Moene (@code{toon@@moene.indiv.nluug.nl}). +These three options are intended to be removed someday, once +they have helped determine the efficacy of various +approaches to improving the performance of Fortran code. + Please let us (@code{fortran@@gnu.ai.mit.edu}) know how use of these options affects the performance of your production code. @@ -4270,6 +4276,78 @@ compilation). With @samp{+e1}, G++ actually generates the code implementing virtual functions defined in the code, and makes them publicly visible. + +@cindex aliasing of parameters +@cindex parameters, aliased +@item -fargument-alias +@item -fargument-noalias +@item -fargument-noalias-global +Specify the possible relationships among parameters and between +parameters and global data. + +@samp{-fargument-alias} specifies that arguments (parameters) may +alias each other and may alias global storage. +@samp{-fargument-noalias} specifies that arguments do not alias +each other, but may alias global storage. +@samp{-fargument-noalias-global} specifies that arguments do not +alias each other and do not alias global storage. + +For code written in C, C++, and Objective-C, @samp{-fargument-alias} +is the default. +For code written in Fortran, @samp{-fargument-noalias-global} is +the default, though this is pertinent only on systems where +@code{g77} is installed. +(See the documentation for other compilers for information on the +defaults for their respective languages.) + +Normally, @code{gcc} assumes that a write through a pointer +passed as a parameter to the current function might modify a +value pointed to by another pointer passed as a parameter, or +in global storage. + +For example, consider this code: + +@example +void x(int *i, int *j) +@{ + extern int k; + + ++*i; + ++*j; + ++k; +@} +@end example + +When compiling the above function, @code{gcc} assumes that @samp{i} might +be a pointer to the same variable as @samp{j}, and that either @samp{i}, +@samp{j}, or both might be a pointer to @samp{k}. + +Therefore, @code{gcc} does not assume it can generate code to read +@samp{*i}, @samp{*j}, and @samp{k} into separate registers, increment +each register, then write the incremented values back out. + +Instead, @code{gcc} must generate code that reads @samp{*i}, +increments it, and writes it back before reading @samp{*j}, +in case @samp{i} and @samp{j} are aliased, and, similarly, +that writes @samp{*j} before reading @samp{k}. +The result is code that, on many systems, takes longer to execute, +due to the way many processors schedule instruction execution. + +Compiling the above code with the @samp{-fargument-noalias} option +allows @code{gcc} to assume that @samp{i} and @samp{j} do not alias +each other, but either might alias @samp{k}. + +Compiling the above code with the @samp{-fargument-noalias-global} +option allows @code{gcc} to assume that no combination of @samp{i}, +@samp{j}, and @samp{k} are aliases for each other. + +@emph{Note:} Use the @samp{-fargument-noalias} and +@samp{-fargument-noalias-global} options with care. +While they can result in faster executables, they can +also result in executables with subtle bugs, bugs that +show up only when compiled for specific target systems, +or bugs that show up only when compiled by specific versions +of @code{g77}. @end table @node Environment Variables diff --git a/gnu/usr.bin/gcc/local-alloc.c b/gnu/usr.bin/gcc/local-alloc.c index 647b2d53304..800861d7ff2 100644 --- a/gnu/usr.bin/gcc/local-alloc.c +++ b/gnu/usr.bin/gcc/local-alloc.c @@ -544,7 +544,7 @@ validate_equiv_mem_from_store (dest, set) if ((GET_CODE (dest) == REG && reg_overlap_mentioned_p (dest, equiv_mem)) || (GET_CODE (dest) == MEM - && true_dependence (dest, equiv_mem))) + && true_dependence (dest, VOIDmode, equiv_mem, rtx_varies_p))) equiv_mem_modified = 1; } @@ -629,7 +629,7 @@ memref_referenced_p (memref, x) return 0; case MEM: - if (true_dependence (memref, x)) + if (true_dependence (memref, VOIDmode, x, rtx_varies_p)) return 1; break; diff --git a/gnu/usr.bin/gcc/loop.c b/gnu/usr.bin/gcc/loop.c index 3e780203977..5fb24ca016d 100644 --- a/gnu/usr.bin/gcc/loop.c +++ b/gnu/usr.bin/gcc/loop.c @@ -110,8 +110,7 @@ int *loop_number_exit_count; unsigned HOST_WIDE_INT loop_n_iterations; -/* Nonzero if there is a subroutine call in the current loop. - (unknown_address_altered is also nonzero in this case.) */ +/* Nonzero if there is a subroutine call in the current loop. */ static int loop_has_call; @@ -159,7 +158,7 @@ static char *moved_once; /* Array of MEMs that are stored in this loop. If there are too many to fit here, we just turn on unknown_address_altered. */ -#define NUM_STORES 20 +#define NUM_STORES 50 static rtx loop_store_mems[NUM_STORES]; /* Index of first available slot in above array. */ @@ -2199,7 +2198,8 @@ prescan_loop (start, end) } else if (GET_CODE (insn) == CALL_INSN) { - unknown_address_altered = 1; + if (! CONST_CALL_P (insn)) + unknown_address_altered = 1; loop_has_call = 1; } else @@ -2777,7 +2777,7 @@ invariant_p (x) /* See if there is any dependence between a store and this load. */ for (i = loop_store_mems_idx - 1; i >= 0; i--) - if (true_dependence (loop_store_mems[i], x)) + if (true_dependence (loop_store_mems[i], VOIDmode, x, rtx_varies_p)) return 0; /* It's not invalidated by a store in memory @@ -4375,6 +4375,8 @@ record_giv (v, insn, src_reg, dest_reg, mult_val, add_val, benefit, v->new_reg = 0; v->final_value = 0; v->same_insn = 0; + v->unrolled = 0; + v->shared = 0; /* The v->always_computable field is used in update_giv_derive, to determine whether a giv can be used to derive another giv. For a @@ -4652,8 +4654,11 @@ check_final_value (v, loop_start, loop_end) if (GET_CODE (p) == JUMP_INSN && JUMP_LABEL (p) && LABEL_NAME (JUMP_LABEL (p)) - && ((INSN_LUID (JUMP_LABEL (p)) < INSN_LUID (v->insn) - && INSN_LUID (JUMP_LABEL (p)) > INSN_LUID (loop_start)) + && ((INSN_UID (JUMP_LABEL (p)) >= max_uid_for_loop) + || (INSN_UID (v->insn) >= max_uid_for_loop) + || (INSN_UID (last_giv_use) >= max_uid_for_loop) + || (INSN_LUID (JUMP_LABEL (p)) < INSN_LUID (v->insn) + && INSN_LUID (JUMP_LABEL (p)) > INSN_LUID (loop_start)) || (INSN_LUID (JUMP_LABEL (p)) > INSN_LUID (last_giv_use) && INSN_LUID (JUMP_LABEL (p)) < INSN_LUID (loop_end)))) { @@ -5560,6 +5565,8 @@ emit_iv_add_mult (b, m, a, reg, insert_before) end_sequence (); emit_insn_before (seq, insert_before); + + record_base_value (REGNO (reg), b); } /* Test whether A * B can be computed without diff --git a/gnu/usr.bin/gcc/loop.h b/gnu/usr.bin/gcc/loop.h index 4c9c483e411..e83063a5ad2 100644 --- a/gnu/usr.bin/gcc/loop.h +++ b/gnu/usr.bin/gcc/loop.h @@ -88,6 +88,9 @@ struct induction unsigned maybe_dead : 1; /* 1 if this giv might be dead. In that case, we won't use it to eliminate a biv, it would probably lose. */ + unsigned unrolled : 1; /* 1 if new register has been allocated in + unrolled loop. */ + unsigned shared : 1; int lifetime; /* Length of life of this giv */ int times_used; /* # times this giv is used. */ rtx derive_adjustment; /* If nonzero, is an adjustment to be diff --git a/gnu/usr.bin/gcc/real.c b/gnu/usr.bin/gcc/real.c index 082cfd03af1..121a51d2609 100644 --- a/gnu/usr.bin/gcc/real.c +++ b/gnu/usr.bin/gcc/real.c @@ -5624,11 +5624,77 @@ make_nan (nan, sign, mode) *nan = (sign << 15) | *p; } -/* Convert an SFmode target `float' value to a REAL_VALUE_TYPE. - This is the inverse of the function `etarsingle' invoked by +/* This is the inverse of the function `etarsingle' invoked by REAL_VALUE_TO_TARGET_SINGLE. */ REAL_VALUE_TYPE +ereal_unto_float (f) + long f; +{ + REAL_VALUE_TYPE r; + unsigned EMUSHORT s[2]; + unsigned EMUSHORT e[NE]; + + /* Convert 32 bit integer to array of 16 bit pieces in target machine order. + This is the inverse operation to what the function `endian' does. */ + if (REAL_WORDS_BIG_ENDIAN) + { + s[0] = (unsigned EMUSHORT) (f >> 16); + s[1] = (unsigned EMUSHORT) f; + } + else + { + s[0] = (unsigned EMUSHORT) f; + s[1] = (unsigned EMUSHORT) (f >> 16); + } + /* Convert and promote the target float to E-type. */ + e24toe (s, e); + /* Output E-type to REAL_VALUE_TYPE. */ + PUT_REAL (e, &r); + return r; +} + + +/* This is the inverse of the function `etardouble' invoked by + REAL_VALUE_TO_TARGET_DOUBLE. */ + +REAL_VALUE_TYPE +ereal_unto_double (d) + long d[]; +{ + REAL_VALUE_TYPE r; + unsigned EMUSHORT s[4]; + unsigned EMUSHORT e[NE]; + + /* Convert array of HOST_WIDE_INT to equivalent array of 16-bit pieces. */ + if (REAL_WORDS_BIG_ENDIAN) + { + s[0] = (unsigned EMUSHORT) (d[0] >> 16); + s[1] = (unsigned EMUSHORT) d[0]; + s[2] = (unsigned EMUSHORT) (d[1] >> 16); + s[3] = (unsigned EMUSHORT) d[1]; + } + else + { + /* Target float words are little-endian. */ + s[0] = (unsigned EMUSHORT) d[0]; + s[1] = (unsigned EMUSHORT) (d[0] >> 16); + s[2] = (unsigned EMUSHORT) d[1]; + s[3] = (unsigned EMUSHORT) (d[1] >> 16); + } + /* Convert target double to E-type. */ + e53toe (s, e); + /* Output E-type to REAL_VALUE_TYPE. */ + PUT_REAL (e, &r); + return r; +} + + +/* Convert an SFmode target `float' value to a REAL_VALUE_TYPE. + This is somewhat like ereal_unto_float, but the input types + for these are different. */ + +REAL_VALUE_TYPE ereal_from_float (f) HOST_WIDE_INT f; { @@ -5657,8 +5723,8 @@ ereal_from_float (f) /* Convert a DFmode target `double' value to a REAL_VALUE_TYPE. - This is the inverse of the function `etardouble' invoked by - REAL_VALUE_TO_TARGET_DOUBLE. + This is somewhat like ereal_unto_double, but the input types + for these are different. The DFmode is stored as an array of HOST_WIDE_INT in the target's data format, with no holes in the bit packing. The first element diff --git a/gnu/usr.bin/gcc/real.h b/gnu/usr.bin/gcc/real.h index 799e158c95f..716c835ddb0 100644 --- a/gnu/usr.bin/gcc/real.h +++ b/gnu/usr.bin/gcc/real.h @@ -151,6 +151,8 @@ extern long etarsingle PROTO((REAL_VALUE_TYPE)); extern void ereal_to_decimal PROTO((REAL_VALUE_TYPE, char *)); extern int ereal_cmp PROTO((REAL_VALUE_TYPE, REAL_VALUE_TYPE)); extern int ereal_isneg PROTO((REAL_VALUE_TYPE)); +extern REAL_VALUE_TYPE ereal_unto_float PROTO((long)); +extern REAL_VALUE_TYPE ereal_unto_double PROTO((long *)); extern REAL_VALUE_TYPE ereal_from_float PROTO((HOST_WIDE_INT)); extern REAL_VALUE_TYPE ereal_from_double PROTO((HOST_WIDE_INT *)); @@ -197,6 +199,12 @@ extern REAL_VALUE_TYPE real_value_truncate (); /* IN is a REAL_VALUE_TYPE. OUT is a long. */ #define REAL_VALUE_TO_TARGET_SINGLE(IN, OUT) ((OUT) = etarsingle ((IN))) +/* Inverse of REAL_VALUE_TO_TARGET_DOUBLE. */ +#define REAL_VALUE_UNTO_TARGET_DOUBLE(d) (ereal_unto_double (d)) + +/* Inverse of REAL_VALUE_TO_TARGET_SINGLE. */ +#define REAL_VALUE_UNTO_TARGET_SINGLE(f) (ereal_unto_float (f)) + /* d is an array of HOST_WIDE_INT that holds a double precision value in the target computer's floating point format. */ #define REAL_VALUE_FROM_TARGET_DOUBLE(d) (ereal_from_double (d)) diff --git a/gnu/usr.bin/gcc/reload.c b/gnu/usr.bin/gcc/reload.c index d797e74df89..04bbe4af661 100644 --- a/gnu/usr.bin/gcc/reload.c +++ b/gnu/usr.bin/gcc/reload.c @@ -1,5 +1,5 @@ /* Search an insn for pseudo regs that must be in hard regs and are not. - Copyright (C) 1987, 88, 89, 92, 93, 94, 1995 Free Software Foundation, Inc. + Copyright (C) 1987, 88, 89, 92-5, 1996 Free Software Foundation, Inc. This file is part of GNU CC. @@ -291,6 +291,7 @@ static int output_reloadnum; static int push_secondary_reload PROTO((int, rtx, int, int, enum reg_class, enum machine_mode, enum reload_type, enum insn_code *)); +static enum reg_class find_valid_class PROTO((enum machine_mode, int)); static int push_reload PROTO((rtx, rtx, rtx *, rtx *, enum reg_class, enum machine_mode, enum machine_mode, int, int, int, enum reload_type)); @@ -360,6 +361,9 @@ push_secondary_reload (in_p, x, opnum, optional, reload_class, reload_mode, /* If X is a paradoxical SUBREG, use the inner value to determine both the mode and object being reloaded. */ if (GET_CODE (x) == SUBREG +#ifdef CLASS_CANNOT_CHANGE_SIZE + && reload_class != CLASS_CANNOT_CHANGE_SIZE +#endif && (GET_MODE_SIZE (GET_MODE (x)) > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))) { @@ -688,6 +692,38 @@ clear_secondary_mem () } #endif /* SECONDARY_MEMORY_NEEDED */ +/* Find the largest class for which every register number plus N is valid in + M1 (if in range). Abort if no such class exists. */ + +static enum reg_class +find_valid_class (m1, n) + enum machine_mode m1; + int n; +{ + int class; + int regno; + enum reg_class best_class; + int best_size = 0; + + for (class = 1; class < N_REG_CLASSES; class++) + { + int bad = 0; + for (regno = 0; regno < FIRST_PSEUDO_REGISTER && ! bad; regno++) + if (TEST_HARD_REG_BIT (reg_class_contents[class], regno) + && TEST_HARD_REG_BIT (reg_class_contents[class], regno + n) + && ! HARD_REGNO_MODE_OK (regno + n, m1)) + bad = 1; + + if (! bad && reg_class_size[class] > best_size) + best_class = class, best_size = reg_class_size[class]; + } + + if (best_size == 0) + abort (); + + return best_class; +} + /* Record one reload that needs to be performed. IN is an rtx saying where the data are to be found before this instruction. OUT says where they must be stored after the instruction. @@ -893,7 +929,8 @@ push_reload (in, out, inloc, outloc, class, if (in != 0 && GET_CODE (in) == SUBREG && GET_CODE (SUBREG_REG (in)) == REG && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER - && (! HARD_REGNO_MODE_OK (REGNO (SUBREG_REG (in)), inmode) + && (! HARD_REGNO_MODE_OK (REGNO (SUBREG_REG (in)) + SUBREG_WORD (in), + inmode) || (GET_MODE_SIZE (inmode) <= UNITS_PER_WORD && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))) > UNITS_PER_WORD) @@ -908,7 +945,8 @@ push_reload (in, out, inloc, outloc, class, RELOAD_OTHER, we are guaranteed that this inner reload will be output before the outer reload. */ push_reload (SUBREG_REG (in), NULL_RTX, &SUBREG_REG (in), NULL_PTR, - GENERAL_REGS, VOIDmode, VOIDmode, 0, 0, opnum, type); + find_valid_class (inmode, SUBREG_WORD (in)), + VOIDmode, VOIDmode, 0, 0, opnum, type); dont_remove_subreg = 1; } @@ -981,7 +1019,8 @@ push_reload (in, out, inloc, outloc, class, if (out != 0 && GET_CODE (out) == SUBREG && GET_CODE (SUBREG_REG (out)) == REG && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER - && (! HARD_REGNO_MODE_OK (REGNO (SUBREG_REG (out)), outmode) + && (! HARD_REGNO_MODE_OK (REGNO (SUBREG_REG (out)) + SUBREG_WORD (out), + outmode) || (GET_MODE_SIZE (outmode) <= UNITS_PER_WORD && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))) > UNITS_PER_WORD) @@ -997,7 +1036,9 @@ push_reload (in, out, inloc, outloc, class, output after the outer reload. */ dont_remove_subreg = 1; push_reload (SUBREG_REG (out), SUBREG_REG (out), &SUBREG_REG (out), - &SUBREG_REG (out), ALL_REGS, VOIDmode, VOIDmode, 0, 0, + &SUBREG_REG (out), + find_valid_class (outmode, SUBREG_WORD (out)), + VOIDmode, VOIDmode, 0, 0, opnum, RELOAD_OTHER); } @@ -5517,7 +5558,7 @@ find_equiv_reg (goal, insn, class, other, reload_reg_p, goalreg, mode) /* Reject VALUE if it was loaded from GOAL and is also a register that appears in the address of GOAL. */ - if (goal_mem && value == SET_DEST (PATTERN (where)) + if (goal_mem && value == SET_DEST (single_set (where)) && refers_to_regno_for_reload_p (valueno, (valueno + HARD_REGNO_NREGS (valueno, mode)), @@ -5899,7 +5940,7 @@ debug_reload() fprintf (stderr, ", inc by %d\n", reload_inc[r]); if (reload_nocombine[r]) - fprintf (stderr, ", can combine", reload_nocombine[r]); + fprintf (stderr, ", can't combine %d", reload_nocombine[r]); if (reload_secondary_p[r]) fprintf (stderr, ", secondary_reload_p"); diff --git a/gnu/usr.bin/gcc/rtl.h b/gnu/usr.bin/gcc/rtl.h index b757aec2750..079664cfb9a 100644 --- a/gnu/usr.bin/gcc/rtl.h +++ b/gnu/usr.bin/gcc/rtl.h @@ -348,7 +348,7 @@ enum reg_note { REG_DEAD = 1, REG_INC = 2, REG_EQUIV = 3, REG_WAS_0 = 4, REG_EQUAL = 5, REG_RETVAL = 6, REG_LIBCALL = 7, REG_NONNEG = 8, REG_NO_CONFLICT = 9, REG_UNUSED = 10, REG_CC_SETTER = 11, REG_CC_USER = 12, REG_LABEL = 13, - REG_DEP_ANTI = 14, REG_DEP_OUTPUT = 15 }; + REG_DEP_ANTI = 14, REG_DEP_OUTPUT = 15, REG_NOALIAS = 16 }; /* Define macros to extract and insert the reg-note kind in an EXPR_LIST. */ #define REG_NOTE_KIND(LINK) ((enum reg_note) GET_MODE (LINK)) @@ -431,7 +431,6 @@ extern char *reg_note_name[]; their homes, etc. */ #define NOTE_INSN_FUNCTION_BEG -13 - #if 0 /* These are not used, and I don't know what they were for. --rms. */ #define NOTE_DECL_NAME(INSN) ((INSN)->fld[3].rtstr) #define NOTE_DECL_CODE(INSN) ((INSN)->fld[4].rtint) @@ -575,6 +574,7 @@ extern char *note_insn_name[]; /* For a TRAP_IF rtx, TRAP_CONDITION is an expression. */ #define TRAP_CONDITION(RTX) ((RTX)->fld[0].rtx) +#define TRAP_CODE(RTX) ((RTX)->fld[1].rtint) /* 1 in a SYMBOL_REF if it addresses this function's constants pool. */ #define CONSTANT_POOL_ADDRESS_P(RTX) ((RTX)->unchanging) @@ -816,6 +816,16 @@ extern rtx gen_ble PROTO((rtx)); extern rtx eliminate_constant_term PROTO((rtx, rtx *)); extern rtx expand_complex_abs PROTO((enum machine_mode, rtx, rtx, int)); extern enum machine_mode choose_hard_reg_mode PROTO((int, int)); +extern int rtx_varies_p PROTO((rtx)); +extern int may_trap_p PROTO((rtx)); +extern int side_effects_p PROTO((rtx)); +extern int volatile_refs_p PROTO((rtx)); +extern int volatile_insn_p PROTO((rtx)); +extern void remove_note PROTO((rtx, rtx)); +extern void note_stores PROTO((rtx, void (*)())); +extern int refers_to_regno_p PROTO((int, int, rtx, rtx *)); +extern int reg_overlap_mentioned_p PROTO((rtx, rtx)); + /* Maximum number of parallel sets and clobbers in any insn in this fn. Always at least 3, since the combiner could put that many togetherm @@ -966,3 +976,10 @@ extern rtx *regno_reg_rtx; know what `enum tree_code' means. */ extern int rtx_to_tree_code PROTO((enum rtx_code)); + +extern int true_dependence PROTO((rtx, enum machine_mode, rtx, int (*)())); +extern int read_dependence PROTO((rtx, rtx)); +extern int anti_dependence PROTO((rtx, rtx)); +extern int output_dependence PROTO((rtx, rtx)); +extern void init_alias_analysis PROTO((void)); +extern void end_alias_analysis PROTO((void)); diff --git a/gnu/usr.bin/gcc/sched.c b/gnu/usr.bin/gcc/sched.c index 81d77bfd1bd..8533de1e035 100644 --- a/gnu/usr.bin/gcc/sched.c +++ b/gnu/usr.bin/gcc/sched.c @@ -125,6 +125,9 @@ Boston, MA 02111-1307, USA. */ #include "insn-config.h" #include "insn-attr.h" +extern char *reg_known_equiv_p; +extern rtx *reg_known_value; + #ifdef INSN_SCHEDULING /* Arrays set up by scheduling for the same respective purposes as similar-named arrays set up by flow analysis. We work with these @@ -142,6 +145,7 @@ static int *sched_reg_live_length; such insn. Needed for new registers which may be introduced by splitting insns. */ static rtx *reg_last_uses; +static int reg_last_uses_size; static rtx *reg_last_sets; static regset reg_pending_sets; static int reg_pending_sets_all; @@ -293,11 +297,6 @@ struct sometimes }; /* Forward declarations. */ -static rtx canon_rtx PROTO((rtx)); -static int rtx_equal_for_memref_p PROTO((rtx, rtx)); -static rtx find_symbolic_term PROTO((rtx)); -static int memrefs_conflict_p PROTO((int, rtx, int, rtx, - HOST_WIDE_INT)); static void add_dependence PROTO((rtx, rtx, enum reg_note)); static void remove_dependence PROTO((rtx, rtx)); static rtx find_insn_list PROTO((rtx, rtx)); @@ -345,542 +344,6 @@ void schedule_insns PROTO((FILE *)); #endif /* INSN_SCHEDULING */ -#define SIZE_FOR_MODE(X) (GET_MODE_SIZE (GET_MODE (X))) - -/* Vector indexed by N giving the initial (unchanging) value known - for pseudo-register N. */ -static rtx *reg_known_value; - -/* Vector recording for each reg_known_value whether it is due to a - REG_EQUIV note. Future passes (viz., reload) may replace the - pseudo with the equivalent expression and so we account for the - dependences that would be introduced if that happens. */ -/* ??? This is a problem only on the Convex. The REG_EQUIV notes created in - assign_parms mention the arg pointer, and there are explicit insns in the - RTL that modify the arg pointer. Thus we must ensure that such insns don't - get scheduled across each other because that would invalidate the REG_EQUIV - notes. One could argue that the REG_EQUIV notes are wrong, but solving - the problem in the scheduler will likely give better code, so we do it - here. */ -static char *reg_known_equiv_p; - -/* Indicates number of valid entries in reg_known_value. */ -static int reg_known_value_size; - -static rtx -canon_rtx (x) - rtx x; -{ - if (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER - && REGNO (x) <= reg_known_value_size) - return reg_known_value[REGNO (x)]; - else if (GET_CODE (x) == PLUS) - { - rtx x0 = canon_rtx (XEXP (x, 0)); - rtx x1 = canon_rtx (XEXP (x, 1)); - - if (x0 != XEXP (x, 0) || x1 != XEXP (x, 1)) - { - /* We can tolerate LO_SUMs being offset here; these - rtl are used for nothing other than comparisons. */ - if (GET_CODE (x0) == CONST_INT) - return plus_constant_for_output (x1, INTVAL (x0)); - else if (GET_CODE (x1) == CONST_INT) - return plus_constant_for_output (x0, INTVAL (x1)); - return gen_rtx (PLUS, GET_MODE (x), x0, x1); - } - } - return x; -} - -/* Set up all info needed to perform alias analysis on memory references. */ - -void -init_alias_analysis () -{ - int maxreg = max_reg_num (); - rtx insn; - rtx note; - rtx set; - - reg_known_value_size = maxreg; - - reg_known_value - = (rtx *) oballoc ((maxreg-FIRST_PSEUDO_REGISTER) * sizeof (rtx)) - - FIRST_PSEUDO_REGISTER; - bzero ((char *) (reg_known_value + FIRST_PSEUDO_REGISTER), - (maxreg-FIRST_PSEUDO_REGISTER) * sizeof (rtx)); - - reg_known_equiv_p - = (char *) oballoc ((maxreg -FIRST_PSEUDO_REGISTER) * sizeof (char)) - - FIRST_PSEUDO_REGISTER; - bzero (reg_known_equiv_p + FIRST_PSEUDO_REGISTER, - (maxreg - FIRST_PSEUDO_REGISTER) * sizeof (char)); - - /* Fill in the entries with known constant values. */ - for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) - if ((set = single_set (insn)) != 0 - && GET_CODE (SET_DEST (set)) == REG - && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER - && (((note = find_reg_note (insn, REG_EQUAL, 0)) != 0 - && reg_n_sets[REGNO (SET_DEST (set))] == 1) - || (note = find_reg_note (insn, REG_EQUIV, NULL_RTX)) != 0) - && GET_CODE (XEXP (note, 0)) != EXPR_LIST) - { - int regno = REGNO (SET_DEST (set)); - reg_known_value[regno] = XEXP (note, 0); - reg_known_equiv_p[regno] = REG_NOTE_KIND (note) == REG_EQUIV; - } - - /* Fill in the remaining entries. */ - while (--maxreg >= FIRST_PSEUDO_REGISTER) - if (reg_known_value[maxreg] == 0) - reg_known_value[maxreg] = regno_reg_rtx[maxreg]; -} - -/* Return 1 if X and Y are identical-looking rtx's. - - We use the data in reg_known_value above to see if two registers with - different numbers are, in fact, equivalent. */ - -static int -rtx_equal_for_memref_p (x, y) - rtx x, y; -{ - register int i; - register int j; - register enum rtx_code code; - register char *fmt; - - if (x == 0 && y == 0) - return 1; - if (x == 0 || y == 0) - return 0; - x = canon_rtx (x); - y = canon_rtx (y); - - if (x == y) - return 1; - - code = GET_CODE (x); - /* Rtx's of different codes cannot be equal. */ - if (code != GET_CODE (y)) - return 0; - - /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent. - (REG:SI x) and (REG:HI x) are NOT equivalent. */ - - if (GET_MODE (x) != GET_MODE (y)) - return 0; - - /* REG, LABEL_REF, and SYMBOL_REF can be compared nonrecursively. */ - - if (code == REG) - return REGNO (x) == REGNO (y); - if (code == LABEL_REF) - return XEXP (x, 0) == XEXP (y, 0); - if (code == SYMBOL_REF) - return XSTR (x, 0) == XSTR (y, 0); - - /* For commutative operations, the RTX match if the operand match in any - order. Also handle the simple binary and unary cases without a loop. */ - if (code == EQ || code == NE || GET_RTX_CLASS (code) == 'c') - return ((rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 0)) - && rtx_equal_for_memref_p (XEXP (x, 1), XEXP (y, 1))) - || (rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 1)) - && rtx_equal_for_memref_p (XEXP (x, 1), XEXP (y, 0)))); - else if (GET_RTX_CLASS (code) == '<' || GET_RTX_CLASS (code) == '2') - return (rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 0)) - && rtx_equal_for_memref_p (XEXP (x, 1), XEXP (y, 1))); - else if (GET_RTX_CLASS (code) == '1') - return rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 0)); - - /* Compare the elements. If any pair of corresponding elements - fail to match, return 0 for the whole things. */ - - fmt = GET_RTX_FORMAT (code); - for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) - { - switch (fmt[i]) - { - case 'w': - if (XWINT (x, i) != XWINT (y, i)) - return 0; - break; - - case 'n': - case 'i': - if (XINT (x, i) != XINT (y, i)) - return 0; - break; - - case 'V': - case 'E': - /* Two vectors must have the same length. */ - if (XVECLEN (x, i) != XVECLEN (y, i)) - return 0; - - /* And the corresponding elements must match. */ - for (j = 0; j < XVECLEN (x, i); j++) - if (rtx_equal_for_memref_p (XVECEXP (x, i, j), XVECEXP (y, i, j)) == 0) - return 0; - break; - - case 'e': - if (rtx_equal_for_memref_p (XEXP (x, i), XEXP (y, i)) == 0) - return 0; - break; - - case 'S': - case 's': - if (strcmp (XSTR (x, i), XSTR (y, i))) - return 0; - break; - - case 'u': - /* These are just backpointers, so they don't matter. */ - break; - - case '0': - break; - - /* It is believed that rtx's at this level will never - contain anything but integers and other rtx's, - except for within LABEL_REFs and SYMBOL_REFs. */ - default: - abort (); - } - } - return 1; -} - -/* Given an rtx X, find a SYMBOL_REF or LABEL_REF within - X and return it, or return 0 if none found. */ - -static rtx -find_symbolic_term (x) - rtx x; -{ - register int i; - register enum rtx_code code; - register char *fmt; - - code = GET_CODE (x); - if (code == SYMBOL_REF || code == LABEL_REF) - return x; - if (GET_RTX_CLASS (code) == 'o') - return 0; - - fmt = GET_RTX_FORMAT (code); - for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) - { - rtx t; - - if (fmt[i] == 'e') - { - t = find_symbolic_term (XEXP (x, i)); - if (t != 0) - return t; - } - else if (fmt[i] == 'E') - break; - } - return 0; -} - -/* Return nonzero if X and Y (memory addresses) could reference the - same location in memory. C is an offset accumulator. When - C is nonzero, we are testing aliases between X and Y + C. - XSIZE is the size in bytes of the X reference, - similarly YSIZE is the size in bytes for Y. - - If XSIZE or YSIZE is zero, we do not know the amount of memory being - referenced (the reference was BLKmode), so make the most pessimistic - assumptions. - - We recognize the following cases of non-conflicting memory: - - (1) addresses involving the frame pointer cannot conflict - with addresses involving static variables. - (2) static variables with different addresses cannot conflict. - - Nice to notice that varying addresses cannot conflict with fp if no - local variables had their addresses taken, but that's too hard now. */ - -/* ??? In Fortran, references to a array parameter can never conflict with - another array parameter. */ - -static int -memrefs_conflict_p (xsize, x, ysize, y, c) - rtx x, y; - int xsize, ysize; - HOST_WIDE_INT c; -{ - if (GET_CODE (x) == HIGH) - x = XEXP (x, 0); - else if (GET_CODE (x) == LO_SUM) - x = XEXP (x, 1); - else - x = canon_rtx (x); - if (GET_CODE (y) == HIGH) - y = XEXP (y, 0); - else if (GET_CODE (y) == LO_SUM) - y = XEXP (y, 1); - else - y = canon_rtx (y); - - if (rtx_equal_for_memref_p (x, y)) - return (xsize == 0 || ysize == 0 || - (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0)); - - if (y == frame_pointer_rtx || y == hard_frame_pointer_rtx - || y == stack_pointer_rtx) - { - rtx t = y; - int tsize = ysize; - y = x; ysize = xsize; - x = t; xsize = tsize; - } - - if (x == frame_pointer_rtx || x == hard_frame_pointer_rtx - || x == stack_pointer_rtx) - { - rtx y1; - - if (CONSTANT_P (y)) - return 0; - - if (GET_CODE (y) == PLUS - && canon_rtx (XEXP (y, 0)) == x - && (y1 = canon_rtx (XEXP (y, 1))) - && GET_CODE (y1) == CONST_INT) - { - c += INTVAL (y1); - return (xsize == 0 || ysize == 0 - || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0)); - } - - if (GET_CODE (y) == PLUS - && (y1 = canon_rtx (XEXP (y, 0))) - && CONSTANT_P (y1)) - return 0; - - return 1; - } - - if (GET_CODE (x) == PLUS) - { - /* The fact that X is canonicalized means that this - PLUS rtx is canonicalized. */ - rtx x0 = XEXP (x, 0); - rtx x1 = XEXP (x, 1); - - if (GET_CODE (y) == PLUS) - { - /* The fact that Y is canonicalized means that this - PLUS rtx is canonicalized. */ - rtx y0 = XEXP (y, 0); - rtx y1 = XEXP (y, 1); - - if (rtx_equal_for_memref_p (x1, y1)) - return memrefs_conflict_p (xsize, x0, ysize, y0, c); - if (rtx_equal_for_memref_p (x0, y0)) - return memrefs_conflict_p (xsize, x1, ysize, y1, c); - if (GET_CODE (x1) == CONST_INT) - if (GET_CODE (y1) == CONST_INT) - return memrefs_conflict_p (xsize, x0, ysize, y0, - c - INTVAL (x1) + INTVAL (y1)); - else - return memrefs_conflict_p (xsize, x0, ysize, y, c - INTVAL (x1)); - else if (GET_CODE (y1) == CONST_INT) - return memrefs_conflict_p (xsize, x, ysize, y0, c + INTVAL (y1)); - - /* Handle case where we cannot understand iteration operators, - but we notice that the base addresses are distinct objects. */ - x = find_symbolic_term (x); - if (x == 0) - return 1; - y = find_symbolic_term (y); - if (y == 0) - return 1; - return rtx_equal_for_memref_p (x, y); - } - else if (GET_CODE (x1) == CONST_INT) - return memrefs_conflict_p (xsize, x0, ysize, y, c - INTVAL (x1)); - } - else if (GET_CODE (y) == PLUS) - { - /* The fact that Y is canonicalized means that this - PLUS rtx is canonicalized. */ - rtx y0 = XEXP (y, 0); - rtx y1 = XEXP (y, 1); - - if (GET_CODE (y1) == CONST_INT) - return memrefs_conflict_p (xsize, x, ysize, y0, c + INTVAL (y1)); - else - return 1; - } - - if (GET_CODE (x) == GET_CODE (y)) - switch (GET_CODE (x)) - { - case MULT: - { - /* Handle cases where we expect the second operands to be the - same, and check only whether the first operand would conflict - or not. */ - rtx x0, y0; - rtx x1 = canon_rtx (XEXP (x, 1)); - rtx y1 = canon_rtx (XEXP (y, 1)); - if (! rtx_equal_for_memref_p (x1, y1)) - return 1; - x0 = canon_rtx (XEXP (x, 0)); - y0 = canon_rtx (XEXP (y, 0)); - if (rtx_equal_for_memref_p (x0, y0)) - return (xsize == 0 || ysize == 0 - || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0)); - - /* Can't properly adjust our sizes. */ - if (GET_CODE (x1) != CONST_INT) - return 1; - xsize /= INTVAL (x1); - ysize /= INTVAL (x1); - c /= INTVAL (x1); - return memrefs_conflict_p (xsize, x0, ysize, y0, c); - } - } - - if (CONSTANT_P (x)) - { - if (GET_CODE (x) == CONST_INT && GET_CODE (y) == CONST_INT) - { - c += (INTVAL (y) - INTVAL (x)); - return (xsize == 0 || ysize == 0 - || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0)); - } - - if (GET_CODE (x) == CONST) - { - if (GET_CODE (y) == CONST) - return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)), - ysize, canon_rtx (XEXP (y, 0)), c); - else - return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)), - ysize, y, c); - } - if (GET_CODE (y) == CONST) - return memrefs_conflict_p (xsize, x, ysize, - canon_rtx (XEXP (y, 0)), c); - - if (CONSTANT_P (y)) - return (rtx_equal_for_memref_p (x, y) - && (xsize == 0 || ysize == 0 - || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0))); - - return 1; - } - return 1; -} - -/* Functions to compute memory dependencies. - - Since we process the insns in execution order, we can build tables - to keep track of what registers are fixed (and not aliased), what registers - are varying in known ways, and what registers are varying in unknown - ways. - - If both memory references are volatile, then there must always be a - dependence between the two references, since their order can not be - changed. A volatile and non-volatile reference can be interchanged - though. - - A MEM_IN_STRUCT reference at a non-QImode varying address can never - conflict with a non-MEM_IN_STRUCT reference at a fixed address. We must - allow QImode aliasing because the ANSI C standard allows character - pointers to alias anything. We are assuming that characters are - always QImode here. */ - -/* Read dependence: X is read after read in MEM takes place. There can - only be a dependence here if both reads are volatile. */ - -int -read_dependence (mem, x) - rtx mem; - rtx x; -{ - return MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem); -} - -/* True dependence: X is read after store in MEM takes place. */ - -int -true_dependence (mem, x) - rtx mem; - rtx x; -{ - /* If X is an unchanging read, then it can't possibly conflict with any - non-unchanging store. It may conflict with an unchanging write though, - because there may be a single store to this address to initialize it. - Just fall through to the code below to resolve the case where we have - both an unchanging read and an unchanging write. This won't handle all - cases optimally, but the possible performance loss should be - negligible. */ - if (RTX_UNCHANGING_P (x) && ! RTX_UNCHANGING_P (mem)) - return 0; - - return ((MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem)) - || (memrefs_conflict_p (SIZE_FOR_MODE (mem), XEXP (mem, 0), - SIZE_FOR_MODE (x), XEXP (x, 0), 0) - && ! (MEM_IN_STRUCT_P (mem) && rtx_addr_varies_p (mem) - && GET_MODE (mem) != QImode - && ! MEM_IN_STRUCT_P (x) && ! rtx_addr_varies_p (x)) - && ! (MEM_IN_STRUCT_P (x) && rtx_addr_varies_p (x) - && GET_MODE (x) != QImode - && ! MEM_IN_STRUCT_P (mem) && ! rtx_addr_varies_p (mem)))); -} - -/* Anti dependence: X is written after read in MEM takes place. */ - -int -anti_dependence (mem, x) - rtx mem; - rtx x; -{ - /* If MEM is an unchanging read, then it can't possibly conflict with - the store to X, because there is at most one store to MEM, and it must - have occurred somewhere before MEM. */ - if (RTX_UNCHANGING_P (mem)) - return 0; - - return ((MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem)) - || (memrefs_conflict_p (SIZE_FOR_MODE (mem), XEXP (mem, 0), - SIZE_FOR_MODE (x), XEXP (x, 0), 0) - && ! (MEM_IN_STRUCT_P (mem) && rtx_addr_varies_p (mem) - && GET_MODE (mem) != QImode - && ! MEM_IN_STRUCT_P (x) && ! rtx_addr_varies_p (x)) - && ! (MEM_IN_STRUCT_P (x) && rtx_addr_varies_p (x) - && GET_MODE (x) != QImode - && ! MEM_IN_STRUCT_P (mem) && ! rtx_addr_varies_p (mem)))); -} - -/* Output dependence: X is written after store in MEM takes place. */ - -int -output_dependence (mem, x) - rtx mem; - rtx x; -{ - return ((MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem)) - || (memrefs_conflict_p (SIZE_FOR_MODE (mem), XEXP (mem, 0), - SIZE_FOR_MODE (x), XEXP (x, 0), 0) - && ! (MEM_IN_STRUCT_P (mem) && rtx_addr_varies_p (mem) - && GET_MODE (mem) != QImode - && ! MEM_IN_STRUCT_P (x) && ! rtx_addr_varies_p (x)) - && ! (MEM_IN_STRUCT_P (x) && rtx_addr_varies_p (x) - && GET_MODE (x) != QImode - && ! MEM_IN_STRUCT_P (mem) && ! rtx_addr_varies_p (mem)))); -} - /* Helper functions for instruction scheduling. */ /* Add ELEM wrapped in an INSN_LIST with reg note kind DEP_TYPE to the @@ -1921,7 +1384,8 @@ sched_analyze_2 (x, insn) { /* If a dependency already exists, don't create a new one. */ if (! find_insn_list (XEXP (pending, 0), LOG_LINKS (insn))) - if (true_dependence (XEXP (pending_mem, 0), x)) + if (true_dependence (XEXP (pending_mem, 0), VOIDmode, + x, rtx_varies_p)) add_dependence (insn, XEXP (pending, 0), 0); pending = XEXP (pending, 1); @@ -2020,7 +1484,7 @@ sched_analyze_insn (x, insn, loop_notes) { register RTX_CODE code = GET_CODE (x); rtx link; - int maxreg = max_reg_num (); + int maxreg = reg_last_uses_size; int i; if (code == SET || code == CLOBBER) @@ -2057,7 +1521,7 @@ sched_analyze_insn (x, insn, loop_notes) if (loop_notes) { - int max_reg = max_reg_num (); + int max_reg = reg_last_uses_size; rtx link; for (i = 0; i < max_reg; i++) @@ -2201,8 +1665,7 @@ sched_analyze (head, tail) if (NEXT_INSN (insn) && GET_CODE (NEXT_INSN (insn)) == NOTE && NOTE_LINE_NUMBER (NEXT_INSN (insn)) == NOTE_INSN_SETJMP) { - int max_reg = max_reg_num (); - for (i = 0; i < max_reg; i++) + for (i = 0; i < reg_last_uses_size; i++) { for (u = reg_last_uses[i]; u; u = XEXP (u, 1)) add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI); @@ -2371,11 +1834,10 @@ sched_note_set (b, x, death) dealing with queueing and dequeueing of instructions. */ #define SCHED_SORT(READY, NEW_READY, OLD_READY) \ - do { if ((NEW_READY) - (OLD_READY) == 1) \ - swap_sort (READY, NEW_READY); \ - else if ((NEW_READY) - (OLD_READY) > 1) \ - qsort (READY, NEW_READY, sizeof (rtx), rank_for_schedule); } \ - while (0) + if ((NEW_READY) - (OLD_READY) == 1) \ + swap_sort (READY, NEW_READY); \ + else if ((NEW_READY) - (OLD_READY) > 1) \ + qsort (READY, NEW_READY, sizeof (rtx), rank_for_schedule); else \ /* Returns a positive value if y is preferred; returns a negative value if x is preferred. Should never return 0, since that will make the sort @@ -3173,7 +2635,7 @@ schedule_block (b, file) fprintf (file, ";;\t -- basic block number %d from %d to %d --\n", b, INSN_UID (basic_block_head[b]), INSN_UID (basic_block_end[b])); - i = max_reg_num (); + reg_last_uses_size = i = max_reg_num (); reg_last_uses = (rtx *) alloca (i * sizeof (rtx)); bzero ((char *) reg_last_uses, i * sizeof (rtx)); reg_last_sets = (rtx *) alloca (i * sizeof (rtx)); @@ -4717,6 +4179,21 @@ schedule_insns (dump_file) bcopy ((char *) reg_n_deaths, (char *) sched_reg_n_deaths, max_regno * sizeof (short)); init_alias_analysis (); +#if 0 + if (dump_file) + { + extern rtx *reg_base_value; + extern int reg_base_value_size; + int i; + for (i = 0; i < reg_base_value_size; i++) + if (reg_base_value[i]) + { + fprintf (dump_file, ";; reg_base_value[%d] = ", i); + print_rtl (dump_file, reg_base_value[i]); + fputc ('\n', dump_file); + } + } +#endif } else { @@ -4725,8 +4202,7 @@ schedule_insns (dump_file) sched_reg_live_length = 0; bb_dead_regs = 0; bb_live_regs = 0; - if (! flag_schedule_insns) - init_alias_analysis (); + init_alias_analysis (); } if (write_symbols != NO_DEBUG) diff --git a/gnu/usr.bin/gcc/toplev.c b/gnu/usr.bin/gcc/toplev.c index 4d33910170d..01b71e1bb18 100644 --- a/gnu/usr.bin/gcc/toplev.c +++ b/gnu/usr.bin/gcc/toplev.c @@ -535,6 +535,17 @@ int flag_gnu_linker = 1; /* Tag all structures with __attribute__(packed) */ int flag_pack_struct = 0; +/* 1 if alias checking is on (by default, when -O). */ +int flag_alias_check = 0; + +/* 0 if pointer arguments may alias each other. True in C. + 1 if pointer arguments may not alias each other but may alias + global variables. + 2 if pointer arguments may not alias each other and may not + alias global variables. True in Fortran. + This defaults to 0 for C. */ +int flag_argument_noalias = 0; + /* Table of language-independent -f options. STRING is the option name. VARIABLE is the address of the variable. ON_VALUE is the value to store in VARIABLE @@ -584,7 +595,11 @@ struct { char *string; int *variable; int on_value;} f_options[] = {"verbose-asm", &flag_verbose_asm, 1}, {"gnu-linker", &flag_gnu_linker, 1}, {"pack-struct", &flag_pack_struct, 1}, - {"bytecode", &output_bytecode, 1} + {"bytecode", &output_bytecode, 1}, + {"alias-check", &flag_alias_check, 1}, + {"argument-alias", &flag_argument_noalias, 0}, + {"argument-noalias", &flag_argument_noalias, 1}, + {"argument-noalias-global", &flag_argument_noalias, 2} }; /* Table of language-specific options. */ @@ -3401,6 +3416,7 @@ main (argc, argv, envp) #ifdef CAN_DEBUG_WITHOUT_FP flag_omit_frame_pointer = 1; #endif + flag_alias_check = 1; } if (optimize >= 2) diff --git a/gnu/usr.bin/gcc/tree.c b/gnu/usr.bin/gcc/tree.c index e92863b35ee..8281e9c457b 100644 --- a/gnu/usr.bin/gcc/tree.c +++ b/gnu/usr.bin/gcc/tree.c @@ -1964,30 +1964,6 @@ saveable_tree_cons (purpose, value, chain) return node; } -/* Try to find out whether the type for which the size is to be determined - is an ARRAY(of ARRAY(of ARRAY ... of something with a constant size - which is an integral multiple of BITS_PER_UNIT)). - In that case, the size in bytes can be determined using an EXACT_DIV_EXPR. -*/ -enum tree_code -which_div_expr(type) - tree type; -{ - tree t; - - if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != ARRAY_TYPE) - return CEIL_DIV_EXPR; - - for (t = TREE_TYPE (type); TREE_CODE (t) == ARRAY_TYPE; t = TREE_TYPE (t)) - ; - - if (TYPE_SIZE (t) != 0 && TREE_CODE (TYPE_SIZE (t)) == INTEGER_CST && - TREE_INT_CST_LOW (TYPE_SIZE (t)) % BITS_PER_UNIT == 0) - return EXACT_DIV_EXPR; - else - return CEIL_DIV_EXPR; -} - /* Return the size nominally occupied by an object of type TYPE when it resides in memory. The value is measured in units of bytes, and its data type is that normally used for type sizes @@ -2008,7 +1984,7 @@ size_in_bytes (type) incomplete_type_error (NULL_TREE, type); return integer_zero_node; } - t = size_binop (which_div_expr (type), TYPE_SIZE (type), + t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), size_int (BITS_PER_UNIT)); if (TREE_CODE (t) == INTEGER_CST) force_fit_type (t, 0); @@ -2032,7 +2008,7 @@ int_size_in_bytes (type) return -1; if (TREE_INT_CST_HIGH (TYPE_SIZE (type)) != 0) { - tree t = size_binop (which_div_expr (type), TYPE_SIZE (type), + tree t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), size_int (BITS_PER_UNIT)); return TREE_INT_CST_LOW (t); } diff --git a/gnu/usr.bin/gcc/unroll.c b/gnu/usr.bin/gcc/unroll.c index c5985780a82..459257ef899 100644 --- a/gnu/usr.bin/gcc/unroll.c +++ b/gnu/usr.bin/gcc/unroll.c @@ -994,8 +994,11 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before, for (j = FIRST_PSEUDO_REGISTER; j < max_reg_before_loop; j++) if (local_regno[j]) - map->reg_map[j] = gen_reg_rtx (GET_MODE (regno_reg_rtx[j])); - + { + map->reg_map[j] = gen_reg_rtx (GET_MODE (regno_reg_rtx[j])); + record_base_value (REGNO (map->reg_map[j]), + regno_reg_rtx[j]); + } /* The last copy needs the compare/branch insns at the end, so reset copy_end here if the loop ends with a conditional branch. */ @@ -1135,7 +1138,11 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before, for (j = FIRST_PSEUDO_REGISTER; j < max_reg_before_loop; j++) if (local_regno[j]) - map->reg_map[j] = gen_reg_rtx (GET_MODE (regno_reg_rtx[j])); + { + map->reg_map[j] = gen_reg_rtx (GET_MODE (regno_reg_rtx[j])); + record_base_value (REGNO (map->reg_map[j]), + regno_reg_rtx[j]); + } /* If loop starts with a branch to the test, then fix it so that it points to the test of the first unrolled copy of the loop. */ @@ -1630,7 +1637,7 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration, /* Check for shared address givs, and avoid incrementing the shared pseudo reg more than once. */ - if (! tv->same_insn) + if (! tv->same_insn && ! tv->shared) { /* tv->dest_reg may actually be a (PLUS (REG) (CONST)) here, so we must call plus_constant @@ -1756,6 +1763,7 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration, tem = gen_reg_rtx (GET_MODE (giv_src_reg)); giv_dest_reg = tem; map->reg_map[regno] = tem; + record_base_value (REGNO (tem), giv_src_reg); } else map->reg_map[regno] = giv_src_reg; @@ -2442,7 +2450,8 @@ find_splittable_regs (unroll_type, loop_start, loop_end, end_insert_before, || ! invariant_p (bl->initial_value))) { rtx tem = gen_reg_rtx (bl->biv->mode); - + + record_base_value (REGNO (tem), bl->biv->add_val); emit_insn_before (gen_move_insn (tem, bl->biv->src_reg), loop_start); @@ -2499,6 +2508,8 @@ find_splittable_regs (unroll_type, loop_start, loop_end, end_insert_before, this insn will always be executed, no matter how the loop exits. */ rtx tem = gen_reg_rtx (bl->biv->mode); + record_base_value (REGNO (tem), bl->biv->add_val); + emit_insn_before (gen_move_insn (tem, bl->biv->src_reg), loop_start); emit_insn_before (gen_move_insn (bl->biv->src_reg, @@ -2674,6 +2685,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment, { rtx tem = gen_reg_rtx (bl->biv->mode); + record_base_value (REGNO (tem), bl->biv->add_val); emit_insn_before (gen_move_insn (tem, bl->biv->src_reg), loop_start); biv_initial_value = tem; @@ -2715,6 +2727,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment, || GET_CODE (XEXP (value, 1)) != CONST_INT)) { rtx tem = gen_reg_rtx (v->mode); + record_base_value (REGNO (tem), v->add_val); emit_iv_add_mult (bl->initial_value, v->mult_val, v->add_val, tem, loop_start); value = tem; @@ -2733,16 +2746,9 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment, what we want for split addr regs. We always create a new register for the split addr giv, just to be safe. */ - /* ??? If there are multiple address givs which have been - combined with the same dest_reg giv, then we may only need - one new register for them. Pulling out constants below will - catch some of the common cases of this. Currently, I leave - the work of simplifying multiple address givs to the - following cse pass. */ - - /* As a special case, if we have multiple identical address givs - within a single instruction, then we do use a single pseudo - reg for both. This is necessary in case one is a match_dup + /* If we have multiple identical address givs within a + single instruction, then use a single pseudo reg for + both. This is necessary in case one is a match_dup of the other. */ v->const_adjust = 0; @@ -2755,12 +2761,26 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment, "Sharing address givs in insn %d\n", INSN_UID (v->insn)); } + /* If multiple address GIVs have been combined with the + same dest_reg GIV, do not create a new register for + each. */ + else if (unroll_type != UNROLL_COMPLETELY + && v->giv_type == DEST_ADDR + && v->same && v->same->giv_type == DEST_ADDR + && v->same->unrolled) + { + v->dest_reg = v->same->dest_reg; + v->shared = 1; + } else if (unroll_type != UNROLL_COMPLETELY) { /* If not completely unrolling the loop, then create a new register to hold the split value of the DEST_ADDR giv. Emit insn to initialize its value before loop start. */ - tem = gen_reg_rtx (v->mode); + + rtx tem = gen_reg_rtx (v->mode); + record_base_value (REGNO (tem), v->add_val); + v->unrolled = 1; /* If the address giv has a constant in its new_reg value, then this constant can be pulled out and put in value, @@ -2771,7 +2791,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment, { v->dest_reg = plus_constant (tem, INTVAL (XEXP (v->new_reg,1))); - + /* Only succeed if this will give valid addresses. Try to validate both the first and the last address resulting from loop unrolling, if @@ -3060,6 +3080,7 @@ final_biv_value (bl, loop_start, loop_end) case it is needed later. */ tem = gen_reg_rtx (bl->biv->mode); + record_base_value (REGNO (tem), bl->biv->add_val); /* Make sure loop_end is not the last insn. */ if (NEXT_INSN (loop_end) == 0) emit_note_after (NOTE_INSN_DELETED, loop_end); @@ -3153,6 +3174,7 @@ final_giv_value (v, loop_start, loop_end) /* Put the final biv value in tem. */ tem = gen_reg_rtx (bl->biv->mode); + record_base_value (REGNO (tem), bl->biv->add_val); emit_iv_add_mult (increment, GEN_INT (loop_n_iterations), bl->initial_value, tem, insert_before); |