summaryrefslogtreecommitdiff
path: root/gcc/fortran
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/fortran')
-rw-r--r--gcc/fortran/ChangeLog16
-rw-r--r--gcc/fortran/gfortran.h7
-rw-r--r--gcc/fortran/gfortran.texi96
-rw-r--r--gcc/fortran/invoke.texi28
-rw-r--r--gcc/fortran/lang.opt16
-rw-r--r--gcc/fortran/options.c16
-rw-r--r--gcc/fortran/trans-decl.c21
7 files changed, 193 insertions, 7 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index dbd94d52427..66f638f6301 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,19 @@
+2005-02-06 Thomas Koenig <Thomas.Koenig@online.de>
+
+ PR libfortran/23815
+ * gfortran.texi: Document the GFORTRAN_CONVERT_UNIT environment
+ variable.
+ * invoke.texi: Mention the "Runtime" chapter.
+ Document the -fconvert= option.
+ * gfortran.h: Add options_convert.
+ * lang.opt: Add fconvert=little-endian, fconvert=big-endian,
+ fconvert=native and fconvert=swap.
+ * trans-decl.c (top level): Add gfor_fndecl_set_convert.
+ (gfc_build_builtin_function_decls): Set gfor_fndecl_set_convert.
+ (gfc_generate_function_code): If -fconvert was specified,
+ and this is the main program, add a call to set_convert().
+ * options.c: Handle the -fconvert options.
+
2006-02-06 Roger Sayle <roger@eyesopen.com>
* trans-stmt.c (gfc_evaluate_where_mask): Allow the NMASK argument
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index a1aaaf09967..31d5a4eca0e 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -111,6 +111,12 @@ mstring;
#define GFC_FPE_UNDERFLOW (1<<4)
#define GFC_FPE_PRECISION (1<<5)
+/* Keep this in sync with libgfortran/io/io.h ! */
+
+typedef enum
+ { CONVERT_NATIVE=0, CONVERT_SWAP, CONVERT_BIG, CONVERT_LITTLE }
+options_convert;
+
/*************************** Enums *****************************/
@@ -1531,6 +1537,7 @@ typedef struct
int allow_std;
int warn_nonstd_intrinsics;
int fshort_enums;
+ int convert;
}
gfc_option_t;
diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi
index b4f1bf95c22..65a2542de6e 100644
--- a/gcc/fortran/gfortran.texi
+++ b/gcc/fortran/gfortran.texi
@@ -125,6 +125,7 @@ not accurately reflect the status of the most recent @command{gfortran}.
* Project Status:: Status of @command{gfortran}, roadmap, proposed extensions.
* Contributing:: How you can help.
* Standards:: Standards supported by @command{gfortran}
+* Runtime:: Influencing runtime behavior with environment variables.
* Extensions:: Language extensions implemented by @command{gfortran}
* Intrinsic Procedures:: Intrinsic procedures supported by @command{gfortran}
* Copying:: GNU General Public License says
@@ -545,13 +546,82 @@ Environment variable for temporary file directory.
@item
Environment variable forcing standard output to be line buffered (unix).
-@item
-Variable for swapping endianness during unformatted read.
+@end itemize
-@item
-Variable for swapping Endianness during unformatted write.
+@node Runtime
+@chapter Runtime: Influencing runtime behavior with environment variables
+@cindex Runtime
+
+The behaviour of the @command{gfortran} can be influenced by
+environment variables.
+@menu
+* GFORTRAN_CONVERT_UNIT:: Set endianness for unformatted I/O
+@end menu
+
+@node GFORTRAN_CONVERT_UNIT
+@section GFORTRAN_CONVERT_UNIT --- Set endianness for unformatted I/O
+
+By setting the @code{GFORTRAN_CONVERT_UNIT variable}, it is possible
+to change the representation of data for unformatted files.
+The syntax for the @code{GFORTRAN_CONVERT_UNIT} variable is:
+@smallexample
+GFORTRAN_CONVERT_UNIT: mode | mode ';' exception ;
+mode: 'native' | 'swap' | 'big_endian' | 'little_endian' ;
+exception: mode ':' unit_list | unit_list ;
+unit_list: unit_spec | unit_list unit_spec ;
+unit_spec: INTEGER | INTEGER '-' INTEGER ;
+@end smallexample
+The variable consists of an optional default mode, followed by
+a list of optional exceptions, which are separated by semicolons
+from the preceding default and each other. Each exception consists
+of a format and a comma-separated list of units. Valid values for
+the modes are the same as for the @code{CONVERT} specifier:
+
+@itemize @w{}
+@item @code{NATIVE} Use the native format. This is the default.
+@item @code{SWAP} Swap between little- and big-endian.
+@item @code{LITTLE_ENDIAN} Use the little-endian format
+ for unformatted files.
+@item @code{BIG_ENDIAN} Use the big-endian format for unformatted files.
+@end itemize
+A missing mode for an exception is taken to mean @code{BIG_ENDIAN}.
+Examples of values for @code{GFORTRAN_CONVERT_UNIT} are:
+@itemize @w{}
+@item @code{'big_endian'} Do all unformatted I/O in big_endian mode.
+@item @code{'little_endian;native:10-20,25'} Do all unformatted I/O
+in little_endian mode, except for units 10 to 20 and 25, which are in
+native format.
+@item @code{'10-20'} Units 10 to 20 are big-endian, the rest is native.
@end itemize
+Setting the environment variables should be done on the command
+line or via the @code{export}
+command for @code{sh}-compatible shells and via @code{setenv}
+for @code{csh}-compatible shells.
+
+Example for @code{sh}:
+@smallexample
+$ gfortran foo.f90
+$ GFORTRAN_CONVERT_UNIT='big_endian;native:10-20' ./a.out
+@end smallexample
+
+Example code for @code{csh}:
+@smallexample
+% gfortran foo.f90
+% setenv GFORTRAN_CONVERT_UNIT 'big_endian;native:10-20'
+% ./a.out
+@end smallexample
+
+Using anything but the native representation for unformatted data
+carries a significant speed overhead. If speed in this area matters
+to you, it is best if you use this only for data that needs to be
+portable.
+
+@xref{CONVERT specifier}, for an alternative way to specify the
+data representation for unformatted files. @xref{Runtime Options}, for
+setting a default data representation for the whole program. The
+@code{CONVERT} specifier overrides the @code{-fconvert} compile options.
+
@c ---------------------------------------------------------------------
@c Extensions
@c ---------------------------------------------------------------------
@@ -937,16 +1007,18 @@ will not change the base address of the array that was passed.
gfortran allows the conversion of unformatted data between little-
and big-endian representation to facilitate moving of data
-between different systems. The conversion is indicated with
+between different systems. The conversion can be indicated with
the @code{CONVERT} specifier on the @code{OPEN} statement.
+@xref{GFORTRAN_CONVERT_UNIT}, for an alternative way of specifying
+the data format via an environment variable.
Valid values for @code{CONVERT} are:
@itemize @w{}
@item @code{CONVERT='NATIVE'} Use the native format. This is the default.
@item @code{CONVERT='SWAP'} Swap between little- and big-endian.
-@item @code{CONVERT='LITTLE_ENDIAN'} Use the little-endian format
+@item @code{CONVERT='LITTLE_ENDIAN'} Use the little-endian representation
for unformatted files.
-@item @code{CONVERT='BIG_ENDIAN'} Use the big-endian format for
+@item @code{CONVERT='BIG_ENDIAN'} Use the big-endian representation for
unformatted files.
@end itemize
@@ -967,6 +1039,16 @@ on IEEE systems of kinds 4 and 8. Conversion between different
m68k and x86_64, which gfortran
supports as @code{REAL(KIND=10)} will probably not work.
+@emph{Note that the values specified via the GFORTRAN_CONVERT_UNIT
+environment variable will override the CONVERT specifier in the
+open statement}. This is to give control over data formats to
+a user who does not have the source code of his program available.
+
+Using anything but the native representation for unformatted data
+carries a significant speed overhead. If speed in this area matters
+to you, it is best if you use this only for data that needs to be
+portable.
+
@c ---------------------------------------------------------------------
@include intrinsic.texi
@c ---------------------------------------------------------------------
diff --git a/gcc/fortran/invoke.texi b/gcc/fortran/invoke.texi
index 5816207d4a6..8d7a1d52f11 100644
--- a/gcc/fortran/invoke.texi
+++ b/gcc/fortran/invoke.texi
@@ -98,6 +98,7 @@ one is not the default.
* Warning Options:: How picky should the compiler be?
* Debugging Options:: Symbol tables, measurements, and debugging dumps.
* Directory Options:: Where to find module files
+* Runtime Options:: Influencing runtime behavior
* Code Gen Options:: Specifying conventions for function calls, data layout
and register usage.
* Environment Variables:: Env vars that affect GNU Fortran.
@@ -141,6 +142,11 @@ by type. Explanations are in the following sections.
@gccoptlist{
-I@var{dir} -M@var{dir}}
+@item Runtime Options
+@xref{Runtime Options,,Options for influencing runtime behavior}.
+@gccoptlist{
+-fconvert=@var{conversion}}
+
@item Code Generation Options
@xref{Code Gen Options,,Options for Code Generation Conventions}.
@gccoptlist{
@@ -155,6 +161,7 @@ by type. Explanations are in the following sections.
* Warning Options:: How picky should the compiler be?
* Debugging Options:: Symbol tables, measurements, and debugging dumps.
* Directory Options:: Where to find module files
+* Runtime Options:: Influencing runtime behavior
* Code Gen Options:: Specifying conventions for function calls, data layout
and register usage.
@end menu
@@ -557,6 +564,25 @@ The default is the current directory.
GCC options.
@end table
+@node Runtime Options
+@section Influencing runtime behavior
+@cindex runtime, options
+
+These options affect the runtime behavior of @command{gfortran}.
+@table @gcctabopt
+@cindex -fconvert=@var{conversion} option
+@item -fconvert=@var{conversion}
+Specify the representation of data for unformatted files. Valid
+values for conversion are: @samp{native}, the default; @samp{swap},
+swap between big- and little-endian; @samp{big-endian}, use big-endian
+representation for unformatted files; @samp{little-endian}, use little-endian
+representation for unformatted files.
+
+@emph{This option has an effect only when used in the main program.
+The @code{CONVERT} specifier and the GFORTRAN_CONVERT_UNIT environment
+variable override the default specified by -fconvert.}
+@end table
+
@node Code Gen Options
@section Options for Code Generation Conventions
@cindex code generation, conventions
@@ -796,4 +822,6 @@ that affect the operation of @command{gcc}.
gcc,Using the GNU Compiler Collection (GCC)}, for information on environment
variables.
+@xref{Runtime}, for environment variables that affect the
+run-time behavior of @command{gfortran} programs.
@c man end
diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
index 465d589813a..5ce2934f590 100644
--- a/gcc/fortran/lang.opt
+++ b/gcc/fortran/lang.opt
@@ -205,4 +205,20 @@ fshort-enums
Fortran
Use the narrowest integer type possible for enumeration types
+fconvert=little-endian
+Fortran RejectNegative
+Use little-endian format for unformatted files
+
+fconvert=big-endian
+Fortran RejectNegative
+Use big-endian format for unformatted files
+
+fconvert=native
+Fortran RejectNegative
+Use native format for unformatted files
+
+fconvert=swap
+Fortran RejectNegative
+Swap endianness for unformatted files
+
; This comment is to ensure we retain the blank line above.
diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
index d65827c9bb3..0b2f7b36f21 100644
--- a/gcc/fortran/options.c
+++ b/gcc/fortran/options.c
@@ -573,6 +573,22 @@ gfc_handle_option (size_t scode, const char *arg, int value)
case OPT_fshort_enums:
gfc_option.fshort_enums = 1;
break;
+
+ case OPT_fconvert_little_endian:
+ gfc_option.convert = CONVERT_LITTLE;
+ break;
+
+ case OPT_fconvert_big_endian:
+ gfc_option.convert = CONVERT_BIG;
+ break;
+
+ case OPT_fconvert_native:
+ gfc_option.convert = CONVERT_NATIVE;
+ break;
+
+ case OPT_fconvert_swap:
+ gfc_option.convert = CONVERT_SWAP;
+ break;
}
return result;
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index cdbb9995567..4811b7a1d60 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -88,6 +88,7 @@ tree gfor_fndecl_select_string;
tree gfor_fndecl_runtime_error;
tree gfor_fndecl_set_fpe;
tree gfor_fndecl_set_std;
+tree gfor_fndecl_set_convert;
tree gfor_fndecl_ctime;
tree gfor_fndecl_fdate;
tree gfor_fndecl_ttynam;
@@ -2229,6 +2230,10 @@ gfc_build_builtin_function_decls (void)
gfc_int4_type_node,
gfc_int4_type_node);
+ gfor_fndecl_set_convert =
+ gfc_build_library_function_decl (get_identifier (PREFIX("set_convert")),
+ void_type_node, 1, gfc_c_int_type_node);
+
gfor_fndecl_in_pack = gfc_build_library_function_decl (
get_identifier (PREFIX("internal_pack")),
pvoid_type_node, 1, pvoid_type_node);
@@ -2845,6 +2850,22 @@ gfc_generate_function_code (gfc_namespace * ns)
gfc_add_expr_to_block (&body, tmp);
}
+ /* If this is the main program and an -fconvert option was provided,
+ add a call to set_convert. */
+
+ if (sym->attr.is_main_program && gfc_option.convert != CONVERT_NATIVE)
+ {
+ tree arglist, gfc_c_int_type_node;
+
+ gfc_c_int_type_node = gfc_get_int_type (gfc_c_int_kind);
+ arglist = gfc_chainon_list (NULL_TREE,
+ build_int_cst (gfc_c_int_type_node,
+ gfc_option.convert));
+ tmp = build_function_call_expr (gfor_fndecl_set_convert, arglist);
+ gfc_add_expr_to_block (&body, tmp);
+ }
+
+
if (TREE_TYPE (DECL_RESULT (fndecl)) != void_type_node
&& sym->attr.subroutine)
{