1 /* ste.c -- Implementation File (module.c template V1.0)
2 Copyright (C) 1995, 1996, 2000 Free Software Foundation, Inc.
3 Contributed by James Craig Burley.
5 This file is part of GNU Fortran.
7 GNU Fortran is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Fortran is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Fortran; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
26 Implements the various statements and such like.
35 #if FFECOM_targetCURRENT == FFECOM_targetGCC
56 /* Externals defined here. */
59 /* Simple definitions and enumerations. */
63 FFESTE_stateletSIMPLE_, /* Expecting simple/start. */
64 FFESTE_stateletATTRIB_, /* Expecting attrib/item/itemstart. */
65 FFESTE_stateletITEM_, /* Expecting item/itemstart/finish. */
66 FFESTE_stateletITEMVALS_, /* Expecting itemvalue/itemendvals. */
70 /* Internal typedefs. */
73 /* Private include files. */
76 /* Internal structure definitions. */
79 /* Static objects accessed by functions in this module. */
81 static ffesteStatelet_ ffeste_statelet_ = FFESTE_stateletSIMPLE_;
82 #if FFECOM_targetCURRENT == FFECOM_targetGCC
83 static ffelab ffeste_label_formatdef_ = NULL;
84 static tree (*ffeste_io_driver_) (ffebld expr); /* do?io. */
85 static ffecomGfrt ffeste_io_endgfrt_; /* end function to call. */
86 static tree ffeste_io_abort_; /* abort-io label or NULL_TREE. */
87 static bool ffeste_io_abort_is_temp_; /* abort-io label is a temp. */
88 static tree ffeste_io_end_; /* END= label or NULL_TREE. */
89 static tree ffeste_io_err_; /* ERR= label or NULL_TREE. */
90 static tree ffeste_io_iostat_; /* IOSTAT= var or NULL_TREE. */
91 static bool ffeste_io_iostat_is_temp_; /* IOSTAT= var is a temp. */
94 /* Static functions (internal). */
96 #if FFECOM_targetCURRENT == FFECOM_targetGCC
97 static void ffeste_begin_iterdo_ (ffestw block, tree *tvar, tree *tincr,
98 tree *xitersvar, ffebld var,
99 ffebld start, ffelexToken start_token,
100 ffebld end, ffelexToken end_token,
101 ffebld incr, ffelexToken incr_token,
103 static void ffeste_end_iterdo_ (ffestw block, tree tvar, tree tincr,
105 static void ffeste_io_call_ (tree call, bool do_check);
106 static void ffeste_io_impdo_ (ffebld impdo, ffelexToken impdo_token);
107 static tree ffeste_io_dofio_ (ffebld expr);
108 static tree ffeste_io_dolio_ (ffebld expr);
109 static tree ffeste_io_douio_ (ffebld expr);
110 static tree ffeste_io_ialist_ (bool have_err, ffestvUnit unit,
111 ffebld unit_expr, int unit_dflt);
112 static tree ffeste_io_cilist_ (bool have_err, ffestvUnit unit,
113 ffebld unit_expr, int unit_dflt,
114 bool have_end, ffestvFormat format,
115 ffestpFile *format_spec, bool rec,
117 static tree ffeste_io_cllist_ (bool have_err, ffebld unit_expr,
118 ffestpFile *stat_spec);
119 static tree ffeste_io_icilist_ (bool have_err, ffebld unit_expr,
120 bool have_end, ffestvFormat format,
121 ffestpFile *format_spec);
122 static tree ffeste_io_inlist_ (bool have_err,
123 ffestpFile *unit_spec,
124 ffestpFile *file_spec,
125 ffestpFile *exist_spec,
126 ffestpFile *open_spec,
127 ffestpFile *number_spec,
128 ffestpFile *named_spec,
129 ffestpFile *name_spec,
130 ffestpFile *access_spec,
131 ffestpFile *sequential_spec,
132 ffestpFile *direct_spec,
133 ffestpFile *form_spec,
134 ffestpFile *formatted_spec,
135 ffestpFile *unformatted_spec,
136 ffestpFile *recl_spec,
137 ffestpFile *nextrec_spec,
138 ffestpFile *blank_spec);
139 static tree ffeste_io_olist_ (bool have_err, ffebld unit_expr,
140 ffestpFile *file_spec,
141 ffestpFile *stat_spec,
142 ffestpFile *access_spec,
143 ffestpFile *form_spec,
144 ffestpFile *recl_spec,
145 ffestpFile *blank_spec);
146 static void ffeste_subr_beru_ (ffestpBeruStmt *info, ffecomGfrt rt);
147 #elif FFECOM_targetCURRENT == FFECOM_targetFFE
148 static void ffeste_subr_file_ (const char *kw, ffestpFile *spec);
153 /* Internal macros. */
155 #if FFECOM_targetCURRENT == FFECOM_targetGCC
156 #define ffeste_emit_line_note_() \
157 emit_line_note (input_filename, lineno)
159 #define ffeste_check_simple_() \
160 assert(ffeste_statelet_ == FFESTE_stateletSIMPLE_)
161 #define ffeste_check_start_() \
162 assert(ffeste_statelet_ == FFESTE_stateletSIMPLE_); \
163 ffeste_statelet_ = FFESTE_stateletATTRIB_
164 #define ffeste_check_attrib_() \
165 assert(ffeste_statelet_ == FFESTE_stateletATTRIB_)
166 #define ffeste_check_item_() \
167 assert(ffeste_statelet_ == FFESTE_stateletATTRIB_ \
168 || ffeste_statelet_ == FFESTE_stateletITEM_); \
169 ffeste_statelet_ = FFESTE_stateletITEM_
170 #define ffeste_check_item_startvals_() \
171 assert(ffeste_statelet_ == FFESTE_stateletATTRIB_ \
172 || ffeste_statelet_ == FFESTE_stateletITEM_); \
173 ffeste_statelet_ = FFESTE_stateletITEMVALS_
174 #define ffeste_check_item_value_() \
175 assert(ffeste_statelet_ == FFESTE_stateletITEMVALS_)
176 #define ffeste_check_item_endvals_() \
177 assert(ffeste_statelet_ == FFESTE_stateletITEMVALS_); \
178 ffeste_statelet_ = FFESTE_stateletITEM_
179 #define ffeste_check_finish_() \
180 assert(ffeste_statelet_ == FFESTE_stateletATTRIB_ \
181 || ffeste_statelet_ == FFESTE_stateletITEM_); \
182 ffeste_statelet_ = FFESTE_stateletSIMPLE_
184 #define ffeste_f2c_init_charnolen_(Exp,Init,Spec) \
187 if ((Spec)->kw_or_val_present) \
188 Exp = ffecom_arg_ptr_to_const_expr ((Spec)->u.expr, &ignore); \
190 Exp = null_pointer_node; \
195 Init = null_pointer_node; \
200 #define ffeste_f2c_init_char_(Exp,Init,Lenexp,Leninit,Spec) \
203 if ((Spec)->kw_or_val_present) \
204 Exp = ffecom_arg_ptr_to_const_expr ((Spec)->u.expr, &Lenexp); \
207 Exp = null_pointer_node; \
208 Lenexp = ffecom_f2c_ftnlen_zero_node; \
214 Init = null_pointer_node; \
221 Leninit = ffecom_f2c_ftnlen_zero_node; \
226 #define ffeste_f2c_init_flag_(Flag,Init) \
229 Init = convert (ffecom_f2c_flag_type_node, \
230 (Flag) ? integer_one_node : integer_zero_node); \
233 #define ffeste_f2c_init_format_(Exp,Init,Spec) \
236 Exp = ffecom_arg_ptr_to_const_expr ((Spec)->u.expr, NULL); \
241 Init = null_pointer_node; \
246 #define ffeste_f2c_init_int_(Exp,Init,Spec) \
249 if ((Spec)->kw_or_val_present) \
250 Exp = ffecom_const_expr ((Spec)->u.expr); \
252 Exp = ffecom_integer_zero_node; \
257 Init = ffecom_integer_zero_node; \
262 #define ffeste_f2c_init_ptrtoint_(Exp,Init,Spec) \
265 if ((Spec)->kw_or_val_present) \
266 Exp = ffecom_ptr_to_const_expr ((Spec)->u.expr); \
268 Exp = null_pointer_node; \
273 Init = null_pointer_node; \
278 #define ffeste_f2c_init_next_(Init) \
281 TREE_CHAIN (initn) = build_tree_list ((field = TREE_CHAIN (field)), \
283 initn = TREE_CHAIN(initn); \
286 #define ffeste_f2c_prepare_charnolen_(Spec,Exp) \
290 ffecom_prepare_arg_ptr_to_expr ((Spec)->u.expr); \
293 #define ffeste_f2c_prepare_char_(Spec,Exp) \
297 ffecom_prepare_arg_ptr_to_expr ((Spec)->u.expr); \
300 #define ffeste_f2c_prepare_format_(Spec,Exp) \
304 ffecom_prepare_arg_ptr_to_expr ((Spec)->u.expr); \
307 #define ffeste_f2c_prepare_int_(Spec,Exp) \
311 ffecom_prepare_expr ((Spec)->u.expr); \
314 #define ffeste_f2c_prepare_ptrtoint_(Spec,Exp) \
318 ffecom_prepare_ptr_to_expr ((Spec)->u.expr); \
321 #define ffeste_f2c_compile_(Field,Exp) \
327 exz = ffecom_modify (void_type_node, \
328 ffecom_2 (COMPONENT_REF, TREE_TYPE (Field), \
331 expand_expr_stmt (exz); \
335 #define ffeste_f2c_compile_charnolen_(Field,Spec,Exp) \
341 exq = ffecom_arg_ptr_to_expr ((Spec)->u.expr, &ignore); \
342 ffeste_f2c_compile_ ((Field), exq); \
346 #define ffeste_f2c_compile_char_(Field,Lenfield,Spec,Exp,Lenexp) \
350 tree lenexq = (Lenexp); \
351 int need_exq = (! exq); \
352 int need_lenexq = (! lenexq); \
353 if (need_exq || need_lenexq) \
355 exq = ffecom_arg_ptr_to_expr ((Spec)->u.expr, &lenexq); \
357 ffeste_f2c_compile_ ((Field), exq); \
359 ffeste_f2c_compile_ ((Lenfield), lenexq); \
363 #define ffeste_f2c_compile_format_(Field,Spec,Exp) \
369 exq = ffecom_arg_ptr_to_expr ((Spec)->u.expr, NULL); \
370 ffeste_f2c_compile_ ((Field), exq); \
374 #define ffeste_f2c_compile_int_(Field,Spec,Exp) \
380 exq = ffecom_expr ((Spec)->u.expr); \
381 ffeste_f2c_compile_ ((Field), exq); \
385 #define ffeste_f2c_compile_ptrtoint_(Field,Spec,Exp) \
391 exq = ffecom_ptr_to_expr ((Spec)->u.expr); \
392 ffeste_f2c_compile_ ((Field), exq); \
396 /* Start a Fortran block. */
398 #ifdef ENABLE_CHECKING
400 typedef struct gbe_block
402 struct gbe_block *outer;
405 const char *input_filename;
409 gbe_block ffeste_top_block_ = NULL;
412 ffeste_start_block_ (ffestw block)
414 gbe_block b = xmalloc (sizeof (*b));
416 b->outer = ffeste_top_block_;
419 b->input_filename = input_filename;
422 ffeste_top_block_ = b;
424 ffecom_start_compstmt ();
427 /* End a Fortran block. */
430 ffeste_end_block_ (ffestw block)
432 gbe_block b = ffeste_top_block_;
435 assert (! b->is_stmt);
436 assert (b->block == block);
437 assert (! b->is_stmt);
439 ffeste_top_block_ = b->outer;
443 ffecom_end_compstmt ();
446 /* Start a Fortran statement.
448 Starts a back-end block, so temporaries can be managed, clean-ups
449 properly handled, etc. Nesting of statements *is* allowed -- the
450 handling of I/O items, even implied-DO I/O lists, within a READ,
451 PRINT, or WRITE statement is one example. */
454 ffeste_start_stmt_(void)
456 gbe_block b = xmalloc (sizeof (*b));
458 b->outer = ffeste_top_block_;
461 b->input_filename = input_filename;
464 ffeste_top_block_ = b;
466 ffecom_start_compstmt ();
469 /* End a Fortran statement. */
472 ffeste_end_stmt_(void)
474 gbe_block b = ffeste_top_block_;
479 ffeste_top_block_ = b->outer;
483 ffecom_end_compstmt ();
486 #else /* ! defined (ENABLE_CHECKING) */
488 #define ffeste_start_block_(b) ffecom_start_compstmt ()
489 #define ffeste_end_block_(b) \
492 ffecom_end_compstmt (); \
494 #define ffeste_start_stmt_() ffeste_start_block_(NULL)
495 #define ffeste_end_stmt_() ffeste_end_block_(NULL)
497 #endif /* ! defined (ENABLE_CHECKING) */
499 /* Begin an iterative DO loop. Pass the block to start if
502 #if FFECOM_targetCURRENT == FFECOM_targetGCC
504 ffeste_begin_iterdo_ (ffestw block, tree *xtvar, tree *xtincr,
505 tree *xitersvar, ffebld var,
506 ffebld start, ffelexToken start_token,
507 ffebld end, ffelexToken end_token,
508 ffebld incr, ffelexToken incr_token,
518 struct nesting *expanded_loop;
520 /* Want to have tvar, tincr, and niters for the whole loop body. */
523 ffeste_start_block_ (block);
525 ffeste_start_stmt_ ();
527 niters = ffecom_make_tempvar (block ? "do" : "impdo",
528 ffecom_integer_type_node,
529 FFETARGET_charactersizeNONE, -1);
531 ffecom_prepare_expr (incr);
532 ffecom_prepare_expr_rw (NULL_TREE, var);
534 ffecom_prepare_end ();
536 tvar = ffecom_expr_rw (NULL_TREE, var);
537 tincr = ffecom_expr (incr);
539 if (TREE_CODE (tvar) == ERROR_MARK
540 || TREE_CODE (tincr) == ERROR_MARK)
544 ffeste_end_block_ (block);
545 ffestw_set_do_tvar (block, error_mark_node);
550 *xtvar = error_mark_node;
555 /* Check whether incr is known to be zero, complain and fix. */
557 if (integer_zerop (tincr) || real_zerop (tincr))
559 ffebad_start (FFEBAD_DO_STEP_ZERO);
560 ffebad_here (0, ffelex_token_where_line (incr_token),
561 ffelex_token_where_column (incr_token));
564 tincr = convert (TREE_TYPE (tvar), integer_one_node);
567 tincr_saved = ffecom_save_tree (tincr);
569 /* Want to have tstart, tend for just this statement. */
571 ffeste_start_stmt_ ();
573 ffecom_prepare_expr (start);
574 ffecom_prepare_expr (end);
576 ffecom_prepare_end ();
578 tstart = ffecom_expr (start);
579 tend = ffecom_expr (end);
581 if (TREE_CODE (tstart) == ERROR_MARK
582 || TREE_CODE (tend) == ERROR_MARK)
588 ffeste_end_block_ (block);
589 ffestw_set_do_tvar (block, error_mark_node);
594 *xtvar = error_mark_node;
599 /* For warnings only, nothing else happens here. */
603 if (! ffe_is_onetrip ())
605 try = ffecom_2 (MINUS_EXPR, TREE_TYPE (tvar),
609 try = ffecom_2 (PLUS_EXPR, TREE_TYPE (tvar),
613 if (TREE_CODE (TREE_TYPE (tvar)) != REAL_TYPE)
614 try = ffecom_2 (TRUNC_DIV_EXPR, integer_type_node, try,
617 try = convert (integer_type_node,
618 ffecom_2 (RDIV_EXPR, TREE_TYPE (tvar),
622 /* Warn if loop never executed, since we've done the evaluation
623 of the unofficial iteration count already. */
625 try = ffecom_truth_value (ffecom_2 (LE_EXPR, integer_type_node,
627 convert (TREE_TYPE (tvar),
628 integer_zero_node)));
630 if (integer_onep (try))
632 ffebad_start (FFEBAD_DO_NULL);
633 ffebad_here (0, ffelex_token_where_line (start_token),
634 ffelex_token_where_column (start_token));
640 /* Warn if end plus incr would overflow. */
642 try = ffecom_2 (PLUS_EXPR, TREE_TYPE (tvar),
646 if ((TREE_CODE_CLASS (TREE_CODE (try)) == 'c')
647 && TREE_CONSTANT_OVERFLOW (try))
649 ffebad_start (FFEBAD_DO_END_OVERFLOW);
650 ffebad_here (0, ffelex_token_where_line (end_token),
651 ffelex_token_where_column (end_token));
657 /* Do the initial assignment into the DO var. */
659 tstart = ffecom_save_tree (tstart);
661 expr = ffecom_2 (MINUS_EXPR, TREE_TYPE (tvar),
665 if (! ffe_is_onetrip ())
667 expr = ffecom_2 (PLUS_EXPR, TREE_TYPE (expr),
669 convert (TREE_TYPE (expr), tincr_saved));
672 if (TREE_CODE (TREE_TYPE (tvar)) != REAL_TYPE)
673 expr = ffecom_2 (TRUNC_DIV_EXPR, TREE_TYPE (expr),
677 expr = ffecom_2 (RDIV_EXPR, TREE_TYPE (expr),
681 #if 1 /* New, F90-approved approach: convert to default INTEGER. */
682 if (TREE_TYPE (tvar) != error_mark_node)
683 expr = convert (ffecom_integer_type_node, expr);
684 #else /* Old approach; convert to INTEGER unless that's a narrowing. */
685 if ((TREE_TYPE (tvar) != error_mark_node)
686 && ((TREE_CODE (TREE_TYPE (tvar)) != INTEGER_TYPE)
687 || ((TYPE_SIZE (TREE_TYPE (tvar)) != NULL_TREE)
688 && ((TREE_CODE (TYPE_SIZE (TREE_TYPE (tvar)))
690 || (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (tvar)))
691 <= TREE_INT_CST_LOW (TYPE_SIZE (ffecom_integer_type_node)))))))
692 /* Convert unless promoting INTEGER type of any kind downward to
693 default INTEGER; else leave as, say, INTEGER*8 (long long int). */
694 expr = convert (ffecom_integer_type_node, expr);
697 assert (TYPE_MAIN_VARIANT (TREE_TYPE (niters))
698 == TYPE_MAIN_VARIANT (TREE_TYPE (expr)));
700 expr = ffecom_modify (void_type_node, niters, expr);
701 expand_expr_stmt (expr);
703 expr = ffecom_modify (void_type_node, tvar, tstart);
704 expand_expr_stmt (expr);
708 expanded_loop = expand_start_loop_continue_elsewhere (!! block);
710 ffestw_set_do_hook (block, expanded_loop);
712 if (! ffe_is_onetrip ())
714 expr = ffecom_truth_value
715 (ffecom_2 (GE_EXPR, integer_type_node,
716 ffecom_2 (PREDECREMENT_EXPR,
719 convert (TREE_TYPE (niters),
720 ffecom_integer_one_node)),
721 convert (TREE_TYPE (niters),
722 ffecom_integer_zero_node)));
724 expand_exit_loop_if_false (0, expr);
729 ffestw_set_do_tvar (block, tvar);
730 ffestw_set_do_incr_saved (block, tincr_saved);
731 ffestw_set_do_count_var (block, niters);
736 *xtincr = tincr_saved;
743 /* End an iterative DO loop. Pass the same iteration variable and increment
744 value trees that were generated in the paired _begin_ call. */
746 #if FFECOM_targetCURRENT == FFECOM_targetGCC
748 ffeste_end_iterdo_ (ffestw block, tree tvar, tree tincr, tree itersvar)
751 tree niters = itersvar;
753 if (tvar == error_mark_node)
756 expand_loop_continue_here ();
758 ffeste_start_stmt_ ();
760 if (ffe_is_onetrip ())
762 expr = ffecom_truth_value
763 (ffecom_2 (GE_EXPR, integer_type_node,
764 ffecom_2 (PREDECREMENT_EXPR,
767 convert (TREE_TYPE (niters),
768 ffecom_integer_one_node)),
769 convert (TREE_TYPE (niters),
770 ffecom_integer_zero_node)));
772 expand_exit_loop_if_false (0, expr);
775 expr = ffecom_modify (void_type_node, tvar,
776 ffecom_2 (PLUS_EXPR, TREE_TYPE (tvar),
779 expand_expr_stmt (expr);
781 /* Lose the stuff we just built. */
786 /* Lose the tvar and incr_saved trees. */
788 ffeste_end_block_ (block);
794 /* Generate call to run-time I/O routine. */
796 #if FFECOM_targetCURRENT == FFECOM_targetGCC
798 ffeste_io_call_ (tree call, bool do_check)
800 /* Generate the call and optional assignment into iostat var. */
802 TREE_SIDE_EFFECTS (call) = 1;
803 if (ffeste_io_iostat_ != NULL_TREE)
804 call = ffecom_modify (do_check ? NULL_TREE : void_type_node,
805 ffeste_io_iostat_, call);
806 expand_expr_stmt (call);
809 || ffeste_io_abort_ == NULL_TREE
810 || TREE_CODE (ffeste_io_abort_) == ERROR_MARK)
813 /* Generate optional test. */
815 expand_start_cond (ffecom_truth_value (ffeste_io_iostat_), 0);
816 expand_goto (ffeste_io_abort_);
821 /* Handle implied-DO in I/O list.
823 Expands code to start up the DO loop. Then for each item in the
824 DO loop, handles appropriately (possibly including recursively calling
825 itself). Then expands code to end the DO loop. */
827 #if FFECOM_targetCURRENT == FFECOM_targetGCC
829 ffeste_io_impdo_ (ffebld impdo, ffelexToken impdo_token)
831 ffebld var = ffebld_head (ffebld_right (impdo));
832 ffebld start = ffebld_head (ffebld_trail (ffebld_right (impdo)));
833 ffebld end = ffebld_head (ffebld_trail (ffebld_trail
834 (ffebld_right (impdo))));
835 ffebld incr = ffebld_head (ffebld_trail (ffebld_trail
836 (ffebld_trail (ffebld_right (impdo)))));
845 incr = ffebld_new_conter (ffebld_constant_new_integerdefault_val (1));
846 ffebld_set_info (incr, ffeinfo_new
847 (FFEINFO_basictypeINTEGER,
848 FFEINFO_kindtypeINTEGERDEFAULT,
851 FFEINFO_whereCONSTANT,
852 FFETARGET_charactersizeNONE));
855 /* Start the DO loop. */
857 start = ffeexpr_convert_expr (start, impdo_token, var, impdo_token,
859 end = ffeexpr_convert_expr (end, impdo_token, var, impdo_token,
861 incr = ffeexpr_convert_expr (incr, impdo_token, var, impdo_token,
864 ffeste_begin_iterdo_ (NULL, &tvar, &tincr, &titervar, var,
870 /* Handle the list of items. */
872 for (list = ffebld_left (impdo); list != NULL; list = ffebld_trail (list))
874 item = ffebld_head (list);
878 /* Strip parens off items such as in "READ *,(A)". This is really a bug
879 in the user's code, but I've been told lots of code does this. */
880 while (ffebld_op (item) == FFEBLD_opPAREN)
881 item = ffebld_left (item);
883 if (ffebld_op (item) == FFEBLD_opANY)
886 if (ffebld_op (item) == FFEBLD_opIMPDO)
887 ffeste_io_impdo_ (item, impdo_token);
890 ffeste_start_stmt_ ();
892 ffecom_prepare_arg_ptr_to_expr (item);
894 ffecom_prepare_end ();
896 ffeste_io_call_ ((*ffeste_io_driver_) (item), TRUE);
902 /* Generate end of implied-do construct. */
904 ffeste_end_iterdo_ (NULL, tvar, tincr, titervar);
908 /* I/O driver for formatted I/O item (do_fio)
910 Returns a tree for a CALL_EXPR to the do_fio function, which handles
911 a formatted I/O list item, along with the appropriate arguments for
912 the function. It is up to the caller to set the TREE_SIDE_EFFECTS flag
913 for the CALL_EXPR, expand (emit) the expression, emit any assignment
914 of the result to an IOSTAT= variable, and emit any checking of the
915 result for errors. */
917 #if FFECOM_targetCURRENT == FFECOM_targetGCC
919 ffeste_io_dofio_ (ffebld expr)
929 bt = ffeinfo_basictype (ffebld_info (expr));
930 kt = ffeinfo_kindtype (ffebld_info (expr));
932 if ((bt == FFEINFO_basictypeANY)
933 || (kt == FFEINFO_kindtypeANY))
934 return error_mark_node;
936 if (bt == FFEINFO_basictypeCOMPLEX)
939 bt = FFEINFO_basictypeREAL;
944 variable = ffecom_arg_ptr_to_expr (expr, &size);
946 if ((variable == error_mark_node)
947 || (size == error_mark_node))
948 return error_mark_node;
950 if (size == NULL_TREE) /* Already filled in for CHARACTER type. */
951 { /* "(ftnlen) sizeof(type)" */
952 size = size_binop (CEIL_DIV_EXPR,
953 TYPE_SIZE_UNIT (ffecom_tree_type[bt][kt]),
954 size_int (TYPE_PRECISION (char_type_node)
956 #if 0 /* Assume that while it is possible that char * is wider than
957 ftnlen, no object in Fortran space can get big enough for its
958 size to be wider than ftnlen. I really hope nobody wastes
959 time debugging a case where it can! */
960 assert (TYPE_PRECISION (ffecom_f2c_ftnlen_type_node)
961 >= TYPE_PRECISION (TREE_TYPE (size)));
963 size = convert (ffecom_f2c_ftnlen_type_node, size);
966 if (ffeinfo_rank (ffebld_info (expr)) == 0
967 || TREE_CODE (TREE_TYPE (TREE_TYPE (variable))) != ARRAY_TYPE)
969 = is_complex ? ffecom_f2c_ftnlen_two_node : ffecom_f2c_ftnlen_one_node;
973 = size_binop (CEIL_DIV_EXPR,
974 TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (variable))),
975 convert (sizetype, size));
976 num_elements = size_binop (CEIL_DIV_EXPR, num_elements,
977 size_int (TYPE_PRECISION (char_type_node)
979 num_elements = convert (ffecom_f2c_ftnlen_type_node,
984 = ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
987 variable = convert (string_type_node, variable);
989 arglist = build_tree_list (NULL_TREE, num_elements);
990 TREE_CHAIN (arglist) = build_tree_list (NULL_TREE, variable);
991 TREE_CHAIN (TREE_CHAIN (arglist)) = build_tree_list (NULL_TREE, size);
993 return ffecom_call_gfrt (FFECOM_gfrtDOFIO, arglist, NULL_TREE);
997 /* I/O driver for list-directed I/O item (do_lio)
999 Returns a tree for a CALL_EXPR to the do_lio function, which handles
1000 a list-directed I/O list item, along with the appropriate arguments for
1001 the function. It is up to the caller to set the TREE_SIDE_EFFECTS flag
1002 for the CALL_EXPR, expand (emit) the expression, emit any assignment
1003 of the result to an IOSTAT= variable, and emit any checking of the
1004 result for errors. */
1006 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1008 ffeste_io_dolio_ (ffebld expr)
1015 ffeinfoBasictype bt;
1019 bt = ffeinfo_basictype (ffebld_info (expr));
1020 kt = ffeinfo_kindtype (ffebld_info (expr));
1022 if ((bt == FFEINFO_basictypeANY)
1023 || (kt == FFEINFO_kindtypeANY))
1024 return error_mark_node;
1026 tc = ffecom_f2c_typecode (bt, kt);
1028 type_id = build_int_2 (tc, 0);
1031 = ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnint_type_node,
1032 convert (ffecom_f2c_ftnint_type_node,
1035 variable = ffecom_arg_ptr_to_expr (expr, &size);
1037 if ((type_id == error_mark_node)
1038 || (variable == error_mark_node)
1039 || (size == error_mark_node))
1040 return error_mark_node;
1042 if (size == NULL_TREE) /* Already filled in for CHARACTER type. */
1043 { /* "(ftnlen) sizeof(type)" */
1044 size = size_binop (CEIL_DIV_EXPR,
1045 TYPE_SIZE_UNIT (ffecom_tree_type[bt][kt]),
1046 size_int (TYPE_PRECISION (char_type_node)
1048 #if 0 /* Assume that while it is possible that char * is wider than
1049 ftnlen, no object in Fortran space can get big enough for its
1050 size to be wider than ftnlen. I really hope nobody wastes
1051 time debugging a case where it can! */
1052 assert (TYPE_PRECISION (ffecom_f2c_ftnlen_type_node)
1053 >= TYPE_PRECISION (TREE_TYPE (size)));
1055 size = convert (ffecom_f2c_ftnlen_type_node, size);
1058 if (ffeinfo_rank (ffebld_info (expr)) == 0
1059 || TREE_CODE (TREE_TYPE (TREE_TYPE (variable))) != ARRAY_TYPE)
1060 num_elements = ffecom_integer_one_node;
1064 = size_binop (CEIL_DIV_EXPR,
1065 TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (variable))),
1066 convert (sizetype, size));
1067 num_elements = size_binop (CEIL_DIV_EXPR, num_elements,
1068 size_int (TYPE_PRECISION (char_type_node)
1070 num_elements = convert (ffecom_f2c_ftnlen_type_node,
1075 = ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
1078 variable = convert (string_type_node, variable);
1080 arglist = build_tree_list (NULL_TREE, type_id);
1081 TREE_CHAIN (arglist) = build_tree_list (NULL_TREE, num_elements);
1082 TREE_CHAIN (TREE_CHAIN (arglist)) = build_tree_list (NULL_TREE, variable);
1083 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist)))
1084 = build_tree_list (NULL_TREE, size);
1086 return ffecom_call_gfrt (FFECOM_gfrtDOLIO, arglist, NULL_TREE);
1090 /* I/O driver for unformatted I/O item (do_uio)
1092 Returns a tree for a CALL_EXPR to the do_uio function, which handles
1093 an unformatted I/O list item, along with the appropriate arguments for
1094 the function. It is up to the caller to set the TREE_SIDE_EFFECTS flag
1095 for the CALL_EXPR, expand (emit) the expression, emit any assignment
1096 of the result to an IOSTAT= variable, and emit any checking of the
1097 result for errors. */
1099 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1101 ffeste_io_douio_ (ffebld expr)
1107 ffeinfoBasictype bt;
1111 bt = ffeinfo_basictype (ffebld_info (expr));
1112 kt = ffeinfo_kindtype (ffebld_info (expr));
1114 if ((bt == FFEINFO_basictypeANY)
1115 || (kt == FFEINFO_kindtypeANY))
1116 return error_mark_node;
1118 if (bt == FFEINFO_basictypeCOMPLEX)
1121 bt = FFEINFO_basictypeREAL;
1126 variable = ffecom_arg_ptr_to_expr (expr, &size);
1128 if ((variable == error_mark_node)
1129 || (size == error_mark_node))
1130 return error_mark_node;
1132 if (size == NULL_TREE) /* Already filled in for CHARACTER type. */
1133 { /* "(ftnlen) sizeof(type)" */
1134 size = size_binop (CEIL_DIV_EXPR,
1135 TYPE_SIZE_UNIT (ffecom_tree_type[bt][kt]),
1136 size_int (TYPE_PRECISION (char_type_node)
1138 #if 0 /* Assume that while it is possible that char * is wider than
1139 ftnlen, no object in Fortran space can get big enough for its
1140 size to be wider than ftnlen. I really hope nobody wastes
1141 time debugging a case where it can! */
1142 assert (TYPE_PRECISION (ffecom_f2c_ftnlen_type_node)
1143 >= TYPE_PRECISION (TREE_TYPE (size)));
1145 size = convert (ffecom_f2c_ftnlen_type_node, size);
1148 if (ffeinfo_rank (ffebld_info (expr)) == 0
1149 || TREE_CODE (TREE_TYPE (TREE_TYPE (variable))) != ARRAY_TYPE)
1151 = is_complex ? ffecom_f2c_ftnlen_two_node : ffecom_f2c_ftnlen_one_node;
1155 = size_binop (CEIL_DIV_EXPR,
1156 TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (variable))),
1157 convert (sizetype, size));
1158 num_elements = size_binop (CEIL_DIV_EXPR, num_elements,
1159 size_int (TYPE_PRECISION (char_type_node)
1161 num_elements = convert (ffecom_f2c_ftnlen_type_node,
1166 = ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
1169 variable = convert (string_type_node, variable);
1171 arglist = build_tree_list (NULL_TREE, num_elements);
1172 TREE_CHAIN (arglist) = build_tree_list (NULL_TREE, variable);
1173 TREE_CHAIN (TREE_CHAIN (arglist)) = build_tree_list (NULL_TREE, size);
1175 return ffecom_call_gfrt (FFECOM_gfrtDOUIO, arglist, NULL_TREE);
1179 /* Make arglist with ptr to BACKSPACE/ENDFILE/REWIND control list.
1181 Returns a tree suitable as an argument list containing a pointer to
1182 a BACKSPACE/ENDFILE/REWIND control list. First, generates that control
1183 list, if necessary, along with any static and run-time initializations
1184 that are needed as specified by the arguments to this function.
1186 Must ensure that all expressions are prepared before being evaluated,
1187 for any whose evaluation might result in the generation of temporaries.
1189 Note that this means this function causes a transition, within the
1190 current block being code-generated via the back end, from the
1191 declaration of variables (temporaries) to the expanding of expressions,
1194 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1196 ffeste_io_ialist_ (bool have_err,
1201 static tree f2c_alist_struct = NULL_TREE;
1206 bool constantp = TRUE;
1207 static tree errfield, unitfield;
1208 tree errinit, unitinit;
1210 static int mynumber = 0;
1212 if (f2c_alist_struct == NULL_TREE)
1216 ref = make_node (RECORD_TYPE);
1218 errfield = ffecom_decl_field (ref, NULL_TREE, "err",
1219 ffecom_f2c_flag_type_node);
1220 unitfield = ffecom_decl_field (ref, errfield, "unit",
1221 ffecom_f2c_ftnint_type_node);
1223 TYPE_FIELDS (ref) = errfield;
1226 ggc_add_tree_root (&f2c_alist_struct, 1);
1228 f2c_alist_struct = ref;
1231 /* Try to do as much compile-time initialization of the structure
1232 as possible, to save run time. */
1234 ffeste_f2c_init_flag_ (have_err, errinit);
1238 case FFESTV_unitNONE:
1239 case FFESTV_unitASTERISK:
1240 unitinit = build_int_2 (unit_dflt, 0);
1244 case FFESTV_unitINTEXPR:
1245 unitexp = ffecom_const_expr (unit_expr);
1250 unitinit = ffecom_integer_zero_node;
1256 assert ("bad unit spec" == NULL);
1257 unitinit = ffecom_integer_zero_node;
1262 inits = build_tree_list ((field = TYPE_FIELDS (f2c_alist_struct)), errinit);
1264 ffeste_f2c_init_next_ (unitinit);
1266 inits = build (CONSTRUCTOR, f2c_alist_struct, NULL_TREE, inits);
1267 TREE_CONSTANT (inits) = constantp ? 1 : 0;
1268 TREE_STATIC (inits) = 1;
1270 t = build_decl (VAR_DECL,
1271 ffecom_get_invented_identifier ("__g77_alist_%d",
1274 TREE_STATIC (t) = 1;
1275 t = ffecom_start_decl (t, 1);
1276 ffecom_finish_decl (t, inits, 0);
1278 /* Prepare run-time expressions. */
1281 ffecom_prepare_expr (unit_expr);
1283 ffecom_prepare_end ();
1285 /* Now evaluate run-time expressions as needed. */
1289 unitexp = ffecom_expr (unit_expr);
1290 ffeste_f2c_compile_ (unitfield, unitexp);
1293 ttype = build_pointer_type (TREE_TYPE (t));
1294 t = ffecom_1 (ADDR_EXPR, ttype, t);
1296 t = build_tree_list (NULL_TREE, t);
1302 /* Make arglist with ptr to external-I/O control list.
1304 Returns a tree suitable as an argument list containing a pointer to
1305 an external-I/O control list. First, generates that control
1306 list, if necessary, along with any static and run-time initializations
1307 that are needed as specified by the arguments to this function.
1309 Must ensure that all expressions are prepared before being evaluated,
1310 for any whose evaluation might result in the generation of temporaries.
1312 Note that this means this function causes a transition, within the
1313 current block being code-generated via the back end, from the
1314 declaration of variables (temporaries) to the expanding of expressions,
1317 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1319 ffeste_io_cilist_ (bool have_err,
1324 ffestvFormat format,
1325 ffestpFile *format_spec,
1329 static tree f2c_cilist_struct = NULL_TREE;
1334 bool constantp = TRUE;
1335 static tree errfield, unitfield, endfield, formatfield, recfield;
1336 tree errinit, unitinit, endinit, formatinit, recinit;
1337 tree unitexp, formatexp, recexp;
1338 static int mynumber = 0;
1340 if (f2c_cilist_struct == NULL_TREE)
1344 ref = make_node (RECORD_TYPE);
1346 errfield = ffecom_decl_field (ref, NULL_TREE, "err",
1347 ffecom_f2c_flag_type_node);
1348 unitfield = ffecom_decl_field (ref, errfield, "unit",
1349 ffecom_f2c_ftnint_type_node);
1350 endfield = ffecom_decl_field (ref, unitfield, "end",
1351 ffecom_f2c_flag_type_node);
1352 formatfield = ffecom_decl_field (ref, endfield, "format",
1354 recfield = ffecom_decl_field (ref, formatfield, "rec",
1355 ffecom_f2c_ftnint_type_node);
1357 TYPE_FIELDS (ref) = errfield;
1360 ggc_add_tree_root (&f2c_cilist_struct, 1);
1362 f2c_cilist_struct = ref;
1365 /* Try to do as much compile-time initialization of the structure
1366 as possible, to save run time. */
1368 ffeste_f2c_init_flag_ (have_err, errinit);
1372 case FFESTV_unitNONE:
1373 case FFESTV_unitASTERISK:
1374 unitinit = build_int_2 (unit_dflt, 0);
1378 case FFESTV_unitINTEXPR:
1379 unitexp = ffecom_const_expr (unit_expr);
1384 unitinit = ffecom_integer_zero_node;
1390 assert ("bad unit spec" == NULL);
1391 unitinit = ffecom_integer_zero_node;
1398 case FFESTV_formatNONE:
1399 formatinit = null_pointer_node;
1400 formatexp = formatinit;
1403 case FFESTV_formatLABEL:
1404 formatexp = error_mark_node;
1405 formatinit = ffecom_lookup_label (format_spec->u.label);
1406 if ((formatinit == NULL_TREE)
1407 || (TREE_CODE (formatinit) == ERROR_MARK))
1409 formatinit = ffecom_1 (ADDR_EXPR,
1410 build_pointer_type (void_type_node),
1412 TREE_CONSTANT (formatinit) = 1;
1415 case FFESTV_formatCHAREXPR:
1416 formatexp = ffecom_arg_ptr_to_const_expr (format_spec->u.expr, NULL);
1418 formatinit = formatexp;
1421 formatinit = null_pointer_node;
1426 case FFESTV_formatASTERISK:
1427 formatinit = null_pointer_node;
1428 formatexp = formatinit;
1431 case FFESTV_formatINTEXPR:
1432 formatinit = null_pointer_node;
1433 formatexp = ffecom_expr_assign (format_spec->u.expr);
1434 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (formatexp)))
1435 < GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
1436 error ("ASSIGNed FORMAT specifier is too small");
1437 formatexp = convert (string_type_node, formatexp);
1440 case FFESTV_formatNAMELIST:
1441 formatinit = ffecom_expr (format_spec->u.expr);
1442 formatexp = formatinit;
1446 assert ("bad format spec" == NULL);
1447 formatinit = integer_zero_node;
1448 formatexp = formatinit;
1452 ffeste_f2c_init_flag_ (have_end, endinit);
1455 recexp = ffecom_const_expr (rec_expr);
1457 recexp = ffecom_integer_zero_node;
1462 recinit = ffecom_integer_zero_node;
1466 inits = build_tree_list ((field = TYPE_FIELDS (f2c_cilist_struct)), errinit);
1468 ffeste_f2c_init_next_ (unitinit);
1469 ffeste_f2c_init_next_ (endinit);
1470 ffeste_f2c_init_next_ (formatinit);
1471 ffeste_f2c_init_next_ (recinit);
1473 inits = build (CONSTRUCTOR, f2c_cilist_struct, NULL_TREE, inits);
1474 TREE_CONSTANT (inits) = constantp ? 1 : 0;
1475 TREE_STATIC (inits) = 1;
1477 t = build_decl (VAR_DECL,
1478 ffecom_get_invented_identifier ("__g77_cilist_%d",
1481 TREE_STATIC (t) = 1;
1482 t = ffecom_start_decl (t, 1);
1483 ffecom_finish_decl (t, inits, 0);
1485 /* Prepare run-time expressions. */
1488 ffecom_prepare_expr (unit_expr);
1491 ffecom_prepare_arg_ptr_to_expr (format_spec->u.expr);
1494 ffecom_prepare_expr (rec_expr);
1496 ffecom_prepare_end ();
1498 /* Now evaluate run-time expressions as needed. */
1502 unitexp = ffecom_expr (unit_expr);
1503 ffeste_f2c_compile_ (unitfield, unitexp);
1508 formatexp = ffecom_arg_ptr_to_expr (format_spec->u.expr, NULL);
1509 ffeste_f2c_compile_ (formatfield, formatexp);
1511 else if (format == FFESTV_formatINTEXPR)
1512 ffeste_f2c_compile_ (formatfield, formatexp);
1516 recexp = ffecom_expr (rec_expr);
1517 ffeste_f2c_compile_ (recfield, recexp);
1520 ttype = build_pointer_type (TREE_TYPE (t));
1521 t = ffecom_1 (ADDR_EXPR, ttype, t);
1523 t = build_tree_list (NULL_TREE, t);
1529 /* Make arglist with ptr to CLOSE control list.
1531 Returns a tree suitable as an argument list containing a pointer to
1532 a CLOSE-statement control list. First, generates that control
1533 list, if necessary, along with any static and run-time initializations
1534 that are needed as specified by the arguments to this function.
1536 Must ensure that all expressions are prepared before being evaluated,
1537 for any whose evaluation might result in the generation of temporaries.
1539 Note that this means this function causes a transition, within the
1540 current block being code-generated via the back end, from the
1541 declaration of variables (temporaries) to the expanding of expressions,
1544 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1546 ffeste_io_cllist_ (bool have_err,
1548 ffestpFile *stat_spec)
1550 static tree f2c_close_struct = NULL_TREE;
1555 tree ignore; /* Ignore length info for certain fields. */
1556 bool constantp = TRUE;
1557 static tree errfield, unitfield, statfield;
1558 tree errinit, unitinit, statinit;
1559 tree unitexp, statexp;
1560 static int mynumber = 0;
1562 if (f2c_close_struct == NULL_TREE)
1566 ref = make_node (RECORD_TYPE);
1568 errfield = ffecom_decl_field (ref, NULL_TREE, "err",
1569 ffecom_f2c_flag_type_node);
1570 unitfield = ffecom_decl_field (ref, errfield, "unit",
1571 ffecom_f2c_ftnint_type_node);
1572 statfield = ffecom_decl_field (ref, unitfield, "stat",
1575 TYPE_FIELDS (ref) = errfield;
1578 ggc_add_tree_root (&f2c_close_struct, 1);
1580 f2c_close_struct = ref;
1583 /* Try to do as much compile-time initialization of the structure
1584 as possible, to save run time. */
1586 ffeste_f2c_init_flag_ (have_err, errinit);
1588 unitexp = ffecom_const_expr (unit_expr);
1593 unitinit = ffecom_integer_zero_node;
1597 ffeste_f2c_init_charnolen_ (statexp, statinit, stat_spec);
1599 inits = build_tree_list ((field = TYPE_FIELDS (f2c_close_struct)), errinit);
1601 ffeste_f2c_init_next_ (unitinit);
1602 ffeste_f2c_init_next_ (statinit);
1604 inits = build (CONSTRUCTOR, f2c_close_struct, NULL_TREE, inits);
1605 TREE_CONSTANT (inits) = constantp ? 1 : 0;
1606 TREE_STATIC (inits) = 1;
1608 t = build_decl (VAR_DECL,
1609 ffecom_get_invented_identifier ("__g77_cllist_%d",
1612 TREE_STATIC (t) = 1;
1613 t = ffecom_start_decl (t, 1);
1614 ffecom_finish_decl (t, inits, 0);
1616 /* Prepare run-time expressions. */
1619 ffecom_prepare_expr (unit_expr);
1622 ffecom_prepare_arg_ptr_to_expr (stat_spec->u.expr);
1624 ffecom_prepare_end ();
1626 /* Now evaluate run-time expressions as needed. */
1630 unitexp = ffecom_expr (unit_expr);
1631 ffeste_f2c_compile_ (unitfield, unitexp);
1634 ffeste_f2c_compile_charnolen_ (statfield, stat_spec, statexp);
1636 ttype = build_pointer_type (TREE_TYPE (t));
1637 t = ffecom_1 (ADDR_EXPR, ttype, t);
1639 t = build_tree_list (NULL_TREE, t);
1645 /* Make arglist with ptr to internal-I/O control list.
1647 Returns a tree suitable as an argument list containing a pointer to
1648 an internal-I/O control list. First, generates that control
1649 list, if necessary, along with any static and run-time initializations
1650 that are needed as specified by the arguments to this function.
1652 Must ensure that all expressions are prepared before being evaluated,
1653 for any whose evaluation might result in the generation of temporaries.
1655 Note that this means this function causes a transition, within the
1656 current block being code-generated via the back end, from the
1657 declaration of variables (temporaries) to the expanding of expressions,
1660 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1662 ffeste_io_icilist_ (bool have_err,
1665 ffestvFormat format,
1666 ffestpFile *format_spec)
1668 static tree f2c_icilist_struct = NULL_TREE;
1673 bool constantp = TRUE;
1674 static tree errfield, unitfield, endfield, formatfield, unitlenfield,
1676 tree errinit, unitinit, endinit, formatinit, unitleninit, unitnuminit;
1677 tree unitexp, formatexp, unitlenexp, unitnumexp;
1678 static int mynumber = 0;
1680 if (f2c_icilist_struct == NULL_TREE)
1684 ref = make_node (RECORD_TYPE);
1686 errfield = ffecom_decl_field (ref, NULL_TREE, "err",
1687 ffecom_f2c_flag_type_node);
1688 unitfield = ffecom_decl_field (ref, errfield, "unit",
1690 endfield = ffecom_decl_field (ref, unitfield, "end",
1691 ffecom_f2c_flag_type_node);
1692 formatfield = ffecom_decl_field (ref, endfield, "format",
1694 unitlenfield = ffecom_decl_field (ref, formatfield, "unitlen",
1695 ffecom_f2c_ftnint_type_node);
1696 unitnumfield = ffecom_decl_field (ref, unitlenfield, "unitnum",
1697 ffecom_f2c_ftnint_type_node);
1699 TYPE_FIELDS (ref) = errfield;
1702 ggc_add_tree_root (&f2c_icilist_struct, 1);
1704 f2c_icilist_struct = ref;
1707 /* Try to do as much compile-time initialization of the structure
1708 as possible, to save run time. */
1710 ffeste_f2c_init_flag_ (have_err, errinit);
1712 unitexp = ffecom_arg_ptr_to_const_expr (unit_expr, &unitlenexp);
1717 unitinit = null_pointer_node;
1721 unitleninit = unitlenexp;
1724 unitleninit = ffecom_integer_zero_node;
1728 /* Now see if we can fully initialize the number of elements, or
1729 if we have to compute that at run time. */
1730 if (ffeinfo_rank (ffebld_info (unit_expr)) == 0
1732 && TREE_CODE (TREE_TYPE (TREE_TYPE (unitexp))) != ARRAY_TYPE))
1734 /* Not an array, so just one element. */
1735 unitnuminit = ffecom_integer_one_node;
1736 unitnumexp = unitnuminit;
1738 else if (unitexp && unitlenexp)
1740 /* An array, but all the info is constant, so compute now. */
1742 = size_binop (CEIL_DIV_EXPR,
1743 TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (unitexp))),
1744 convert (sizetype, unitlenexp));
1745 unitnuminit = size_binop (CEIL_DIV_EXPR, unitnuminit,
1746 size_int (TYPE_PRECISION (char_type_node)
1748 unitnumexp = unitnuminit;
1752 /* Put off computing until run time. */
1753 unitnuminit = ffecom_integer_zero_node;
1754 unitnumexp = NULL_TREE;
1760 case FFESTV_formatNONE:
1761 formatinit = null_pointer_node;
1762 formatexp = formatinit;
1765 case FFESTV_formatLABEL:
1766 formatexp = error_mark_node;
1767 formatinit = ffecom_lookup_label (format_spec->u.label);
1768 if ((formatinit == NULL_TREE)
1769 || (TREE_CODE (formatinit) == ERROR_MARK))
1771 formatinit = ffecom_1 (ADDR_EXPR,
1772 build_pointer_type (void_type_node),
1774 TREE_CONSTANT (formatinit) = 1;
1777 case FFESTV_formatCHAREXPR:
1778 ffeste_f2c_init_format_ (formatexp, formatinit, format_spec);
1781 case FFESTV_formatASTERISK:
1782 formatinit = null_pointer_node;
1783 formatexp = formatinit;
1786 case FFESTV_formatINTEXPR:
1787 formatinit = null_pointer_node;
1788 formatexp = ffecom_expr_assign (format_spec->u.expr);
1789 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (formatexp)))
1790 < GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
1791 error ("ASSIGNed FORMAT specifier is too small");
1792 formatexp = convert (string_type_node, formatexp);
1796 assert ("bad format spec" == NULL);
1797 formatinit = ffecom_integer_zero_node;
1798 formatexp = formatinit;
1802 ffeste_f2c_init_flag_ (have_end, endinit);
1804 inits = build_tree_list ((field = TYPE_FIELDS (f2c_icilist_struct)),
1807 ffeste_f2c_init_next_ (unitinit);
1808 ffeste_f2c_init_next_ (endinit);
1809 ffeste_f2c_init_next_ (formatinit);
1810 ffeste_f2c_init_next_ (unitleninit);
1811 ffeste_f2c_init_next_ (unitnuminit);
1813 inits = build (CONSTRUCTOR, f2c_icilist_struct, NULL_TREE, inits);
1814 TREE_CONSTANT (inits) = constantp ? 1 : 0;
1815 TREE_STATIC (inits) = 1;
1817 t = build_decl (VAR_DECL,
1818 ffecom_get_invented_identifier ("__g77_icilist_%d",
1820 f2c_icilist_struct);
1821 TREE_STATIC (t) = 1;
1822 t = ffecom_start_decl (t, 1);
1823 ffecom_finish_decl (t, inits, 0);
1825 /* Prepare run-time expressions. */
1828 ffecom_prepare_arg_ptr_to_expr (unit_expr);
1830 ffeste_f2c_prepare_format_ (format_spec, formatexp);
1832 ffecom_prepare_end ();
1834 /* Now evaluate run-time expressions as needed. */
1836 if (! unitexp || ! unitlenexp)
1838 int need_unitexp = (! unitexp);
1839 int need_unitlenexp = (! unitlenexp);
1841 unitexp = ffecom_arg_ptr_to_expr (unit_expr, &unitlenexp);
1843 ffeste_f2c_compile_ (unitfield, unitexp);
1844 if (need_unitlenexp)
1845 ffeste_f2c_compile_ (unitlenfield, unitlenexp);
1849 && unitexp != error_mark_node
1850 && unitlenexp != error_mark_node)
1853 = size_binop (CEIL_DIV_EXPR,
1854 TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (unitexp))),
1855 convert (sizetype, unitlenexp));
1856 unitnumexp = size_binop (CEIL_DIV_EXPR, unitnumexp,
1857 size_int (TYPE_PRECISION (char_type_node)
1859 ffeste_f2c_compile_ (unitnumfield, unitnumexp);
1862 if (format == FFESTV_formatINTEXPR)
1863 ffeste_f2c_compile_ (formatfield, formatexp);
1865 ffeste_f2c_compile_format_ (formatfield, format_spec, formatexp);
1867 ttype = build_pointer_type (TREE_TYPE (t));
1868 t = ffecom_1 (ADDR_EXPR, ttype, t);
1870 t = build_tree_list (NULL_TREE, t);
1876 /* Make arglist with ptr to INQUIRE control list
1878 Returns a tree suitable as an argument list containing a pointer to
1879 an INQUIRE-statement control list. First, generates that control
1880 list, if necessary, along with any static and run-time initializations
1881 that are needed as specified by the arguments to this function.
1883 Must ensure that all expressions are prepared before being evaluated,
1884 for any whose evaluation might result in the generation of temporaries.
1886 Note that this means this function causes a transition, within the
1887 current block being code-generated via the back end, from the
1888 declaration of variables (temporaries) to the expanding of expressions,
1891 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1893 ffeste_io_inlist_ (bool have_err,
1894 ffestpFile *unit_spec,
1895 ffestpFile *file_spec,
1896 ffestpFile *exist_spec,
1897 ffestpFile *open_spec,
1898 ffestpFile *number_spec,
1899 ffestpFile *named_spec,
1900 ffestpFile *name_spec,
1901 ffestpFile *access_spec,
1902 ffestpFile *sequential_spec,
1903 ffestpFile *direct_spec,
1904 ffestpFile *form_spec,
1905 ffestpFile *formatted_spec,
1906 ffestpFile *unformatted_spec,
1907 ffestpFile *recl_spec,
1908 ffestpFile *nextrec_spec,
1909 ffestpFile *blank_spec)
1911 static tree f2c_inquire_struct = NULL_TREE;
1916 bool constantp = TRUE;
1917 static tree errfield, unitfield, filefield, filelenfield, existfield,
1918 openfield, numberfield, namedfield, namefield, namelenfield, accessfield,
1919 accesslenfield, sequentialfield, sequentiallenfield, directfield, directlenfield,
1920 formfield, formlenfield, formattedfield, formattedlenfield, unformattedfield,
1921 unformattedlenfield, reclfield, nextrecfield, blankfield, blanklenfield;
1922 tree errinit, unitinit, fileinit, fileleninit, existinit, openinit, numberinit,
1923 namedinit, nameinit, nameleninit, accessinit, accessleninit, sequentialinit,
1924 sequentialleninit, directinit, directleninit, forminit, formleninit,
1925 formattedinit, formattedleninit, unformattedinit, unformattedleninit,
1926 reclinit, nextrecinit, blankinit, blankleninit;
1928 unitexp, fileexp, filelenexp, existexp, openexp, numberexp, namedexp,
1929 nameexp, namelenexp, accessexp, accesslenexp, sequentialexp, sequentiallenexp,
1930 directexp, directlenexp, formexp, formlenexp, formattedexp, formattedlenexp,
1931 unformattedexp, unformattedlenexp, reclexp, nextrecexp, blankexp, blanklenexp;
1932 static int mynumber = 0;
1934 if (f2c_inquire_struct == NULL_TREE)
1938 ref = make_node (RECORD_TYPE);
1940 errfield = ffecom_decl_field (ref, NULL_TREE, "err",
1941 ffecom_f2c_flag_type_node);
1942 unitfield = ffecom_decl_field (ref, errfield, "unit",
1943 ffecom_f2c_ftnint_type_node);
1944 filefield = ffecom_decl_field (ref, unitfield, "file",
1946 filelenfield = ffecom_decl_field (ref, filefield, "filelen",
1947 ffecom_f2c_ftnlen_type_node);
1948 existfield = ffecom_decl_field (ref, filelenfield, "exist",
1949 ffecom_f2c_ptr_to_ftnint_type_node);
1950 openfield = ffecom_decl_field (ref, existfield, "open",
1951 ffecom_f2c_ptr_to_ftnint_type_node);
1952 numberfield = ffecom_decl_field (ref, openfield, "number",
1953 ffecom_f2c_ptr_to_ftnint_type_node);
1954 namedfield = ffecom_decl_field (ref, numberfield, "named",
1955 ffecom_f2c_ptr_to_ftnint_type_node);
1956 namefield = ffecom_decl_field (ref, namedfield, "name",
1958 namelenfield = ffecom_decl_field (ref, namefield, "namelen",
1959 ffecom_f2c_ftnlen_type_node);
1960 accessfield = ffecom_decl_field (ref, namelenfield, "access",
1962 accesslenfield = ffecom_decl_field (ref, accessfield, "accesslen",
1963 ffecom_f2c_ftnlen_type_node);
1964 sequentialfield = ffecom_decl_field (ref, accesslenfield, "sequential",
1966 sequentiallenfield = ffecom_decl_field (ref, sequentialfield,
1968 ffecom_f2c_ftnlen_type_node);
1969 directfield = ffecom_decl_field (ref, sequentiallenfield, "direct",
1971 directlenfield = ffecom_decl_field (ref, directfield, "directlen",
1972 ffecom_f2c_ftnlen_type_node);
1973 formfield = ffecom_decl_field (ref, directlenfield, "form",
1975 formlenfield = ffecom_decl_field (ref, formfield, "formlen",
1976 ffecom_f2c_ftnlen_type_node);
1977 formattedfield = ffecom_decl_field (ref, formlenfield, "formatted",
1979 formattedlenfield = ffecom_decl_field (ref, formattedfield,
1981 ffecom_f2c_ftnlen_type_node);
1982 unformattedfield = ffecom_decl_field (ref, formattedlenfield,
1985 unformattedlenfield = ffecom_decl_field (ref, unformattedfield,
1987 ffecom_f2c_ftnlen_type_node);
1988 reclfield = ffecom_decl_field (ref, unformattedlenfield, "recl",
1989 ffecom_f2c_ptr_to_ftnint_type_node);
1990 nextrecfield = ffecom_decl_field (ref, reclfield, "nextrec",
1991 ffecom_f2c_ptr_to_ftnint_type_node);
1992 blankfield = ffecom_decl_field (ref, nextrecfield, "blank",
1994 blanklenfield = ffecom_decl_field (ref, blankfield, "blanklen",
1995 ffecom_f2c_ftnlen_type_node);
1997 TYPE_FIELDS (ref) = errfield;
2000 ggc_add_tree_root (&f2c_inquire_struct, 1);
2002 f2c_inquire_struct = ref;
2005 /* Try to do as much compile-time initialization of the structure
2006 as possible, to save run time. */
2008 ffeste_f2c_init_flag_ (have_err, errinit);
2009 ffeste_f2c_init_int_ (unitexp, unitinit, unit_spec);
2010 ffeste_f2c_init_char_ (fileexp, fileinit, filelenexp, fileleninit,
2012 ffeste_f2c_init_ptrtoint_ (existexp, existinit, exist_spec);
2013 ffeste_f2c_init_ptrtoint_ (openexp, openinit, open_spec);
2014 ffeste_f2c_init_ptrtoint_ (numberexp, numberinit, number_spec);
2015 ffeste_f2c_init_ptrtoint_ (namedexp, namedinit, named_spec);
2016 ffeste_f2c_init_char_ (nameexp, nameinit, namelenexp, nameleninit,
2018 ffeste_f2c_init_char_ (accessexp, accessinit, accesslenexp,
2019 accessleninit, access_spec);
2020 ffeste_f2c_init_char_ (sequentialexp, sequentialinit, sequentiallenexp,
2021 sequentialleninit, sequential_spec);
2022 ffeste_f2c_init_char_ (directexp, directinit, directlenexp,
2023 directleninit, direct_spec);
2024 ffeste_f2c_init_char_ (formexp, forminit, formlenexp, formleninit,
2026 ffeste_f2c_init_char_ (formattedexp, formattedinit,
2027 formattedlenexp, formattedleninit, formatted_spec);
2028 ffeste_f2c_init_char_ (unformattedexp, unformattedinit, unformattedlenexp,
2029 unformattedleninit, unformatted_spec);
2030 ffeste_f2c_init_ptrtoint_ (reclexp, reclinit, recl_spec);
2031 ffeste_f2c_init_ptrtoint_ (nextrecexp, nextrecinit, nextrec_spec);
2032 ffeste_f2c_init_char_ (blankexp, blankinit, blanklenexp,
2033 blankleninit, blank_spec);
2035 inits = build_tree_list ((field = TYPE_FIELDS (f2c_inquire_struct)),
2038 ffeste_f2c_init_next_ (unitinit);
2039 ffeste_f2c_init_next_ (fileinit);
2040 ffeste_f2c_init_next_ (fileleninit);
2041 ffeste_f2c_init_next_ (existinit);
2042 ffeste_f2c_init_next_ (openinit);
2043 ffeste_f2c_init_next_ (numberinit);
2044 ffeste_f2c_init_next_ (namedinit);
2045 ffeste_f2c_init_next_ (nameinit);
2046 ffeste_f2c_init_next_ (nameleninit);
2047 ffeste_f2c_init_next_ (accessinit);
2048 ffeste_f2c_init_next_ (accessleninit);
2049 ffeste_f2c_init_next_ (sequentialinit);
2050 ffeste_f2c_init_next_ (sequentialleninit);
2051 ffeste_f2c_init_next_ (directinit);
2052 ffeste_f2c_init_next_ (directleninit);
2053 ffeste_f2c_init_next_ (forminit);
2054 ffeste_f2c_init_next_ (formleninit);
2055 ffeste_f2c_init_next_ (formattedinit);
2056 ffeste_f2c_init_next_ (formattedleninit);
2057 ffeste_f2c_init_next_ (unformattedinit);
2058 ffeste_f2c_init_next_ (unformattedleninit);
2059 ffeste_f2c_init_next_ (reclinit);
2060 ffeste_f2c_init_next_ (nextrecinit);
2061 ffeste_f2c_init_next_ (blankinit);
2062 ffeste_f2c_init_next_ (blankleninit);
2064 inits = build (CONSTRUCTOR, f2c_inquire_struct, NULL_TREE, inits);
2065 TREE_CONSTANT (inits) = constantp ? 1 : 0;
2066 TREE_STATIC (inits) = 1;
2068 t = build_decl (VAR_DECL,
2069 ffecom_get_invented_identifier ("__g77_inlist_%d",
2071 f2c_inquire_struct);
2072 TREE_STATIC (t) = 1;
2073 t = ffecom_start_decl (t, 1);
2074 ffecom_finish_decl (t, inits, 0);
2076 /* Prepare run-time expressions. */
2078 ffeste_f2c_prepare_int_ (unit_spec, unitexp);
2079 ffeste_f2c_prepare_char_ (file_spec, fileexp);
2080 ffeste_f2c_prepare_ptrtoint_ (exist_spec, existexp);
2081 ffeste_f2c_prepare_ptrtoint_ (open_spec, openexp);
2082 ffeste_f2c_prepare_ptrtoint_ (number_spec, numberexp);
2083 ffeste_f2c_prepare_ptrtoint_ (named_spec, namedexp);
2084 ffeste_f2c_prepare_char_ (name_spec, nameexp);
2085 ffeste_f2c_prepare_char_ (access_spec, accessexp);
2086 ffeste_f2c_prepare_char_ (sequential_spec, sequentialexp);
2087 ffeste_f2c_prepare_char_ (direct_spec, directexp);
2088 ffeste_f2c_prepare_char_ (form_spec, formexp);
2089 ffeste_f2c_prepare_char_ (formatted_spec, formattedexp);
2090 ffeste_f2c_prepare_char_ (unformatted_spec, unformattedexp);
2091 ffeste_f2c_prepare_ptrtoint_ (recl_spec, reclexp);
2092 ffeste_f2c_prepare_ptrtoint_ (nextrec_spec, nextrecexp);
2093 ffeste_f2c_prepare_char_ (blank_spec, blankexp);
2095 ffecom_prepare_end ();
2097 /* Now evaluate run-time expressions as needed. */
2099 ffeste_f2c_compile_int_ (unitfield, unit_spec, unitexp);
2100 ffeste_f2c_compile_char_ (filefield, filelenfield, file_spec,
2101 fileexp, filelenexp);
2102 ffeste_f2c_compile_ptrtoint_ (existfield, exist_spec, existexp);
2103 ffeste_f2c_compile_ptrtoint_ (openfield, open_spec, openexp);
2104 ffeste_f2c_compile_ptrtoint_ (numberfield, number_spec, numberexp);
2105 ffeste_f2c_compile_ptrtoint_ (namedfield, named_spec, namedexp);
2106 ffeste_f2c_compile_char_ (namefield, namelenfield, name_spec, nameexp,
2108 ffeste_f2c_compile_char_ (accessfield, accesslenfield, access_spec,
2109 accessexp, accesslenexp);
2110 ffeste_f2c_compile_char_ (sequentialfield, sequentiallenfield,
2111 sequential_spec, sequentialexp,
2113 ffeste_f2c_compile_char_ (directfield, directlenfield, direct_spec,
2114 directexp, directlenexp);
2115 ffeste_f2c_compile_char_ (formfield, formlenfield, form_spec, formexp,
2117 ffeste_f2c_compile_char_ (formattedfield, formattedlenfield, formatted_spec,
2118 formattedexp, formattedlenexp);
2119 ffeste_f2c_compile_char_ (unformattedfield, unformattedlenfield,
2120 unformatted_spec, unformattedexp,
2122 ffeste_f2c_compile_ptrtoint_ (reclfield, recl_spec, reclexp);
2123 ffeste_f2c_compile_ptrtoint_ (nextrecfield, nextrec_spec, nextrecexp);
2124 ffeste_f2c_compile_char_ (blankfield, blanklenfield, blank_spec, blankexp,
2127 ttype = build_pointer_type (TREE_TYPE (t));
2128 t = ffecom_1 (ADDR_EXPR, ttype, t);
2130 t = build_tree_list (NULL_TREE, t);
2136 /* Make arglist with ptr to OPEN control list
2138 Returns a tree suitable as an argument list containing a pointer to
2139 an OPEN-statement control list. First, generates that control
2140 list, if necessary, along with any static and run-time initializations
2141 that are needed as specified by the arguments to this function.
2143 Must ensure that all expressions are prepared before being evaluated,
2144 for any whose evaluation might result in the generation of temporaries.
2146 Note that this means this function causes a transition, within the
2147 current block being code-generated via the back end, from the
2148 declaration of variables (temporaries) to the expanding of expressions,
2151 #if FFECOM_targetCURRENT == FFECOM_targetGCC
2153 ffeste_io_olist_ (bool have_err,
2155 ffestpFile *file_spec,
2156 ffestpFile *stat_spec,
2157 ffestpFile *access_spec,
2158 ffestpFile *form_spec,
2159 ffestpFile *recl_spec,
2160 ffestpFile *blank_spec)
2162 static tree f2c_open_struct = NULL_TREE;
2167 tree ignore; /* Ignore length info for certain fields. */
2168 bool constantp = TRUE;
2169 static tree errfield, unitfield, filefield, filelenfield, statfield,
2170 accessfield, formfield, reclfield, blankfield;
2171 tree errinit, unitinit, fileinit, fileleninit, statinit, accessinit,
2172 forminit, reclinit, blankinit;
2174 unitexp, fileexp, filelenexp, statexp, accessexp, formexp, reclexp,
2176 static int mynumber = 0;
2178 if (f2c_open_struct == NULL_TREE)
2182 ref = make_node (RECORD_TYPE);
2184 errfield = ffecom_decl_field (ref, NULL_TREE, "err",
2185 ffecom_f2c_flag_type_node);
2186 unitfield = ffecom_decl_field (ref, errfield, "unit",
2187 ffecom_f2c_ftnint_type_node);
2188 filefield = ffecom_decl_field (ref, unitfield, "file",
2190 filelenfield = ffecom_decl_field (ref, filefield, "filelen",
2191 ffecom_f2c_ftnlen_type_node);
2192 statfield = ffecom_decl_field (ref, filelenfield, "stat",
2194 accessfield = ffecom_decl_field (ref, statfield, "access",
2196 formfield = ffecom_decl_field (ref, accessfield, "form",
2198 reclfield = ffecom_decl_field (ref, formfield, "recl",
2199 ffecom_f2c_ftnint_type_node);
2200 blankfield = ffecom_decl_field (ref, reclfield, "blank",
2203 TYPE_FIELDS (ref) = errfield;
2206 ggc_add_tree_root (&f2c_open_struct, 1);
2208 f2c_open_struct = ref;
2211 /* Try to do as much compile-time initialization of the structure
2212 as possible, to save run time. */
2214 ffeste_f2c_init_flag_ (have_err, errinit);
2216 unitexp = ffecom_const_expr (unit_expr);
2221 unitinit = ffecom_integer_zero_node;
2225 ffeste_f2c_init_char_ (fileexp, fileinit, filelenexp, fileleninit,
2227 ffeste_f2c_init_charnolen_ (statexp, statinit, stat_spec);
2228 ffeste_f2c_init_charnolen_ (accessexp, accessinit, access_spec);
2229 ffeste_f2c_init_charnolen_ (formexp, forminit, form_spec);
2230 ffeste_f2c_init_int_ (reclexp, reclinit, recl_spec);
2231 ffeste_f2c_init_charnolen_ (blankexp, blankinit, blank_spec);
2233 inits = build_tree_list ((field = TYPE_FIELDS (f2c_open_struct)), errinit);
2235 ffeste_f2c_init_next_ (unitinit);
2236 ffeste_f2c_init_next_ (fileinit);
2237 ffeste_f2c_init_next_ (fileleninit);
2238 ffeste_f2c_init_next_ (statinit);
2239 ffeste_f2c_init_next_ (accessinit);
2240 ffeste_f2c_init_next_ (forminit);
2241 ffeste_f2c_init_next_ (reclinit);
2242 ffeste_f2c_init_next_ (blankinit);
2244 inits = build (CONSTRUCTOR, f2c_open_struct, NULL_TREE, inits);
2245 TREE_CONSTANT (inits) = constantp ? 1 : 0;
2246 TREE_STATIC (inits) = 1;
2248 t = build_decl (VAR_DECL,
2249 ffecom_get_invented_identifier ("__g77_olist_%d",
2252 TREE_STATIC (t) = 1;
2253 t = ffecom_start_decl (t, 1);
2254 ffecom_finish_decl (t, inits, 0);
2256 /* Prepare run-time expressions. */
2259 ffecom_prepare_expr (unit_expr);
2261 ffeste_f2c_prepare_char_ (file_spec, fileexp);
2262 ffeste_f2c_prepare_charnolen_ (stat_spec, statexp);
2263 ffeste_f2c_prepare_charnolen_ (access_spec, accessexp);
2264 ffeste_f2c_prepare_charnolen_ (form_spec, formexp);
2265 ffeste_f2c_prepare_int_ (recl_spec, reclexp);
2266 ffeste_f2c_prepare_charnolen_ (blank_spec, blankexp);
2268 ffecom_prepare_end ();
2270 /* Now evaluate run-time expressions as needed. */
2274 unitexp = ffecom_expr (unit_expr);
2275 ffeste_f2c_compile_ (unitfield, unitexp);
2278 ffeste_f2c_compile_char_ (filefield, filelenfield, file_spec, fileexp,
2280 ffeste_f2c_compile_charnolen_ (statfield, stat_spec, statexp);
2281 ffeste_f2c_compile_charnolen_ (accessfield, access_spec, accessexp);
2282 ffeste_f2c_compile_charnolen_ (formfield, form_spec, formexp);
2283 ffeste_f2c_compile_int_ (reclfield, recl_spec, reclexp);
2284 ffeste_f2c_compile_charnolen_ (blankfield, blank_spec, blankexp);
2286 ttype = build_pointer_type (TREE_TYPE (t));
2287 t = ffecom_1 (ADDR_EXPR, ttype, t);
2289 t = build_tree_list (NULL_TREE, t);
2295 /* Display file-statement specifier. */
2297 #if FFECOM_targetCURRENT == FFECOM_targetFFE
2299 ffeste_subr_file_ (const char *kw, ffestpFile *spec)
2301 if (!spec->kw_or_val_present)
2304 if (spec->value_present)
2306 fputc ('=', dmpout);
2307 if (spec->value_is_label)
2309 assert (spec->value_is_label == 2); /* Temporary checking only. */
2310 fprintf (dmpout, "%" ffelabValue_f "u",
2311 ffelab_value (spec->u.label));
2314 ffebld_dump (spec->u.expr);
2316 fputc (',', dmpout);
2320 /* Generate code for BACKSPACE/ENDFILE/REWIND. */
2322 #if FFECOM_targetCURRENT == FFECOM_targetGCC
2324 ffeste_subr_beru_ (ffestpBeruStmt *info, ffecomGfrt rt)
2330 ffeste_emit_line_note_ ();
2332 #define specified(something) (info->beru_spec[something].kw_or_val_present)
2334 iostat = specified (FFESTP_beruixIOSTAT);
2335 errl = specified (FFESTP_beruixERR);
2339 /* ~~For now, we assume the unit number is specified and is not ASTERISK,
2340 because the FFE doesn't support BACKSPACE(*) and rejects a BACKSPACE
2341 without any unit specifier. f2c, however, supports the former
2342 construct. When it is time to add this feature to the FFE, which
2343 probably is fairly easy, ffestc_R919 and company will want to pass an
2344 ffestvUnit indicator of FFESTV_unitINTEXPR or _unitASTERISK to
2345 ffeste_R919 and company, and they will want to pass that same value to
2346 this function, and that argument will replace the constant _unitINTEXPR_
2347 in the call below. Right now, the default unit number, 6, is ignored. */
2349 ffeste_start_stmt_ ();
2353 /* Have ERR= specification. */
2357 = ffecom_lookup_label
2358 (info->beru_spec[FFESTP_beruixERR].u.label);
2359 ffeste_io_abort_is_temp_ = FALSE;
2363 /* No ERR= specification. */
2365 ffeste_io_err_ = NULL_TREE;
2367 if ((ffeste_io_abort_is_temp_ = iostat))
2368 ffeste_io_abort_ = ffecom_temp_label ();
2370 ffeste_io_abort_ = NULL_TREE;
2375 /* Have IOSTAT= specification. */
2377 ffeste_io_iostat_is_temp_ = FALSE;
2378 ffeste_io_iostat_ = ffecom_expr
2379 (info->beru_spec[FFESTP_beruixIOSTAT].u.expr);
2381 else if (ffeste_io_abort_ != NULL_TREE)
2383 /* Have no IOSTAT= but have ERR=. */
2385 ffeste_io_iostat_is_temp_ = TRUE;
2387 = ffecom_make_tempvar ("beru", ffecom_integer_type_node,
2388 FFETARGET_charactersizeNONE, -1);
2392 /* No IOSTAT= or ERR= specification. */
2394 ffeste_io_iostat_is_temp_ = FALSE;
2395 ffeste_io_iostat_ = NULL_TREE;
2398 /* Now prescan, then convert, all the arguments. */
2400 alist = ffeste_io_ialist_ (errl || iostat, FFESTV_unitINTEXPR,
2401 info->beru_spec[FFESTP_beruixUNIT].u.expr, 6);
2403 /* Don't generate "if (iostat != 0) goto label;" if label is temp abort
2404 label, since we're gonna fall through to there anyway. */
2406 ffeste_io_call_ (ffecom_call_gfrt (rt, alist, NULL_TREE),
2407 ! ffeste_io_abort_is_temp_);
2409 /* If we've got a temp label, generate its code here. */
2411 if (ffeste_io_abort_is_temp_)
2413 DECL_INITIAL (ffeste_io_abort_) = error_mark_node;
2415 expand_label (ffeste_io_abort_);
2417 assert (ffeste_io_err_ == NULL_TREE);
2420 ffeste_end_stmt_ ();
2426 Also invoked by _labeldef_branch_finish_ (or, in cases
2427 of errors, other _labeldef_ functions) when the label definition is
2428 for a DO-target (LOOPEND) label, once per matching/outstanding DO
2429 block on the stack. */
2432 ffeste_do (ffestw block)
2434 #if FFECOM_targetCURRENT == FFECOM_targetFFE
2435 fputs ("+ END_DO\n", dmpout);
2436 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
2437 ffeste_emit_line_note_ ();
2439 if (ffestw_do_tvar (block) == 0)
2441 expand_end_loop (); /* DO WHILE and just DO. */
2443 ffeste_end_block_ (block);
2446 ffeste_end_iterdo_ (block,
2447 ffestw_do_tvar (block),
2448 ffestw_do_incr_saved (block),
2449 ffestw_do_count_var (block));
2455 /* End of statement following logical IF.
2457 Applies to *only* logical IF, not to IF-THEN. */
2462 #if FFECOM_targetCURRENT == FFECOM_targetFFE
2463 fputs ("+ END_IF\n", dmpout); /* Also see ffeste_R806. */
2464 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
2465 ffeste_emit_line_note_ ();
2469 ffeste_end_block_ (NULL);
2475 /* Generate "code" for branch label definition. */
2478 ffeste_labeldef_branch (ffelab label)
2480 #if FFECOM_targetCURRENT == FFECOM_targetFFE
2481 fprintf (dmpout, "+ label %lu\n", ffelab_value (label));
2482 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
2486 glabel = ffecom_lookup_label (label);
2487 assert (glabel != NULL_TREE);
2488 if (TREE_CODE (glabel) == ERROR_MARK)
2491 assert (DECL_INITIAL (glabel) == NULL_TREE);
2493 DECL_INITIAL (glabel) = error_mark_node;
2494 DECL_SOURCE_FILE (glabel) = ffelab_definition_filename (label);
2495 DECL_SOURCE_LINE (glabel) = ffelab_definition_filelinenum (label);
2499 expand_label (glabel);
2506 /* Generate "code" for FORMAT label definition. */
2509 ffeste_labeldef_format (ffelab label)
2511 #if FFECOM_targetCURRENT == FFECOM_targetFFE
2512 fprintf (dmpout, "$ label %lu\n", ffelab_value (label));
2513 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
2514 ffeste_label_formatdef_ = label;
2520 /* Assignment statement (outside of WHERE). */
2523 ffeste_R737A (ffebld dest, ffebld source)
2525 ffeste_check_simple_ ();
2527 #if FFECOM_targetCURRENT == FFECOM_targetFFE
2528 fputs ("+ let ", dmpout);
2530 fputs ("=", dmpout);
2531 ffebld_dump (source);
2532 fputc ('\n', dmpout);
2533 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
2534 ffeste_emit_line_note_ ();
2536 ffeste_start_stmt_ ();
2538 ffecom_expand_let_stmt (dest, source);
2540 ffeste_end_stmt_ ();
2546 /* Block IF (IF-THEN) statement. */
2549 ffeste_R803 (ffestw block, ffebld expr)
2551 ffeste_check_simple_ ();
2553 #if FFECOM_targetCURRENT == FFECOM_targetFFE
2554 fputs ("+ IF_block (", dmpout);
2556 fputs (")\n", dmpout);
2557 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
2561 ffeste_emit_line_note_ ();
2563 ffeste_start_block_ (block);
2565 temp = ffecom_make_tempvar ("ifthen", integer_type_node,
2566 FFETARGET_charactersizeNONE, -1);
2568 ffeste_start_stmt_ ();
2570 ffecom_prepare_expr (expr);
2572 if (ffecom_prepare_end ())
2576 result = ffecom_modify (void_type_node,
2578 ffecom_truth_value (ffecom_expr (expr)));
2580 expand_expr_stmt (result);
2582 ffeste_end_stmt_ ();
2586 ffeste_end_stmt_ ();
2588 temp = ffecom_truth_value (ffecom_expr (expr));
2591 expand_start_cond (temp, 0);
2593 /* No fake `else' constructs introduced (yet). */
2594 ffestw_set_ifthen_fake_else (block, 0);
2601 /* ELSE IF statement. */
2604 ffeste_R804 (ffestw block, ffebld expr)
2606 ffeste_check_simple_ ();
2608 #if FFECOM_targetCURRENT == FFECOM_targetFFE
2609 fputs ("+ ELSE_IF (", dmpout);
2611 fputs (")\n", dmpout);
2612 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
2616 ffeste_emit_line_note_ ();
2618 /* Since ELSEIF(expr) might require preparations for expr,
2619 implement as ELSE; prepare-expr; IF (expr) THEN ...; ENDIF. */
2621 expand_start_else ();
2623 ffeste_start_block_ (block);
2625 temp = ffecom_make_tempvar ("elseif", integer_type_node,
2626 FFETARGET_charactersizeNONE, -1);
2628 ffeste_start_stmt_ ();
2630 ffecom_prepare_expr (expr);
2632 if (ffecom_prepare_end ())
2636 result = ffecom_modify (void_type_node,
2638 ffecom_truth_value (ffecom_expr (expr)));
2640 expand_expr_stmt (result);
2642 ffeste_end_stmt_ ();
2646 /* In this case, we could probably have used expand_start_elseif
2647 instead, saving the need for a fake `else' construct. But,
2648 until it's clear that'd improve performance, it's easier this
2649 way, since we have to expand_start_else before we get to this
2650 test, given the current design. */
2652 ffeste_end_stmt_ ();
2654 temp = ffecom_truth_value (ffecom_expr (expr));
2657 expand_start_cond (temp, 0);
2659 /* Increment number of fake `else' constructs introduced. */
2660 ffestw_set_ifthen_fake_else (block,
2661 ffestw_ifthen_fake_else (block) + 1);
2668 /* ELSE statement. */
2671 ffeste_R805 (ffestw block UNUSED)
2673 ffeste_check_simple_ ();
2675 #if FFECOM_targetCURRENT == FFECOM_targetFFE
2676 fputs ("+ ELSE\n", dmpout);
2677 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
2678 ffeste_emit_line_note_ ();
2680 expand_start_else ();
2686 /* END IF statement. */
2689 ffeste_R806 (ffestw block)
2691 #if FFECOM_targetCURRENT == FFECOM_targetFFE
2692 fputs ("+ END_IF_then\n", dmpout); /* Also see ffeste_shriek_if_. */
2693 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
2695 int i = ffestw_ifthen_fake_else (block) + 1;
2697 ffeste_emit_line_note_ ();
2703 ffeste_end_block_ (block);
2711 /* Logical IF statement. */
2714 ffeste_R807 (ffebld expr)
2716 ffeste_check_simple_ ();
2718 #if FFECOM_targetCURRENT == FFECOM_targetFFE
2719 fputs ("+ IF_logical (", dmpout);
2721 fputs (")\n", dmpout);
2722 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
2726 ffeste_emit_line_note_ ();
2728 ffeste_start_block_ (NULL);
2730 temp = ffecom_make_tempvar ("if", integer_type_node,
2731 FFETARGET_charactersizeNONE, -1);
2733 ffeste_start_stmt_ ();
2735 ffecom_prepare_expr (expr);
2737 if (ffecom_prepare_end ())
2741 result = ffecom_modify (void_type_node,
2743 ffecom_truth_value (ffecom_expr (expr)));
2745 expand_expr_stmt (result);
2747 ffeste_end_stmt_ ();
2751 ffeste_end_stmt_ ();
2753 temp = ffecom_truth_value (ffecom_expr (expr));
2756 expand_start_cond (temp, 0);
2763 /* SELECT CASE statement. */
2766 ffeste_R809 (ffestw block, ffebld expr)
2768 ffeste_check_simple_ ();
2770 #if FFECOM_targetCURRENT == FFECOM_targetFFE
2771 fputs ("+ SELECT_CASE (", dmpout);
2773 fputs (")\n", dmpout);
2774 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
2775 ffeste_emit_line_note_ ();
2777 ffeste_start_block_ (block);
2780 || (ffeinfo_basictype (ffebld_info (expr))
2781 == FFEINFO_basictypeANY))
2782 ffestw_set_select_texpr (block, error_mark_node);
2783 else if (ffeinfo_basictype (ffebld_info (expr))
2784 == FFEINFO_basictypeCHARACTER)
2786 /* ~~~Someday handle CHARACTER*1, CHARACTER*N */
2788 ffebad_start_msg ("SELECT CASE on CHARACTER type (at %0) not supported -- sorry",
2789 FFEBAD_severityFATAL);
2790 ffebad_here (0, ffestw_line (block), ffestw_col (block));
2792 ffestw_set_select_texpr (block, error_mark_node);
2799 result = ffecom_make_tempvar ("select", ffecom_type_expr (expr),
2800 ffeinfo_size (ffebld_info (expr)),
2803 ffeste_start_stmt_ ();
2805 ffecom_prepare_expr (expr);
2807 ffecom_prepare_end ();
2809 texpr = ffecom_expr (expr);
2811 assert (TYPE_MAIN_VARIANT (TREE_TYPE (texpr))
2812 == TYPE_MAIN_VARIANT (TREE_TYPE (result)));
2814 texpr = ffecom_modify (void_type_node,
2817 expand_expr_stmt (texpr);
2819 ffeste_end_stmt_ ();
2821 expand_start_case (1, result, TREE_TYPE (result),
2822 "SELECT CASE statement");
2823 ffestw_set_select_texpr (block, texpr);
2824 ffestw_set_select_break (block, FALSE);
2833 If casenum is 0, it's CASE DEFAULT. Else it's the case ranges at
2834 the start of the first_stmt list in the select object at the top of
2835 the stack that match casenum. */
2838 ffeste_R810 (ffestw block, unsigned long casenum)
2840 ffestwSelect s = ffestw_select (block);
2843 ffeste_check_simple_ ();
2845 if (s->first_stmt == (ffestwCase) &s->first_rel)
2850 #if FFECOM_targetCURRENT == FFECOM_targetFFE
2851 if ((c == NULL) || (casenum != c->casenum))
2853 if (casenum == 0) /* Intentional CASE DEFAULT. */
2854 fputs ("+ CASE_DEFAULT", dmpout);
2860 fputs ("+ CASE (", dmpout);
2864 fputc (',', dmpout);
2868 ffebld_constant_dump (c->low);
2869 if (c->low != c->high)
2871 fputc (':', dmpout);
2872 if (c->high != NULL)
2873 ffebld_constant_dump (c->high);
2877 c->previous_stmt->previous_stmt->next_stmt = c;
2878 c->previous_stmt = c->previous_stmt->previous_stmt;
2880 while ((c != (ffestwCase) &s->first_rel) && (casenum == c->casenum));
2881 fputc (')', dmpout);
2884 fputc ('\n', dmpout);
2885 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
2893 ffeste_emit_line_note_ ();
2895 if (ffestw_select_texpr (block) == error_mark_node)
2898 /* ~~~Someday handle CHARACTER*1, CHARACTER*N */
2900 tlabel = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
2902 if (ffestw_select_break (block))
2903 expand_exit_something ();
2905 ffestw_set_select_break (block, TRUE);
2907 if ((c == NULL) || (casenum != c->casenum))
2909 if (casenum == 0) /* Intentional CASE DEFAULT. */
2911 pushok = pushcase (NULL_TREE, 0, tlabel, &duplicate);
2912 assert (pushok == 0);
2918 texprlow = (c->low == NULL) ? NULL_TREE
2919 : ffecom_constantunion (&ffebld_constant_union (c->low), s->type,
2920 s->kindtype, ffecom_tree_type[s->type][s->kindtype]);
2921 if (c->low != c->high)
2923 texprhigh = (c->high == NULL) ? NULL_TREE
2924 : ffecom_constantunion (&ffebld_constant_union (c->high),
2925 s->type, s->kindtype, ffecom_tree_type[s->type][s->kindtype]);
2926 pushok = pushcase_range (texprlow, texprhigh, convert,
2927 tlabel, &duplicate);
2930 pushok = pushcase (texprlow, convert, tlabel, &duplicate);
2931 assert (pushok == 0);
2934 c->previous_stmt->previous_stmt->next_stmt = c;
2935 c->previous_stmt = c->previous_stmt->previous_stmt;
2937 while ((c != (ffestwCase) &s->first_rel) && (casenum == c->casenum));
2944 /* END SELECT statement. */
2947 ffeste_R811 (ffestw block)
2949 #if FFECOM_targetCURRENT == FFECOM_targetFFE
2950 fputs ("+ END_SELECT\n", dmpout);
2951 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
2952 ffeste_emit_line_note_ ();
2954 /* ~~~Someday handle CHARACTER*1, CHARACTER*N */
2956 if (TREE_CODE (ffestw_select_texpr (block)) != ERROR_MARK)
2957 expand_end_case (ffestw_select_texpr (block));
2959 ffeste_end_block_ (block);
2965 /* Iterative DO statement. */
2968 ffeste_R819A (ffestw block, ffelab label UNUSED, ffebld var,
2969 ffebld start, ffelexToken start_token,
2970 ffebld end, ffelexToken end_token,
2971 ffebld incr, ffelexToken incr_token)
2973 ffeste_check_simple_ ();
2975 #if FFECOM_targetCURRENT == FFECOM_targetFFE
2976 if ((ffebld_op (incr) == FFEBLD_opCONTER)
2977 && (ffebld_constant_is_zero (ffebld_conter (incr))))
2979 ffebad_start (FFEBAD_DO_STEP_ZERO);
2980 ffebad_here (0, ffelex_token_where_line (incr_token),
2981 ffelex_token_where_column (incr_token));
2982 ffebad_string ("Iterative DO loop");
2984 /* Don't bother replacing it with 1 yet. */
2988 fputs ("+ DO_iterative_nonlabeled (", dmpout);
2990 fprintf (dmpout, "+ DO_iterative_labeled %lu (", ffelab_value (label));
2992 fputc ('=', dmpout);
2993 ffebld_dump (start);
2994 fputc (',', dmpout);
2996 fputc (',', dmpout);
2998 fputs (")\n", dmpout);
2999 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
3001 ffeste_emit_line_note_ ();
3003 ffeste_begin_iterdo_ (block, NULL, NULL, NULL,
3008 "Iterative DO loop");
3015 /* DO WHILE statement. */
3018 ffeste_R819B (ffestw block, ffelab label UNUSED, ffebld expr)
3020 ffeste_check_simple_ ();
3022 #if FFECOM_targetCURRENT == FFECOM_targetFFE
3024 fputs ("+ DO_WHILE_nonlabeled (", dmpout);
3026 fprintf (dmpout, "+ DO_WHILE_labeled %lu (", ffelab_value (label));
3028 fputs (")\n", dmpout);
3029 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
3033 ffeste_emit_line_note_ ();
3035 ffeste_start_block_ (block);
3039 struct nesting *loop;
3042 result = ffecom_make_tempvar ("dowhile", integer_type_node,
3043 FFETARGET_charactersizeNONE, -1);
3044 loop = expand_start_loop (1);
3046 ffeste_start_stmt_ ();
3048 ffecom_prepare_expr (expr);
3050 ffecom_prepare_end ();
3052 mod = ffecom_modify (void_type_node,
3054 ffecom_truth_value (ffecom_expr (expr)));
3055 expand_expr_stmt (mod);
3057 ffeste_end_stmt_ ();
3059 ffestw_set_do_hook (block, loop);
3060 expand_exit_loop_if_false (0, result);
3063 ffestw_set_do_hook (block, expand_start_loop (1));
3065 ffestw_set_do_tvar (block, NULL_TREE);
3072 /* END DO statement.
3074 This is the MIL-STD 1753 END DO. It's syntactic sugar, similar to
3075 CONTINUE (except that it has to have a label that is the target of
3076 one or more iterative DO statement), not the Fortran-90 structured
3077 END DO, which is handled elsewhere, as is the actual mechanism of
3078 ending an iterative DO statement, even one that ends at a label. */
3083 ffeste_check_simple_ ();
3085 #if FFECOM_targetCURRENT == FFECOM_targetFFE
3086 fputs ("+ END_DO_sugar\n", dmpout);
3087 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
3088 ffeste_emit_line_note_ ();
3096 /* CYCLE statement. */
3099 ffeste_R834 (ffestw block)
3101 ffeste_check_simple_ ();
3103 #if FFECOM_targetCURRENT == FFECOM_targetFFE
3104 fprintf (dmpout, "+ CYCLE block #%lu\n", ffestw_blocknum (block));
3105 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
3106 ffeste_emit_line_note_ ();
3108 expand_continue_loop (ffestw_do_hook (block));
3114 /* EXIT statement. */
3117 ffeste_R835 (ffestw block)
3119 ffeste_check_simple_ ();
3121 #if FFECOM_targetCURRENT == FFECOM_targetFFE
3122 fprintf (dmpout, "+ EXIT block #%lu\n", ffestw_blocknum (block));
3123 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
3124 ffeste_emit_line_note_ ();
3126 expand_exit_loop (ffestw_do_hook (block));
3132 /* GOTO statement. */
3135 ffeste_R836 (ffelab label)
3137 ffeste_check_simple_ ();
3139 #if FFECOM_targetCURRENT == FFECOM_targetFFE
3140 fprintf (dmpout, "+ GOTO %lu\n", ffelab_value (label));
3141 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
3145 ffeste_emit_line_note_ ();
3147 glabel = ffecom_lookup_label (label);
3148 if ((glabel != NULL_TREE)
3149 && (TREE_CODE (glabel) != ERROR_MARK))
3151 expand_goto (glabel);
3152 TREE_USED (glabel) = 1;
3160 /* Computed GOTO statement. */
3163 ffeste_R837 (ffelab *labels, int count, ffebld expr)
3167 ffeste_check_simple_ ();
3169 #if FFECOM_targetCURRENT == FFECOM_targetFFE
3170 fputs ("+ CGOTO (", dmpout);
3171 for (i = 0; i < count; ++i)
3174 fputc (',', dmpout);
3175 fprintf (dmpout, "%" ffelabValue_f "u", ffelab_value (labels[i]));
3177 fputs ("),", dmpout);
3179 fputc ('\n', dmpout);
3180 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
3188 ffeste_emit_line_note_ ();
3190 ffeste_start_stmt_ ();
3192 ffecom_prepare_expr (expr);
3194 ffecom_prepare_end ();
3196 texpr = ffecom_expr (expr);
3198 expand_start_case (0, texpr, TREE_TYPE (texpr), "computed GOTO statement");
3200 for (i = 0; i < count; ++i)
3202 value = build_int_2 (i + 1, 0);
3203 tlabel = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
3205 pushok = pushcase (value, convert, tlabel, &duplicate);
3206 assert (pushok == 0);
3208 tlabel = ffecom_lookup_label (labels[i]);
3209 if ((tlabel == NULL_TREE)
3210 || (TREE_CODE (tlabel) == ERROR_MARK))
3213 expand_goto (tlabel);
3214 TREE_USED (tlabel) = 1;
3216 expand_end_case (texpr);
3218 ffeste_end_stmt_ ();
3225 /* ASSIGN statement. */
3228 ffeste_R838 (ffelab label, ffebld target)
3230 ffeste_check_simple_ ();
3232 #if FFECOM_targetCURRENT == FFECOM_targetFFE
3233 fprintf (dmpout, "+ ASSIGN %lu TO ", ffelab_value (label));
3234 ffebld_dump (target);
3235 fputc ('\n', dmpout);
3236 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
3242 ffeste_emit_line_note_ ();
3244 /* No need to call ffeste_start_stmt_(), as the sorts of expressions
3245 seen here should never require use of temporaries. */
3247 label_tree = ffecom_lookup_label (label);
3248 if ((label_tree != NULL_TREE)
3249 && (TREE_CODE (label_tree) != ERROR_MARK))
3251 label_tree = ffecom_1 (ADDR_EXPR,
3252 build_pointer_type (void_type_node),
3254 TREE_CONSTANT (label_tree) = 1;
3256 target_tree = ffecom_expr_assign_w (target);
3257 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (target_tree)))
3258 < GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (label_tree))))
3259 error ("ASSIGN to variable that is too small");
3261 label_tree = convert (TREE_TYPE (target_tree), label_tree);
3263 expr_tree = ffecom_modify (void_type_node,
3266 expand_expr_stmt (expr_tree);
3274 /* Assigned GOTO statement. */
3277 ffeste_R839 (ffebld target)
3279 ffeste_check_simple_ ();
3281 #if FFECOM_targetCURRENT == FFECOM_targetFFE
3282 fputs ("+ AGOTO ", dmpout);
3283 ffebld_dump (target);
3284 fputc ('\n', dmpout);
3285 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
3289 ffeste_emit_line_note_ ();
3291 /* No need to call ffeste_start_stmt_(), as the sorts of expressions
3292 seen here should never require use of temporaries. */
3294 t = ffecom_expr_assign (target);
3295 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (t)))
3296 < GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
3297 error ("ASSIGNed GOTO target variable is too small");
3299 expand_computed_goto (convert (TREE_TYPE (null_pointer_node), t));
3306 /* Arithmetic IF statement. */
3309 ffeste_R840 (ffebld expr, ffelab neg, ffelab zero, ffelab pos)
3311 ffeste_check_simple_ ();
3313 #if FFECOM_targetCURRENT == FFECOM_targetFFE
3314 fputs ("+ IF_arithmetic (", dmpout);
3316 fprintf (dmpout, ") %" ffelabValue_f "u,%" ffelabValue_f "u,%" ffelabValue_f "u\n",
3317 ffelab_value (neg), ffelab_value (zero), ffelab_value (pos));
3318 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
3320 tree gneg = ffecom_lookup_label (neg);
3321 tree gzero = ffecom_lookup_label (zero);
3322 tree gpos = ffecom_lookup_label (pos);
3325 ffeste_emit_line_note_ ();
3327 if ((gneg == NULL_TREE) || (gzero == NULL_TREE) || (gpos == NULL_TREE))
3329 if ((TREE_CODE (gneg) == ERROR_MARK)
3330 || (TREE_CODE (gzero) == ERROR_MARK)
3331 || (TREE_CODE (gpos) == ERROR_MARK))
3334 ffeste_start_stmt_ ();
3336 ffecom_prepare_expr (expr);
3338 ffecom_prepare_end ();
3343 expand_goto (gzero);
3346 /* IF (expr.LE.0) THEN GOTO neg/zero ELSE GOTO pos. */
3347 texpr = ffecom_expr (expr);
3348 texpr = ffecom_2 (LE_EXPR, integer_type_node,
3350 convert (TREE_TYPE (texpr),
3351 integer_zero_node));
3352 expand_start_cond (ffecom_truth_value (texpr), 0);
3353 expand_goto (gzero);
3354 expand_start_else ();
3359 else if (neg == pos)
3361 /* IF (expr.NE.0) THEN GOTO neg/pos ELSE GOTO zero. */
3362 texpr = ffecom_expr (expr);
3363 texpr = ffecom_2 (NE_EXPR, integer_type_node,
3365 convert (TREE_TYPE (texpr),
3366 integer_zero_node));
3367 expand_start_cond (ffecom_truth_value (texpr), 0);
3369 expand_start_else ();
3370 expand_goto (gzero);
3373 else if (zero == pos)
3375 /* IF (expr.GE.0) THEN GOTO zero/pos ELSE GOTO neg. */
3376 texpr = ffecom_expr (expr);
3377 texpr = ffecom_2 (GE_EXPR, integer_type_node,
3379 convert (TREE_TYPE (texpr),
3380 integer_zero_node));
3381 expand_start_cond (ffecom_truth_value (texpr), 0);
3382 expand_goto (gzero);
3383 expand_start_else ();
3389 /* Use a SAVE_EXPR in combo with:
3390 IF (expr.LT.0) THEN GOTO neg
3391 ELSEIF (expr.GT.0) THEN GOTO pos
3393 tree expr_saved = ffecom_save_tree (ffecom_expr (expr));
3395 texpr = ffecom_2 (LT_EXPR, integer_type_node,
3397 convert (TREE_TYPE (expr_saved),
3398 integer_zero_node));
3399 expand_start_cond (ffecom_truth_value (texpr), 0);
3401 texpr = ffecom_2 (GT_EXPR, integer_type_node,
3403 convert (TREE_TYPE (expr_saved),
3404 integer_zero_node));
3405 expand_start_elseif (ffecom_truth_value (texpr));
3407 expand_start_else ();
3408 expand_goto (gzero);
3412 ffeste_end_stmt_ ();
3419 /* CONTINUE statement. */
3424 ffeste_check_simple_ ();
3426 #if FFECOM_targetCURRENT == FFECOM_targetFFE
3427 fputs ("+ CONTINUE\n", dmpout);
3428 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
3429 ffeste_emit_line_note_ ();
3437 /* STOP statement. */
3440 ffeste_R842 (ffebld expr)
3442 ffeste_check_simple_ ();
3444 #if FFECOM_targetCURRENT == FFECOM_targetFFE
3447 fputs ("+ STOP\n", dmpout);
3451 fputs ("+ STOP_coded ", dmpout);
3453 fputc ('\n', dmpout);
3455 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
3460 ffeste_emit_line_note_ ();
3463 || (ffeinfo_basictype (ffebld_info (expr))
3464 == FFEINFO_basictypeANY))
3466 msg = ffelex_token_new_character ("", ffelex_token_where_line
3467 (ffesta_tokens[0]), ffelex_token_where_column
3468 (ffesta_tokens[0]));
3469 expr = ffebld_new_conter (ffebld_constant_new_characterdefault
3471 ffelex_token_kill (msg);
3472 ffebld_set_info (expr, ffeinfo_new (FFEINFO_basictypeCHARACTER,
3473 FFEINFO_kindtypeCHARACTERDEFAULT, 0, FFEINFO_kindENTITY,
3474 FFEINFO_whereCONSTANT, 0));
3476 else if (ffeinfo_basictype (ffebld_info (expr))
3477 == FFEINFO_basictypeINTEGER)
3481 assert (ffebld_op (expr) == FFEBLD_opCONTER);
3482 assert (ffeinfo_kindtype (ffebld_info (expr))
3483 == FFEINFO_kindtypeINTEGERDEFAULT);
3484 sprintf (num, "%" ffetargetIntegerDefault_f "d",
3485 ffebld_constant_integer1 (ffebld_conter (expr)));
3486 msg = ffelex_token_new_character (num, ffelex_token_where_line
3487 (ffesta_tokens[0]), ffelex_token_where_column
3488 (ffesta_tokens[0]));
3489 expr = ffebld_new_conter (ffebld_constant_new_characterdefault
3491 ffelex_token_kill (msg);
3492 ffebld_set_info (expr, ffeinfo_new (FFEINFO_basictypeCHARACTER,
3493 FFEINFO_kindtypeCHARACTERDEFAULT, 0, FFEINFO_kindENTITY,
3494 FFEINFO_whereCONSTANT, 0));
3498 assert (ffeinfo_basictype (ffebld_info (expr))
3499 == FFEINFO_basictypeCHARACTER);
3500 assert (ffebld_op (expr) == FFEBLD_opCONTER);
3501 assert (ffeinfo_kindtype (ffebld_info (expr))
3502 == FFEINFO_kindtypeCHARACTERDEFAULT);
3505 /* No need to call ffeste_start_stmt_(), as the sorts of expressions
3506 seen here should never require use of temporaries. */
3508 callit = ffecom_call_gfrt (FFECOM_gfrtSTOP,
3509 ffecom_list_ptr_to_expr (ffebld_new_item (expr, NULL)),
3511 TREE_SIDE_EFFECTS (callit) = 1;
3513 expand_expr_stmt (callit);
3520 /* PAUSE statement. */
3523 ffeste_R843 (ffebld expr)
3525 ffeste_check_simple_ ();
3527 #if FFECOM_targetCURRENT == FFECOM_targetFFE
3530 fputs ("+ PAUSE\n", dmpout);
3534 fputs ("+ PAUSE_coded ", dmpout);
3536 fputc ('\n', dmpout);
3538 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
3543 ffeste_emit_line_note_ ();
3546 || (ffeinfo_basictype (ffebld_info (expr))
3547 == FFEINFO_basictypeANY))
3549 msg = ffelex_token_new_character ("", ffelex_token_where_line
3550 (ffesta_tokens[0]), ffelex_token_where_column
3551 (ffesta_tokens[0]));
3552 expr = ffebld_new_conter (ffebld_constant_new_characterdefault
3554 ffelex_token_kill (msg);
3555 ffebld_set_info (expr, ffeinfo_new (FFEINFO_basictypeCHARACTER,
3556 FFEINFO_kindtypeCHARACTERDEFAULT, 0, FFEINFO_kindENTITY,
3557 FFEINFO_whereCONSTANT, 0));
3559 else if (ffeinfo_basictype (ffebld_info (expr))
3560 == FFEINFO_basictypeINTEGER)
3564 assert (ffebld_op (expr) == FFEBLD_opCONTER);
3565 assert (ffeinfo_kindtype (ffebld_info (expr))
3566 == FFEINFO_kindtypeINTEGERDEFAULT);
3567 sprintf (num, "%" ffetargetIntegerDefault_f "d",
3568 ffebld_constant_integer1 (ffebld_conter (expr)));
3569 msg = ffelex_token_new_character (num, ffelex_token_where_line
3570 (ffesta_tokens[0]), ffelex_token_where_column
3571 (ffesta_tokens[0]));
3572 expr = ffebld_new_conter (ffebld_constant_new_characterdefault
3574 ffelex_token_kill (msg);
3575 ffebld_set_info (expr, ffeinfo_new (FFEINFO_basictypeCHARACTER,
3576 FFEINFO_kindtypeCHARACTERDEFAULT, 0, FFEINFO_kindENTITY,
3577 FFEINFO_whereCONSTANT, 0));
3581 assert (ffeinfo_basictype (ffebld_info (expr))
3582 == FFEINFO_basictypeCHARACTER);
3583 assert (ffebld_op (expr) == FFEBLD_opCONTER);
3584 assert (ffeinfo_kindtype (ffebld_info (expr))
3585 == FFEINFO_kindtypeCHARACTERDEFAULT);
3588 /* No need to call ffeste_start_stmt_(), as the sorts of expressions
3589 seen here should never require use of temporaries. */
3591 callit = ffecom_call_gfrt (FFECOM_gfrtPAUSE,
3592 ffecom_list_ptr_to_expr (ffebld_new_item (expr, NULL)),
3594 TREE_SIDE_EFFECTS (callit) = 1;
3596 expand_expr_stmt (callit);
3598 #if 0 /* Old approach for phantom g77 run-time
3603 ffeste_emit_line_note_ ();
3606 callit = ffecom_call_gfrt (FFECOM_gfrtPAUSENIL, NULL_TREE, NULL_TREE);
3607 else if (ffeinfo_basictype (ffebld_info (expr))
3608 == FFEINFO_basictypeINTEGER)
3609 callit = ffecom_call_gfrt (FFECOM_gfrtPAUSEINT,
3610 ffecom_list_ptr_to_expr (ffebld_new_item (expr, NULL)),
3612 else if (ffeinfo_basictype (ffebld_info (expr))
3613 == FFEINFO_basictypeCHARACTER)
3614 callit = ffecom_call_gfrt (FFECOM_gfrtPAUSECHAR,
3615 ffecom_list_ptr_to_expr (ffebld_new_item (expr, NULL)),
3619 TREE_SIDE_EFFECTS (callit) = 1;
3621 expand_expr_stmt (callit);
3629 /* OPEN statement. */
3632 ffeste_R904 (ffestpOpenStmt *info)
3634 ffeste_check_simple_ ();
3636 #if FFECOM_targetCURRENT == FFECOM_targetFFE
3637 fputs ("+ OPEN (", dmpout);
3638 ffeste_subr_file_ ("UNIT", &info->open_spec[FFESTP_openixUNIT]);
3639 ffeste_subr_file_ ("ACCESS", &info->open_spec[FFESTP_openixACCESS]);
3640 ffeste_subr_file_ ("ACTION", &info->open_spec[FFESTP_openixACTION]);
3641 ffeste_subr_file_ ("ASSOCIATEVARIABLE", &info->open_spec[FFESTP_openixASSOCIATEVARIABLE]);
3642 ffeste_subr_file_ ("BLANK", &info->open_spec[FFESTP_openixBLANK]);
3643 ffeste_subr_file_ ("BLOCKSIZE", &info->open_spec[FFESTP_openixBLOCKSIZE]);
3644 ffeste_subr_file_ ("BUFFERCOUNT", &info->open_spec[FFESTP_openixBUFFERCOUNT]);
3645 ffeste_subr_file_ ("CARRIAGECONTROL", &info->open_spec[FFESTP_openixCARRIAGECONTROL]);
3646 ffeste_subr_file_ ("DEFAULTFILE", &info->open_spec[FFESTP_openixDEFAULTFILE]);
3647 ffeste_subr_file_ ("DELIM", &info->open_spec[FFESTP_openixDELIM]);
3648 ffeste_subr_file_ ("DISPOSE", &info->open_spec[FFESTP_openixDISPOSE]);
3649 ffeste_subr_file_ ("ERR", &info->open_spec[FFESTP_openixERR]);
3650 ffeste_subr_file_ ("EXTENDSIZE", &info->open_spec[FFESTP_openixEXTENDSIZE]);
3651 ffeste_subr_file_ ("FILE", &info->open_spec[FFESTP_openixFILE]);
3652 ffeste_subr_file_ ("FORM", &info->open_spec[FFESTP_openixFORM]);
3653 ffeste_subr_file_ ("INITIALSIZE", &info->open_spec[FFESTP_openixINITIALSIZE]);
3654 ffeste_subr_file_ ("IOSTAT", &info->open_spec[FFESTP_openixIOSTAT]);
3655 ffeste_subr_file_ ("KEY", &info->open_spec[FFESTP_openixKEY]);
3656 ffeste_subr_file_ ("MAXREC", &info->open_spec[FFESTP_openixMAXREC]);
3657 ffeste_subr_file_ ("NOSPANBLOCKS", &info->open_spec[FFESTP_openixNOSPANBLOCKS]);
3658 ffeste_subr_file_ ("ORGANIZATION", &info->open_spec[FFESTP_openixORGANIZATION]);
3659 ffeste_subr_file_ ("PAD", &info->open_spec[FFESTP_openixPAD]);
3660 ffeste_subr_file_ ("POSITION", &info->open_spec[FFESTP_openixPOSITION]);
3661 ffeste_subr_file_ ("READONLY", &info->open_spec[FFESTP_openixREADONLY]);
3662 ffeste_subr_file_ ("RECL", &info->open_spec[FFESTP_openixRECL]);
3663 ffeste_subr_file_ ("RECORDTYPE", &info->open_spec[FFESTP_openixRECORDTYPE]);
3664 ffeste_subr_file_ ("SHARED", &info->open_spec[FFESTP_openixSHARED]);
3665 ffeste_subr_file_ ("STATUS", &info->open_spec[FFESTP_openixSTATUS]);
3666 ffeste_subr_file_ ("USEROPEN", &info->open_spec[FFESTP_openixUSEROPEN]);
3667 fputs (")\n", dmpout);
3668 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
3674 ffeste_emit_line_note_ ();
3676 #define specified(something) (info->open_spec[something].kw_or_val_present)
3678 iostat = specified (FFESTP_openixIOSTAT);
3679 errl = specified (FFESTP_openixERR);
3683 ffeste_start_stmt_ ();
3689 = ffecom_lookup_label
3690 (info->open_spec[FFESTP_openixERR].u.label);
3691 ffeste_io_abort_is_temp_ = FALSE;
3695 ffeste_io_err_ = NULL_TREE;
3697 if ((ffeste_io_abort_is_temp_ = iostat))
3698 ffeste_io_abort_ = ffecom_temp_label ();
3700 ffeste_io_abort_ = NULL_TREE;
3705 /* Have IOSTAT= specification. */
3707 ffeste_io_iostat_is_temp_ = FALSE;
3708 ffeste_io_iostat_ = ffecom_expr
3709 (info->open_spec[FFESTP_openixIOSTAT].u.expr);
3711 else if (ffeste_io_abort_ != NULL_TREE)
3713 /* Have no IOSTAT= but have ERR=. */
3715 ffeste_io_iostat_is_temp_ = TRUE;
3717 = ffecom_make_tempvar ("open", ffecom_integer_type_node,
3718 FFETARGET_charactersizeNONE, -1);
3722 /* No IOSTAT= or ERR= specification. */
3724 ffeste_io_iostat_is_temp_ = FALSE;
3725 ffeste_io_iostat_ = NULL_TREE;
3728 /* Now prescan, then convert, all the arguments. */
3730 args = ffeste_io_olist_ (errl || iostat,
3731 info->open_spec[FFESTP_openixUNIT].u.expr,
3732 &info->open_spec[FFESTP_openixFILE],
3733 &info->open_spec[FFESTP_openixSTATUS],
3734 &info->open_spec[FFESTP_openixACCESS],
3735 &info->open_spec[FFESTP_openixFORM],
3736 &info->open_spec[FFESTP_openixRECL],
3737 &info->open_spec[FFESTP_openixBLANK]);
3739 /* Don't generate "if (iostat != 0) goto label;" if label is temp abort
3740 label, since we're gonna fall through to there anyway. */
3742 ffeste_io_call_ (ffecom_call_gfrt (FFECOM_gfrtFOPEN, args, NULL_TREE),
3743 ! ffeste_io_abort_is_temp_);
3745 /* If we've got a temp label, generate its code here. */
3747 if (ffeste_io_abort_is_temp_)
3749 DECL_INITIAL (ffeste_io_abort_) = error_mark_node;
3751 expand_label (ffeste_io_abort_);
3753 assert (ffeste_io_err_ == NULL_TREE);
3756 ffeste_end_stmt_ ();
3763 /* CLOSE statement. */
3766 ffeste_R907 (ffestpCloseStmt *info)
3768 ffeste_check_simple_ ();
3770 #if FFECOM_targetCURRENT == FFECOM_targetFFE
3771 fputs ("+ CLOSE (", dmpout);
3772 ffeste_subr_file_ ("UNIT", &info->close_spec[FFESTP_closeixUNIT]);
3773 ffeste_subr_file_ ("ERR", &info->close_spec[FFESTP_closeixERR]);
3774 ffeste_subr_file_ ("IOSTAT", &info->close_spec[FFESTP_closeixIOSTAT]);
3775 ffeste_subr_file_ ("STATUS", &info->close_spec[FFESTP_closeixSTATUS]);
3776 fputs (")\n", dmpout);
3777 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
3783 ffeste_emit_line_note_ ();
3785 #define specified(something) (info->close_spec[something].kw_or_val_present)
3787 iostat = specified (FFESTP_closeixIOSTAT);
3788 errl = specified (FFESTP_closeixERR);
3792 ffeste_start_stmt_ ();
3798 = ffecom_lookup_label
3799 (info->close_spec[FFESTP_closeixERR].u.label);
3800 ffeste_io_abort_is_temp_ = FALSE;
3804 ffeste_io_err_ = NULL_TREE;
3806 if ((ffeste_io_abort_is_temp_ = iostat))
3807 ffeste_io_abort_ = ffecom_temp_label ();
3809 ffeste_io_abort_ = NULL_TREE;
3814 /* Have IOSTAT= specification. */
3816 ffeste_io_iostat_is_temp_ = FALSE;
3817 ffeste_io_iostat_ = ffecom_expr
3818 (info->close_spec[FFESTP_closeixIOSTAT].u.expr);
3820 else if (ffeste_io_abort_ != NULL_TREE)
3822 /* Have no IOSTAT= but have ERR=. */
3824 ffeste_io_iostat_is_temp_ = TRUE;
3826 = ffecom_make_tempvar ("close", ffecom_integer_type_node,
3827 FFETARGET_charactersizeNONE, -1);
3831 /* No IOSTAT= or ERR= specification. */
3833 ffeste_io_iostat_is_temp_ = FALSE;
3834 ffeste_io_iostat_ = NULL_TREE;
3837 /* Now prescan, then convert, all the arguments. */
3839 args = ffeste_io_cllist_ (errl || iostat,
3840 info->close_spec[FFESTP_closeixUNIT].u.expr,
3841 &info->close_spec[FFESTP_closeixSTATUS]);
3843 /* Don't generate "if (iostat != 0) goto label;" if label is temp abort
3844 label, since we're gonna fall through to there anyway. */
3846 ffeste_io_call_ (ffecom_call_gfrt (FFECOM_gfrtFCLOS, args, NULL_TREE),
3847 ! ffeste_io_abort_is_temp_);
3849 /* If we've got a temp label, generate its code here. */
3851 if (ffeste_io_abort_is_temp_)
3853 DECL_INITIAL (ffeste_io_abort_) = error_mark_node;
3855 expand_label (ffeste_io_abort_);
3857 assert (ffeste_io_err_ == NULL_TREE);
3860 ffeste_end_stmt_ ();
3867 /* READ(...) statement -- start. */
3870 ffeste_R909_start (ffestpReadStmt *info, bool only_format UNUSED,
3871 ffestvUnit unit, ffestvFormat format, bool rec,
3874 ffeste_check_start_ ();
3876 #if FFECOM_targetCURRENT == FFECOM_targetFFE
3879 case FFESTV_formatNONE:
3881 fputs ("+ READ_ufdac", dmpout);
3883 fputs ("+ READ_ufidx", dmpout);
3885 fputs ("+ READ_ufseq", dmpout);
3888 case FFESTV_formatLABEL:
3889 case FFESTV_formatCHAREXPR:
3890 case FFESTV_formatINTEXPR:
3892 fputs ("+ READ_fmdac", dmpout);
3894 fputs ("+ READ_fmidx", dmpout);
3895 else if (unit == FFESTV_unitCHAREXPR)
3896 fputs ("+ READ_fmint", dmpout);
3898 fputs ("+ READ_fmseq", dmpout);
3901 case FFESTV_formatASTERISK:
3902 if (unit == FFESTV_unitCHAREXPR)
3903 fputs ("+ READ_lsint", dmpout);
3905 fputs ("+ READ_lsseq", dmpout);
3908 case FFESTV_formatNAMELIST:
3909 fputs ("+ READ_nlseq", dmpout);
3913 assert ("Unexpected kind of format item in R909 READ" == NULL);
3918 fputc (' ', dmpout);
3919 ffeste_subr_file_ ("FORMAT", &info->read_spec[FFESTP_readixFORMAT]);
3920 fputc (' ', dmpout);
3925 fputs (" (", dmpout);
3926 ffeste_subr_file_ ("UNIT", &info->read_spec[FFESTP_readixUNIT]);
3927 ffeste_subr_file_ ("FORMAT", &info->read_spec[FFESTP_readixFORMAT]);
3928 ffeste_subr_file_ ("ADVANCE", &info->read_spec[FFESTP_readixADVANCE]);
3929 ffeste_subr_file_ ("EOR", &info->read_spec[FFESTP_readixEOR]);
3930 ffeste_subr_file_ ("ERR", &info->read_spec[FFESTP_readixERR]);
3931 ffeste_subr_file_ ("END", &info->read_spec[FFESTP_readixEND]);
3932 ffeste_subr_file_ ("IOSTAT", &info->read_spec[FFESTP_readixIOSTAT]);
3933 ffeste_subr_file_ ("KEYEQ", &info->read_spec[FFESTP_readixKEYEQ]);
3934 ffeste_subr_file_ ("KEYGE", &info->read_spec[FFESTP_readixKEYGE]);
3935 ffeste_subr_file_ ("KEYGT", &info->read_spec[FFESTP_readixKEYGT]);
3936 ffeste_subr_file_ ("KEYID", &info->read_spec[FFESTP_readixKEYID]);
3937 ffeste_subr_file_ ("NULLS", &info->read_spec[FFESTP_readixNULLS]);
3938 ffeste_subr_file_ ("REC", &info->read_spec[FFESTP_readixREC]);
3939 ffeste_subr_file_ ("SIZE", &info->read_spec[FFESTP_readixSIZE]);
3940 fputs (") ", dmpout);
3941 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
3943 ffeste_emit_line_note_ ();
3953 /* First determine the start, per-item, and end run-time functions to
3954 call. The per-item function is picked by choosing an ffeste function
3955 to call to handle a given item; it knows how to generate a call to the
3956 appropriate run-time function, and is called an "I/O driver". */
3960 case FFESTV_formatNONE: /* no FMT= */
3961 ffeste_io_driver_ = ffeste_io_douio_;
3963 start = FFECOM_gfrtSRDUE, end = FFECOM_gfrtERDUE;
3966 start = FFECOM_gfrtSRIUE, end = FFECOM_gfrtERIUE;
3969 start = FFECOM_gfrtSRSUE, end = FFECOM_gfrtERSUE;
3972 case FFESTV_formatLABEL: /* FMT=10 */
3973 case FFESTV_formatCHAREXPR: /* FMT='(I10)' */
3974 case FFESTV_formatINTEXPR: /* FMT=I [after ASSIGN 10 TO I] */
3975 ffeste_io_driver_ = ffeste_io_dofio_;
3977 start = FFECOM_gfrtSRDFE, end = FFECOM_gfrtERDFE;
3980 start = FFECOM_gfrtSRIFE, end = FFECOM_gfrtERIFE;
3982 else if (unit == FFESTV_unitCHAREXPR)
3983 start = FFECOM_gfrtSRSFI, end = FFECOM_gfrtERSFI;
3985 start = FFECOM_gfrtSRSFE, end = FFECOM_gfrtERSFE;
3988 case FFESTV_formatASTERISK: /* FMT=* */
3989 ffeste_io_driver_ = ffeste_io_dolio_;
3990 if (unit == FFESTV_unitCHAREXPR)
3991 start = FFECOM_gfrtSRSLI, end = FFECOM_gfrtERSLI;
3993 start = FFECOM_gfrtSRSLE, end = FFECOM_gfrtERSLE;
3996 case FFESTV_formatNAMELIST: /* FMT=FOO or NML=FOO [NAMELIST
3998 ffeste_io_driver_ = NULL; /* No start or driver function. */
3999 start = FFECOM_gfrtSRSNE, end = FFECOM_gfrt;
4003 assert ("Weird stuff" == NULL);
4004 start = FFECOM_gfrt, end = FFECOM_gfrt;
4007 ffeste_io_endgfrt_ = end;
4009 #define specified(something) (info->read_spec[something].kw_or_val_present)
4011 iostat = specified (FFESTP_readixIOSTAT);
4012 errl = specified (FFESTP_readixERR);
4013 endl = specified (FFESTP_readixEND);
4017 ffeste_start_stmt_ ();
4021 /* Have ERR= specification. */
4024 = ffecom_lookup_label (info->read_spec[FFESTP_readixERR].u.label);
4028 /* Have both ERR= and END=. Need a temp label to handle both. */
4030 = ffecom_lookup_label (info->read_spec[FFESTP_readixEND].u.label);
4031 ffeste_io_abort_is_temp_ = TRUE;
4032 ffeste_io_abort_ = ffecom_temp_label ();
4036 /* Have ERR= but no END=. */
4037 ffeste_io_end_ = NULL_TREE;
4038 if ((ffeste_io_abort_is_temp_ = iostat))
4039 ffeste_io_abort_ = ffecom_temp_label ();
4041 ffeste_io_abort_ = ffeste_io_err_;
4046 /* No ERR= specification. */
4048 ffeste_io_err_ = NULL_TREE;
4051 /* Have END= but no ERR=. */
4053 = ffecom_lookup_label (info->read_spec[FFESTP_readixEND].u.label);
4054 if ((ffeste_io_abort_is_temp_ = iostat))
4055 ffeste_io_abort_ = ffecom_temp_label ();
4057 ffeste_io_abort_ = ffeste_io_end_;
4061 /* Have no ERR= or END=. */
4063 ffeste_io_end_ = NULL_TREE;
4064 if ((ffeste_io_abort_is_temp_ = iostat))
4065 ffeste_io_abort_ = ffecom_temp_label ();
4067 ffeste_io_abort_ = NULL_TREE;
4073 /* Have IOSTAT= specification. */
4075 ffeste_io_iostat_is_temp_ = FALSE;
4077 = ffecom_expr (info->read_spec[FFESTP_readixIOSTAT].u.expr);
4079 else if (ffeste_io_abort_ != NULL_TREE)
4081 /* Have no IOSTAT= but have ERR= and/or END=. */
4083 ffeste_io_iostat_is_temp_ = TRUE;
4085 = ffecom_make_tempvar ("read", ffecom_integer_type_node,
4086 FFETARGET_charactersizeNONE, -1);
4090 /* No IOSTAT=, ERR=, or END= specification. */
4092 ffeste_io_iostat_is_temp_ = FALSE;
4093 ffeste_io_iostat_ = NULL_TREE;
4096 /* Now prescan, then convert, all the arguments. */
4098 if (unit == FFESTV_unitCHAREXPR)
4099 cilist = ffeste_io_icilist_ (errl || iostat,
4100 info->read_spec[FFESTP_readixUNIT].u.expr,
4101 endl || iostat, format,
4102 &info->read_spec[FFESTP_readixFORMAT]);
4104 cilist = ffeste_io_cilist_ (errl || iostat, unit,
4105 info->read_spec[FFESTP_readixUNIT].u.expr,
4106 5, endl || iostat, format,
4107 &info->read_spec[FFESTP_readixFORMAT],
4109 info->read_spec[FFESTP_readixREC].u.expr);
4111 /* If there is no end function, then there are no item functions (i.e.
4112 it's a NAMELIST), and vice versa by the way. In this situation, don't
4113 generate the "if (iostat != 0) goto label;" if the label is temp abort
4114 label, since we're gonna fall through to there anyway. */
4116 ffeste_io_call_ (ffecom_call_gfrt (start, cilist, NULL_TREE),
4117 (! ffeste_io_abort_is_temp_) || (end != FFECOM_gfrt));
4124 /* READ statement -- I/O item. */
4127 ffeste_R909_item (ffebld expr, ffelexToken expr_token)
4129 ffeste_check_item_ ();
4131 #if FFECOM_targetCURRENT == FFECOM_targetFFE
4133 fputc (',', dmpout);
4134 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
4138 /* Strip parens off items such as in "READ *,(A)". This is really a bug
4139 in the user's code, but I've been told lots of code does this. */
4140 while (ffebld_op (expr) == FFEBLD_opPAREN)
4141 expr = ffebld_left (expr);
4143 if (ffebld_op (expr) == FFEBLD_opANY)
4146 if (ffebld_op (expr) == FFEBLD_opIMPDO)
4147 ffeste_io_impdo_ (expr, expr_token);
4150 ffeste_start_stmt_ ();
4152 ffecom_prepare_arg_ptr_to_expr (expr);
4154 ffecom_prepare_end ();
4156 ffeste_io_call_ ((*ffeste_io_driver_) (expr), TRUE);
4158 ffeste_end_stmt_ ();
4165 /* READ statement -- end. */
4168 ffeste_R909_finish ()
4170 ffeste_check_finish_ ();
4172 #if FFECOM_targetCURRENT == FFECOM_targetFFE
4173 fputc ('\n', dmpout);
4174 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
4176 /* Don't generate "if (iostat != 0) goto label;" if label is temp abort
4177 label, since we're gonna fall through to there anyway. */
4179 if (ffeste_io_endgfrt_ != FFECOM_gfrt)
4180 ffeste_io_call_ (ffecom_call_gfrt (ffeste_io_endgfrt_, NULL_TREE,
4182 ! ffeste_io_abort_is_temp_);
4184 /* If we've got a temp label, generate its code here and have it fan out
4185 to the END= or ERR= label as appropriate. */
4187 if (ffeste_io_abort_is_temp_)
4189 DECL_INITIAL (ffeste_io_abort_) = error_mark_node;
4191 expand_label (ffeste_io_abort_);
4193 /* "if (iostat<0) goto end_label;". */
4195 if ((ffeste_io_end_ != NULL_TREE)
4196 && (TREE_CODE (ffeste_io_end_) != ERROR_MARK))
4198 expand_start_cond (ffecom_truth_value
4199 (ffecom_2 (LT_EXPR, integer_type_node,
4201 ffecom_integer_zero_node)),
4203 expand_goto (ffeste_io_end_);
4207 /* "if (iostat>0) goto err_label;". */
4209 if ((ffeste_io_err_ != NULL_TREE)
4210 && (TREE_CODE (ffeste_io_err_) != ERROR_MARK))
4212 expand_start_cond (ffecom_truth_value
4213 (ffecom_2 (GT_EXPR, integer_type_node,
4215 ffecom_integer_zero_node)),
4217 expand_goto (ffeste_io_err_);
4222 ffeste_end_stmt_ ();
4228 /* WRITE statement -- start. */
4231 ffeste_R910_start (ffestpWriteStmt *info, ffestvUnit unit,
4232 ffestvFormat format, bool rec)
4234 ffeste_check_start_ ();
4236 #if FFECOM_targetCURRENT == FFECOM_targetFFE
4239 case FFESTV_formatNONE:
4241 fputs ("+ WRITE_ufdac (", dmpout);
4243 fputs ("+ WRITE_ufseq_or_idx (", dmpout);
4246 case FFESTV_formatLABEL:
4247 case FFESTV_formatCHAREXPR:
4248 case FFESTV_formatINTEXPR:
4250 fputs ("+ WRITE_fmdac (", dmpout);
4251 else if (unit == FFESTV_unitCHAREXPR)
4252 fputs ("+ WRITE_fmint (", dmpout);
4254 fputs ("+ WRITE_fmseq_or_idx (", dmpout);
4257 case FFESTV_formatASTERISK:
4258 if (unit == FFESTV_unitCHAREXPR)
4259 fputs ("+ WRITE_lsint (", dmpout);
4261 fputs ("+ WRITE_lsseq (", dmpout);
4264 case FFESTV_formatNAMELIST:
4265 fputs ("+ WRITE_nlseq (", dmpout);
4269 assert ("Unexpected kind of format item in R910 WRITE" == NULL);
4272 ffeste_subr_file_ ("UNIT", &info->write_spec[FFESTP_writeixUNIT]);
4273 ffeste_subr_file_ ("FORMAT", &info->write_spec[FFESTP_writeixFORMAT]);
4274 ffeste_subr_file_ ("ADVANCE", &info->write_spec[FFESTP_writeixADVANCE]);
4275 ffeste_subr_file_ ("EOR", &info->write_spec[FFESTP_writeixEOR]);
4276 ffeste_subr_file_ ("ERR", &info->write_spec[FFESTP_writeixERR]);
4277 ffeste_subr_file_ ("IOSTAT", &info->write_spec[FFESTP_writeixIOSTAT]);
4278 ffeste_subr_file_ ("REC", &info->write_spec[FFESTP_writeixREC]);
4279 fputs (") ", dmpout);
4280 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
4282 ffeste_emit_line_note_ ();
4291 /* First determine the start, per-item, and end run-time functions to
4292 call. The per-item function is picked by choosing an ffeste function
4293 to call to handle a given item; it knows how to generate a call to the
4294 appropriate run-time function, and is called an "I/O driver". */
4298 case FFESTV_formatNONE: /* no FMT= */
4299 ffeste_io_driver_ = ffeste_io_douio_;
4301 start = FFECOM_gfrtSWDUE, end = FFECOM_gfrtEWDUE;
4303 start = FFECOM_gfrtSWSUE, end = FFECOM_gfrtEWSUE;
4306 case FFESTV_formatLABEL: /* FMT=10 */
4307 case FFESTV_formatCHAREXPR: /* FMT='(I10)' */
4308 case FFESTV_formatINTEXPR: /* FMT=I [after ASSIGN 10 TO I] */
4309 ffeste_io_driver_ = ffeste_io_dofio_;
4311 start = FFECOM_gfrtSWDFE, end = FFECOM_gfrtEWDFE;
4312 else if (unit == FFESTV_unitCHAREXPR)
4313 start = FFECOM_gfrtSWSFI, end = FFECOM_gfrtEWSFI;
4315 start = FFECOM_gfrtSWSFE, end = FFECOM_gfrtEWSFE;
4318 case FFESTV_formatASTERISK: /* FMT=* */
4319 ffeste_io_driver_ = ffeste_io_dolio_;
4320 if (unit == FFESTV_unitCHAREXPR)
4321 start = FFECOM_gfrtSWSLI, end = FFECOM_gfrtEWSLI;
4323 start = FFECOM_gfrtSWSLE, end = FFECOM_gfrtEWSLE;
4326 case FFESTV_formatNAMELIST: /* FMT=FOO or NML=FOO [NAMELIST
4328 ffeste_io_driver_ = NULL; /* No start or driver function. */
4329 start = FFECOM_gfrtSWSNE, end = FFECOM_gfrt;
4333 assert ("Weird stuff" == NULL);
4334 start = FFECOM_gfrt, end = FFECOM_gfrt;
4337 ffeste_io_endgfrt_ = end;
4339 #define specified(something) (info->write_spec[something].kw_or_val_present)
4341 iostat = specified (FFESTP_writeixIOSTAT);
4342 errl = specified (FFESTP_writeixERR);
4346 ffeste_start_stmt_ ();
4348 ffeste_io_end_ = NULL_TREE;
4352 /* Have ERR= specification. */
4356 = ffecom_lookup_label
4357 (info->write_spec[FFESTP_writeixERR].u.label);
4358 ffeste_io_abort_is_temp_ = FALSE;
4362 /* No ERR= specification. */
4364 ffeste_io_err_ = NULL_TREE;
4366 if ((ffeste_io_abort_is_temp_ = iostat))
4367 ffeste_io_abort_ = ffecom_temp_label ();
4369 ffeste_io_abort_ = NULL_TREE;
4374 /* Have IOSTAT= specification. */
4376 ffeste_io_iostat_is_temp_ = FALSE;
4377 ffeste_io_iostat_ = ffecom_expr
4378 (info->write_spec[FFESTP_writeixIOSTAT].u.expr);
4380 else if (ffeste_io_abort_ != NULL_TREE)
4382 /* Have no IOSTAT= but have ERR=. */
4384 ffeste_io_iostat_is_temp_ = TRUE;
4386 = ffecom_make_tempvar ("write", ffecom_integer_type_node,
4387 FFETARGET_charactersizeNONE, -1);
4391 /* No IOSTAT= or ERR= specification. */
4393 ffeste_io_iostat_is_temp_ = FALSE;
4394 ffeste_io_iostat_ = NULL_TREE;
4397 /* Now prescan, then convert, all the arguments. */
4399 if (unit == FFESTV_unitCHAREXPR)
4400 cilist = ffeste_io_icilist_ (errl || iostat,
4401 info->write_spec[FFESTP_writeixUNIT].u.expr,
4403 &info->write_spec[FFESTP_writeixFORMAT]);
4405 cilist = ffeste_io_cilist_ (errl || iostat, unit,
4406 info->write_spec[FFESTP_writeixUNIT].u.expr,
4408 &info->write_spec[FFESTP_writeixFORMAT],
4410 info->write_spec[FFESTP_writeixREC].u.expr);
4412 /* If there is no end function, then there are no item functions (i.e.
4413 it's a NAMELIST), and vice versa by the way. In this situation, don't
4414 generate the "if (iostat != 0) goto label;" if the label is temp abort
4415 label, since we're gonna fall through to there anyway. */
4417 ffeste_io_call_ (ffecom_call_gfrt (start, cilist, NULL_TREE),
4418 (! ffeste_io_abort_is_temp_) || (end != FFECOM_gfrt));
4425 /* WRITE statement -- I/O item. */
4428 ffeste_R910_item (ffebld expr, ffelexToken expr_token)
4430 ffeste_check_item_ ();
4432 #if FFECOM_targetCURRENT == FFECOM_targetFFE
4434 fputc (',', dmpout);
4435 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
4439 if (ffebld_op (expr) == FFEBLD_opANY)
4442 if (ffebld_op (expr) == FFEBLD_opIMPDO)
4443 ffeste_io_impdo_ (expr, expr_token);
4446 ffeste_start_stmt_ ();
4448 ffecom_prepare_arg_ptr_to_expr (expr);
4450 ffecom_prepare_end ();
4452 ffeste_io_call_ ((*ffeste_io_driver_) (expr), TRUE);
4454 ffeste_end_stmt_ ();
4461 /* WRITE statement -- end. */
4464 ffeste_R910_finish ()
4466 ffeste_check_finish_ ();
4468 #if FFECOM_targetCURRENT == FFECOM_targetFFE
4469 fputc ('\n', dmpout);
4470 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
4472 /* Don't generate "if (iostat != 0) goto label;" if label is temp abort
4473 label, since we're gonna fall through to there anyway. */
4475 if (ffeste_io_endgfrt_ != FFECOM_gfrt)
4476 ffeste_io_call_ (ffecom_call_gfrt (ffeste_io_endgfrt_, NULL_TREE,
4478 ! ffeste_io_abort_is_temp_);
4480 /* If we've got a temp label, generate its code here. */
4482 if (ffeste_io_abort_is_temp_)
4484 DECL_INITIAL (ffeste_io_abort_) = error_mark_node;
4486 expand_label (ffeste_io_abort_);
4488 assert (ffeste_io_err_ == NULL_TREE);
4491 ffeste_end_stmt_ ();
4497 /* PRINT statement -- start. */
4500 ffeste_R911_start (ffestpPrintStmt *info, ffestvFormat format)
4502 ffeste_check_start_ ();
4504 #if FFECOM_targetCURRENT == FFECOM_targetFFE
4507 case FFESTV_formatLABEL:
4508 case FFESTV_formatCHAREXPR:
4509 case FFESTV_formatINTEXPR:
4510 fputs ("+ PRINT_fm ", dmpout);
4513 case FFESTV_formatASTERISK:
4514 fputs ("+ PRINT_ls ", dmpout);
4517 case FFESTV_formatNAMELIST:
4518 fputs ("+ PRINT_nl ", dmpout);
4522 assert ("Unexpected kind of format item in R911 PRINT" == NULL);
4524 ffeste_subr_file_ ("FORMAT", &info->print_spec[FFESTP_printixFORMAT]);
4525 fputc (' ', dmpout);
4526 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
4528 ffeste_emit_line_note_ ();
4535 /* First determine the start, per-item, and end run-time functions to
4536 call. The per-item function is picked by choosing an ffeste function
4537 to call to handle a given item; it knows how to generate a call to the
4538 appropriate run-time function, and is called an "I/O driver". */
4542 case FFESTV_formatLABEL: /* FMT=10 */
4543 case FFESTV_formatCHAREXPR: /* FMT='(I10)' */
4544 case FFESTV_formatINTEXPR: /* FMT=I [after ASSIGN 10 TO I] */
4545 ffeste_io_driver_ = ffeste_io_dofio_;
4546 start = FFECOM_gfrtSWSFE, end = FFECOM_gfrtEWSFE;
4549 case FFESTV_formatASTERISK: /* FMT=* */
4550 ffeste_io_driver_ = ffeste_io_dolio_;
4551 start = FFECOM_gfrtSWSLE, end = FFECOM_gfrtEWSLE;
4554 case FFESTV_formatNAMELIST: /* FMT=FOO or NML=FOO [NAMELIST
4556 ffeste_io_driver_ = NULL; /* No start or driver function. */
4557 start = FFECOM_gfrtSWSNE, end = FFECOM_gfrt;
4561 assert ("Weird stuff" == NULL);
4562 start = FFECOM_gfrt, end = FFECOM_gfrt;
4565 ffeste_io_endgfrt_ = end;
4567 ffeste_start_stmt_ ();
4569 ffeste_io_end_ = NULL_TREE;
4570 ffeste_io_err_ = NULL_TREE;
4571 ffeste_io_abort_ = NULL_TREE;
4572 ffeste_io_abort_is_temp_ = FALSE;
4573 ffeste_io_iostat_is_temp_ = FALSE;
4574 ffeste_io_iostat_ = NULL_TREE;
4576 /* Now prescan, then convert, all the arguments. */
4578 cilist = ffeste_io_cilist_ (FALSE, FFESTV_unitNONE, NULL, 6, FALSE, format,
4579 &info->print_spec[FFESTP_printixFORMAT], FALSE, NULL);
4581 /* If there is no end function, then there are no item functions (i.e.
4582 it's a NAMELIST), and vice versa by the way. In this situation, don't
4583 generate the "if (iostat != 0) goto label;" if the label is temp abort
4584 label, since we're gonna fall through to there anyway. */
4586 ffeste_io_call_ (ffecom_call_gfrt (start, cilist, NULL_TREE),
4587 (! ffeste_io_abort_is_temp_) || (end != FFECOM_gfrt));
4594 /* PRINT statement -- I/O item. */
4597 ffeste_R911_item (ffebld expr, ffelexToken expr_token)
4599 ffeste_check_item_ ();
4601 #if FFECOM_targetCURRENT == FFECOM_targetFFE
4603 fputc (',', dmpout);
4604 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
4608 if (ffebld_op (expr) == FFEBLD_opANY)
4611 if (ffebld_op (expr) == FFEBLD_opIMPDO)
4612 ffeste_io_impdo_ (expr, expr_token);
4615 ffeste_start_stmt_ ();
4617 ffecom_prepare_arg_ptr_to_expr (expr);
4619 ffecom_prepare_end ();
4621 ffeste_io_call_ ((*ffeste_io_driver_) (expr), TRUE);
4623 ffeste_end_stmt_ ();
4630 /* PRINT statement -- end. */
4633 ffeste_R911_finish ()
4635 ffeste_check_finish_ ();
4637 #if FFECOM_targetCURRENT == FFECOM_targetFFE
4638 fputc ('\n', dmpout);
4639 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
4641 if (ffeste_io_endgfrt_ != FFECOM_gfrt)
4642 ffeste_io_call_ (ffecom_call_gfrt (ffeste_io_endgfrt_, NULL_TREE,
4646 ffeste_end_stmt_ ();
4652 /* BACKSPACE statement. */
4655 ffeste_R919 (ffestpBeruStmt *info)
4657 ffeste_check_simple_ ();
4659 #if FFECOM_targetCURRENT == FFECOM_targetFFE
4660 fputs ("+ BACKSPACE (", dmpout);
4661 ffeste_subr_file_ ("UNIT", &info->beru_spec[FFESTP_beruixUNIT]);
4662 ffeste_subr_file_ ("ERR", &info->beru_spec[FFESTP_beruixERR]);
4663 ffeste_subr_file_ ("IOSTAT", &info->beru_spec[FFESTP_beruixIOSTAT]);
4664 fputs (")\n", dmpout);
4665 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
4666 ffeste_subr_beru_ (info, FFECOM_gfrtFBACK);
4672 /* ENDFILE statement. */
4675 ffeste_R920 (ffestpBeruStmt *info)
4677 ffeste_check_simple_ ();
4679 #if FFECOM_targetCURRENT == FFECOM_targetFFE
4680 fputs ("+ ENDFILE (", dmpout);
4681 ffeste_subr_file_ ("UNIT", &info->beru_spec[FFESTP_beruixUNIT]);
4682 ffeste_subr_file_ ("ERR", &info->beru_spec[FFESTP_beruixERR]);
4683 ffeste_subr_file_ ("IOSTAT", &info->beru_spec[FFESTP_beruixIOSTAT]);
4684 fputs (")\n", dmpout);
4685 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
4686 ffeste_subr_beru_ (info, FFECOM_gfrtFEND);
4692 /* REWIND statement. */
4695 ffeste_R921 (ffestpBeruStmt *info)
4697 ffeste_check_simple_ ();
4699 #if FFECOM_targetCURRENT == FFECOM_targetFFE
4700 fputs ("+ REWIND (", dmpout);
4701 ffeste_subr_file_ ("UNIT", &info->beru_spec[FFESTP_beruixUNIT]);
4702 ffeste_subr_file_ ("ERR", &info->beru_spec[FFESTP_beruixERR]);
4703 ffeste_subr_file_ ("IOSTAT", &info->beru_spec[FFESTP_beruixIOSTAT]);
4704 fputs (")\n", dmpout);
4705 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
4706 ffeste_subr_beru_ (info, FFECOM_gfrtFREW);
4712 /* INQUIRE statement (non-IOLENGTH version). */
4715 ffeste_R923A (ffestpInquireStmt *info, bool by_file UNUSED)
4717 ffeste_check_simple_ ();
4719 #if FFECOM_targetCURRENT == FFECOM_targetFFE
4722 fputs ("+ INQUIRE_file (", dmpout);
4723 ffeste_subr_file_ ("FILE", &info->inquire_spec[FFESTP_inquireixFILE]);
4727 fputs ("+ INQUIRE_unit (", dmpout);
4728 ffeste_subr_file_ ("UNIT", &info->inquire_spec[FFESTP_inquireixUNIT]);
4730 ffeste_subr_file_ ("ACCESS", &info->inquire_spec[FFESTP_inquireixACCESS]);
4731 ffeste_subr_file_ ("ACTION", &info->inquire_spec[FFESTP_inquireixACTION]);
4732 ffeste_subr_file_ ("BLANK", &info->inquire_spec[FFESTP_inquireixBLANK]);
4733 ffeste_subr_file_ ("CARRIAGECONTROL", &info->inquire_spec[FFESTP_inquireixCARRIAGECONTROL]);
4734 ffeste_subr_file_ ("DEFAULTFILE", &info->inquire_spec[FFESTP_inquireixDEFAULTFILE]);
4735 ffeste_subr_file_ ("DELIM", &info->inquire_spec[FFESTP_inquireixDELIM]);
4736 ffeste_subr_file_ ("DIRECT", &info->inquire_spec[FFESTP_inquireixDIRECT]);
4737 ffeste_subr_file_ ("ERR", &info->inquire_spec[FFESTP_inquireixERR]);
4738 ffeste_subr_file_ ("EXIST", &info->inquire_spec[FFESTP_inquireixEXIST]);
4739 ffeste_subr_file_ ("FORM", &info->inquire_spec[FFESTP_inquireixFORM]);
4740 ffeste_subr_file_ ("FORMATTED", &info->inquire_spec[FFESTP_inquireixFORMATTED]);
4741 ffeste_subr_file_ ("IOSTAT", &info->inquire_spec[FFESTP_inquireixIOSTAT]);
4742 ffeste_subr_file_ ("KEYED", &info->inquire_spec[FFESTP_inquireixKEYED]);
4743 ffeste_subr_file_ ("NAME", &info->inquire_spec[FFESTP_inquireixNAME]);
4744 ffeste_subr_file_ ("NAMED", &info->inquire_spec[FFESTP_inquireixNAMED]);
4745 ffeste_subr_file_ ("NEXTREC", &info->inquire_spec[FFESTP_inquireixNEXTREC]);
4746 ffeste_subr_file_ ("NUMBER", &info->inquire_spec[FFESTP_inquireixNUMBER]);
4747 ffeste_subr_file_ ("OPENED", &info->inquire_spec[FFESTP_inquireixOPENED]);
4748 ffeste_subr_file_ ("ORGANIZATION", &info->inquire_spec[FFESTP_inquireixORGANIZATION]);
4749 ffeste_subr_file_ ("PAD", &info->inquire_spec[FFESTP_inquireixPAD]);
4750 ffeste_subr_file_ ("POSITION", &info->inquire_spec[FFESTP_inquireixPOSITION]);
4751 ffeste_subr_file_ ("READ", &info->inquire_spec[FFESTP_inquireixREAD]);
4752 ffeste_subr_file_ ("READWRITE", &info->inquire_spec[FFESTP_inquireixREADWRITE]);
4753 ffeste_subr_file_ ("RECL", &info->inquire_spec[FFESTP_inquireixRECL]);
4754 ffeste_subr_file_ ("RECORDTYPE", &info->inquire_spec[FFESTP_inquireixRECORDTYPE]);
4755 ffeste_subr_file_ ("SEQUENTIAL", &info->inquire_spec[FFESTP_inquireixSEQUENTIAL]);
4756 ffeste_subr_file_ ("UNFORMATTED", &info->inquire_spec[FFESTP_inquireixUNFORMATTED]);
4757 ffeste_subr_file_ ("WRITE", &info->inquire_spec[FFESTP_inquireixWRITE]);
4758 fputs (")\n", dmpout);
4759 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
4765 ffeste_emit_line_note_ ();
4767 #define specified(something) (info->inquire_spec[something].kw_or_val_present)
4769 iostat = specified (FFESTP_inquireixIOSTAT);
4770 errl = specified (FFESTP_inquireixERR);
4774 ffeste_start_stmt_ ();
4780 = ffecom_lookup_label
4781 (info->inquire_spec[FFESTP_inquireixERR].u.label);
4782 ffeste_io_abort_is_temp_ = FALSE;
4786 ffeste_io_err_ = NULL_TREE;
4788 if ((ffeste_io_abort_is_temp_ = iostat))
4789 ffeste_io_abort_ = ffecom_temp_label ();
4791 ffeste_io_abort_ = NULL_TREE;
4796 /* Have IOSTAT= specification. */
4798 ffeste_io_iostat_is_temp_ = FALSE;
4799 ffeste_io_iostat_ = ffecom_expr
4800 (info->inquire_spec[FFESTP_inquireixIOSTAT].u.expr);
4802 else if (ffeste_io_abort_ != NULL_TREE)
4804 /* Have no IOSTAT= but have ERR=. */
4806 ffeste_io_iostat_is_temp_ = TRUE;
4808 = ffecom_make_tempvar ("inquire", ffecom_integer_type_node,
4809 FFETARGET_charactersizeNONE, -1);
4813 /* No IOSTAT= or ERR= specification. */
4815 ffeste_io_iostat_is_temp_ = FALSE;
4816 ffeste_io_iostat_ = NULL_TREE;
4819 /* Now prescan, then convert, all the arguments. */
4822 = ffeste_io_inlist_ (errl || iostat,
4823 &info->inquire_spec[FFESTP_inquireixUNIT],
4824 &info->inquire_spec[FFESTP_inquireixFILE],
4825 &info->inquire_spec[FFESTP_inquireixEXIST],
4826 &info->inquire_spec[FFESTP_inquireixOPENED],
4827 &info->inquire_spec[FFESTP_inquireixNUMBER],
4828 &info->inquire_spec[FFESTP_inquireixNAMED],
4829 &info->inquire_spec[FFESTP_inquireixNAME],
4830 &info->inquire_spec[FFESTP_inquireixACCESS],
4831 &info->inquire_spec[FFESTP_inquireixSEQUENTIAL],
4832 &info->inquire_spec[FFESTP_inquireixDIRECT],
4833 &info->inquire_spec[FFESTP_inquireixFORM],
4834 &info->inquire_spec[FFESTP_inquireixFORMATTED],
4835 &info->inquire_spec[FFESTP_inquireixUNFORMATTED],
4836 &info->inquire_spec[FFESTP_inquireixRECL],
4837 &info->inquire_spec[FFESTP_inquireixNEXTREC],
4838 &info->inquire_spec[FFESTP_inquireixBLANK]);
4840 /* Don't generate "if (iostat != 0) goto label;" if label is temp abort
4841 label, since we're gonna fall through to there anyway. */
4843 ffeste_io_call_ (ffecom_call_gfrt (FFECOM_gfrtFINQU, args, NULL_TREE),
4844 ! ffeste_io_abort_is_temp_);
4846 /* If we've got a temp label, generate its code here. */
4848 if (ffeste_io_abort_is_temp_)
4850 DECL_INITIAL (ffeste_io_abort_) = error_mark_node;
4852 expand_label (ffeste_io_abort_);
4854 assert (ffeste_io_err_ == NULL_TREE);
4857 ffeste_end_stmt_ ();
4864 /* INQUIRE(IOLENGTH=expr) statement -- start. */
4867 ffeste_R923B_start (ffestpInquireStmt *info UNUSED)
4869 ffeste_check_start_ ();
4871 #if FFECOM_targetCURRENT == FFECOM_targetFFE
4872 fputs ("+ INQUIRE (", dmpout);
4873 ffeste_subr_file_ ("IOLENGTH", &info->inquire_spec[FFESTP_inquireixIOLENGTH]);
4874 fputs (") ", dmpout);
4875 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
4876 assert ("INQUIRE(IOLENGTH=<var>) not implemented yet! ~~~" == NULL);
4878 ffeste_emit_line_note_ ();
4884 /* INQUIRE(IOLENGTH=expr) statement -- I/O item. */
4887 ffeste_R923B_item (ffebld expr UNUSED)
4889 ffeste_check_item_ ();
4891 #if FFECOM_targetCURRENT == FFECOM_targetFFE
4893 fputc (',', dmpout);
4894 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
4900 /* INQUIRE(IOLENGTH=expr) statement -- end. */
4903 ffeste_R923B_finish ()
4905 ffeste_check_finish_ ();
4907 #if FFECOM_targetCURRENT == FFECOM_targetFFE
4908 fputc ('\n', dmpout);
4909 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
4915 /* ffeste_R1001 -- FORMAT statement
4917 ffeste_R1001(format_list); */
4920 ffeste_R1001 (ffests s)
4922 ffeste_check_simple_ ();
4924 #if FFECOM_targetCURRENT == FFECOM_targetFFE
4925 fprintf (dmpout, "$ FORMAT %.*s\n", (int) ffests_length (s), ffests_text (s));
4926 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
4933 assert (ffeste_label_formatdef_ != NULL);
4935 ffeste_emit_line_note_ ();
4937 t = build_string (ffests_length (s), ffests_text (s));
4940 = build_type_variant (build_array_type
4942 build_range_type (integer_type_node,
4944 build_int_2 (ffests_length (s),
4947 TREE_CONSTANT (t) = 1;
4948 TREE_STATIC (t) = 1;
4950 var = ffecom_lookup_label (ffeste_label_formatdef_);
4951 if ((var != NULL_TREE)
4952 && (TREE_CODE (var) == VAR_DECL))
4954 DECL_INITIAL (var) = t;
4955 maxindex = build_int_2 (ffests_length (s) - 1, 0);
4956 ttype = TREE_TYPE (var);
4957 TYPE_DOMAIN (ttype) = build_range_type (integer_type_node,
4960 if (!TREE_TYPE (maxindex))
4961 TREE_TYPE (maxindex) = TYPE_DOMAIN (ttype);
4962 layout_type (ttype);
4963 rest_of_decl_compilation (var, NULL, 1, 0);
4965 expand_decl_init (var);
4968 ffeste_label_formatdef_ = NULL;
4980 #if FFECOM_targetCURRENT == FFECOM_targetFFE
4981 fputs ("+ END_PROGRAM\n", dmpout);
4982 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
4988 /* END BLOCK DATA. */
4993 #if FFECOM_targetCURRENT == FFECOM_targetFFE
4994 fputs ("* END_BLOCK_DATA\n", dmpout);
4995 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5001 /* CALL statement. */
5004 ffeste_R1212 (ffebld expr)
5006 ffeste_check_simple_ ();
5008 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5009 fputs ("+ CALL ", dmpout);
5011 fputc ('\n', dmpout);
5012 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5014 ffebld args = ffebld_right (expr);
5016 ffebld labels = NULL; /* First in list of LABTERs. */
5017 ffebld prevlabels = NULL;
5018 ffebld prevargs = NULL;
5020 ffeste_emit_line_note_ ();
5022 /* Here we split the list at ffebld_right(expr) into two lists: one at
5023 ffebld_right(expr) consisting of all items that are not LABTERs, the
5024 other at labels consisting of all items that are LABTERs. Then, if
5025 the latter list is NULL, we have an ordinary call, else we have a call
5026 with alternate returns. */
5028 for (args = ffebld_right (expr); args != NULL; args = ffebld_trail (args))
5030 if (((arg = ffebld_head (args)) == NULL)
5031 || (ffebld_op (arg) != FFEBLD_opLABTER))
5033 if (prevargs == NULL)
5036 ffebld_set_right (expr, args);
5040 ffebld_set_trail (prevargs, args);
5046 if (prevlabels == NULL)
5048 prevlabels = labels = args;
5052 ffebld_set_trail (prevlabels, args);
5057 if (prevlabels == NULL)
5060 ffebld_set_trail (prevlabels, NULL);
5061 if (prevargs == NULL)
5062 ffebld_set_right (expr, NULL);
5064 ffebld_set_trail (prevargs, NULL);
5066 ffeste_start_stmt_ ();
5068 /* No temporaries are actually needed at this level, but we go
5069 through the motions anyway, just to be sure in case they do
5070 get made. Temporaries needed for arguments should be in the
5071 scopes of inner blocks, and if clean-up actions are supported,
5072 such as CALL-ing an intrinsic that writes to an argument of one
5073 type when a variable of a different type is provided (requiring
5074 assignment to the variable from a temporary after the library
5075 routine returns), the clean-up must be done by the expression
5076 evaluator, generally, to handle alternate returns (which we hope
5077 won't ever be supported by intrinsics, but might be a similar
5078 issue, such as CALL-ing an F90-style subroutine with an INTERFACE
5079 block). That implies the expression evaluator will have to
5080 recognize the need for its own temporary anyway, meaning it'll
5081 construct a block within the one constructed here. */
5083 ffecom_prepare_expr (expr);
5085 ffecom_prepare_end ();
5088 expand_expr_stmt (ffecom_expr (expr));
5099 texpr = ffecom_expr (expr);
5100 expand_start_case (0, texpr, TREE_TYPE (texpr), "CALL statement");
5102 for (caseno = 1, label = labels;
5104 ++caseno, label = ffebld_trail (label))
5106 value = build_int_2 (caseno, 0);
5107 tlabel = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
5109 pushok = pushcase (value, convert, tlabel, &duplicate);
5110 assert (pushok == 0);
5113 = ffecom_lookup_label (ffebld_labter (ffebld_head (label)));
5114 if ((tlabel == NULL_TREE)
5115 || (TREE_CODE (tlabel) == ERROR_MARK))
5117 TREE_USED (tlabel) = 1;
5118 expand_goto (tlabel);
5121 expand_end_case (texpr);
5124 ffeste_end_stmt_ ();
5136 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5137 fputs ("+ END_FUNCTION\n", dmpout);
5138 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5144 /* END SUBROUTINE. */
5149 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5150 fprintf (dmpout, "+ END_SUBROUTINE\n");
5151 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5157 /* ENTRY statement. */
5160 ffeste_R1226 (ffesymbol entry)
5162 ffeste_check_simple_ ();
5164 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5165 fprintf (dmpout, "+ ENTRY %s", ffesymbol_text (entry));
5166 if (ffesymbol_dummyargs (entry) != NULL)
5170 fputc ('(', dmpout);
5171 for (argh = ffesymbol_dummyargs (entry);
5173 argh = ffebld_trail (argh))
5175 assert (ffebld_head (argh) != NULL);
5176 switch (ffebld_op (ffebld_head (argh)))
5178 case FFEBLD_opSYMTER:
5179 fputs (ffesymbol_text (ffebld_symter (ffebld_head (argh))),
5184 fputc ('*', dmpout);
5188 fputc ('?', dmpout);
5189 ffebld_dump (ffebld_head (argh));
5190 fputc ('?', dmpout);
5193 if (ffebld_trail (argh) != NULL)
5194 fputc (',', dmpout);
5196 fputc (')', dmpout);
5198 fputc ('\n', dmpout);
5199 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5201 tree label = ffesymbol_hook (entry).length_tree;
5203 ffeste_emit_line_note_ ();
5205 if (label == error_mark_node)
5208 DECL_INITIAL (label) = error_mark_node;
5210 expand_label (label);
5217 /* RETURN statement. */
5220 ffeste_R1227 (ffestw block UNUSED, ffebld expr)
5222 ffeste_check_simple_ ();
5224 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5227 fputs ("+ RETURN\n", dmpout);
5231 fputs ("+ RETURN_alternate ", dmpout);
5233 fputc ('\n', dmpout);
5235 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5239 ffeste_emit_line_note_ ();
5241 ffeste_start_stmt_ ();
5243 ffecom_prepare_return_expr (expr);
5245 ffecom_prepare_end ();
5247 rtn = ffecom_return_expr (expr);
5249 if ((rtn == NULL_TREE)
5250 || (rtn == error_mark_node))
5251 expand_null_return ();
5254 tree result = DECL_RESULT (current_function_decl);
5256 if ((result != error_mark_node)
5257 && (TREE_TYPE (result) != error_mark_node))
5258 expand_return (ffecom_modify (NULL_TREE,
5260 convert (TREE_TYPE (result),
5263 expand_null_return ();
5266 ffeste_end_stmt_ ();
5273 /* REWRITE statement -- start. */
5277 ffeste_V018_start (ffestpRewriteStmt *info, ffestvFormat format)
5279 ffeste_check_start_ ();
5281 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5284 case FFESTV_formatNONE:
5285 fputs ("+ REWRITE_uf (", dmpout);
5288 case FFESTV_formatLABEL:
5289 case FFESTV_formatCHAREXPR:
5290 case FFESTV_formatINTEXPR:
5291 fputs ("+ REWRITE_fm (", dmpout);
5295 assert ("Unexpected kind of format item in V018 REWRITE" == NULL);
5297 ffeste_subr_file_ ("UNIT", &info->rewrite_spec[FFESTP_rewriteixUNIT]);
5298 ffeste_subr_file_ ("FMT", &info->rewrite_spec[FFESTP_rewriteixFMT]);
5299 ffeste_subr_file_ ("ERR", &info->rewrite_spec[FFESTP_rewriteixERR]);
5300 ffeste_subr_file_ ("IOSTAT", &info->rewrite_spec[FFESTP_rewriteixIOSTAT]);
5301 fputs (") ", dmpout);
5302 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5308 /* REWRITE statement -- I/O item. */
5311 ffeste_V018_item (ffebld expr)
5313 ffeste_check_item_ ();
5315 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5317 fputc (',', dmpout);
5318 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5324 /* REWRITE statement -- end. */
5327 ffeste_V018_finish ()
5329 ffeste_check_finish_ ();
5331 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5332 fputc ('\n', dmpout);
5333 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5339 /* ACCEPT statement -- start. */
5342 ffeste_V019_start (ffestpAcceptStmt *info, ffestvFormat format)
5344 ffeste_check_start_ ();
5346 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5349 case FFESTV_formatLABEL:
5350 case FFESTV_formatCHAREXPR:
5351 case FFESTV_formatINTEXPR:
5352 fputs ("+ ACCEPT_fm ", dmpout);
5355 case FFESTV_formatASTERISK:
5356 fputs ("+ ACCEPT_ls ", dmpout);
5359 case FFESTV_formatNAMELIST:
5360 fputs ("+ ACCEPT_nl ", dmpout);
5364 assert ("Unexpected kind of format item in V019 ACCEPT" == NULL);
5366 ffeste_subr_file_ ("FORMAT", &info->accept_spec[FFESTP_acceptixFORMAT]);
5367 fputc (' ', dmpout);
5368 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5374 /* ACCEPT statement -- I/O item. */
5377 ffeste_V019_item (ffebld expr)
5379 ffeste_check_item_ ();
5381 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5383 fputc (',', dmpout);
5384 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5390 /* ACCEPT statement -- end. */
5393 ffeste_V019_finish ()
5395 ffeste_check_finish_ ();
5397 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5398 fputc ('\n', dmpout);
5399 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5406 /* TYPE statement -- start. */
5409 ffeste_V020_start (ffestpTypeStmt *info UNUSED,
5410 ffestvFormat format UNUSED)
5412 ffeste_check_start_ ();
5414 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5417 case FFESTV_formatLABEL:
5418 case FFESTV_formatCHAREXPR:
5419 case FFESTV_formatINTEXPR:
5420 fputs ("+ TYPE_fm ", dmpout);
5423 case FFESTV_formatASTERISK:
5424 fputs ("+ TYPE_ls ", dmpout);
5427 case FFESTV_formatNAMELIST:
5428 fputs ("* TYPE_nl ", dmpout);
5432 assert ("Unexpected kind of format item in V020 TYPE" == NULL);
5434 ffeste_subr_file_ ("FORMAT", &info->type_spec[FFESTP_typeixFORMAT]);
5435 fputc (' ', dmpout);
5436 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5442 /* TYPE statement -- I/O item. */
5445 ffeste_V020_item (ffebld expr UNUSED)
5447 ffeste_check_item_ ();
5449 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5451 fputc (',', dmpout);
5452 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5458 /* TYPE statement -- end. */
5461 ffeste_V020_finish ()
5463 ffeste_check_finish_ ();
5465 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5466 fputc ('\n', dmpout);
5467 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5473 /* DELETE statement. */
5477 ffeste_V021 (ffestpDeleteStmt *info)
5479 ffeste_check_simple_ ();
5481 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5482 fputs ("+ DELETE (", dmpout);
5483 ffeste_subr_file_ ("UNIT", &info->delete_spec[FFESTP_deleteixUNIT]);
5484 ffeste_subr_file_ ("REC", &info->delete_spec[FFESTP_deleteixREC]);
5485 ffeste_subr_file_ ("ERR", &info->delete_spec[FFESTP_deleteixERR]);
5486 ffeste_subr_file_ ("IOSTAT", &info->delete_spec[FFESTP_deleteixIOSTAT]);
5487 fputs (")\n", dmpout);
5488 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5494 /* UNLOCK statement. */
5497 ffeste_V022 (ffestpBeruStmt *info)
5499 ffeste_check_simple_ ();
5501 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5502 fputs ("+ UNLOCK (", dmpout);
5503 ffeste_subr_file_ ("UNIT", &info->beru_spec[FFESTP_beruixUNIT]);
5504 ffeste_subr_file_ ("ERR", &info->beru_spec[FFESTP_beruixERR]);
5505 ffeste_subr_file_ ("IOSTAT", &info->beru_spec[FFESTP_beruixIOSTAT]);
5506 fputs (")\n", dmpout);
5507 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5513 /* ENCODE statement -- start. */
5516 ffeste_V023_start (ffestpVxtcodeStmt *info)
5518 ffeste_check_start_ ();
5520 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5521 fputs ("+ ENCODE (", dmpout);
5522 ffeste_subr_file_ ("C", &info->vxtcode_spec[FFESTP_vxtcodeixC]);
5523 ffeste_subr_file_ ("F", &info->vxtcode_spec[FFESTP_vxtcodeixF]);
5524 ffeste_subr_file_ ("B", &info->vxtcode_spec[FFESTP_vxtcodeixB]);
5525 ffeste_subr_file_ ("ERR", &info->vxtcode_spec[FFESTP_vxtcodeixERR]);
5526 ffeste_subr_file_ ("IOSTAT", &info->vxtcode_spec[FFESTP_vxtcodeixIOSTAT]);
5527 fputs (") ", dmpout);
5528 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5534 /* ENCODE statement -- I/O item. */
5537 ffeste_V023_item (ffebld expr)
5539 ffeste_check_item_ ();
5541 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5543 fputc (',', dmpout);
5544 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5550 /* ENCODE statement -- end. */
5553 ffeste_V023_finish ()
5555 ffeste_check_finish_ ();
5557 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5558 fputc ('\n', dmpout);
5559 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5565 /* DECODE statement -- start. */
5568 ffeste_V024_start (ffestpVxtcodeStmt *info)
5570 ffeste_check_start_ ();
5572 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5573 fputs ("+ DECODE (", dmpout);
5574 ffeste_subr_file_ ("C", &info->vxtcode_spec[FFESTP_vxtcodeixC]);
5575 ffeste_subr_file_ ("F", &info->vxtcode_spec[FFESTP_vxtcodeixF]);
5576 ffeste_subr_file_ ("B", &info->vxtcode_spec[FFESTP_vxtcodeixB]);
5577 ffeste_subr_file_ ("ERR", &info->vxtcode_spec[FFESTP_vxtcodeixERR]);
5578 ffeste_subr_file_ ("IOSTAT", &info->vxtcode_spec[FFESTP_vxtcodeixIOSTAT]);
5579 fputs (") ", dmpout);
5580 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5586 /* DECODE statement -- I/O item. */
5589 ffeste_V024_item (ffebld expr)
5591 ffeste_check_item_ ();
5593 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5595 fputc (',', dmpout);
5596 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5602 /* DECODE statement -- end. */
5605 ffeste_V024_finish ()
5607 ffeste_check_finish_ ();
5609 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5610 fputc ('\n', dmpout);
5611 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5617 /* DEFINEFILE statement -- start. */
5620 ffeste_V025_start ()
5622 ffeste_check_start_ ();
5624 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5625 fputs ("+ DEFINE_FILE ", dmpout);
5626 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5632 /* DEFINE FILE statement -- item. */
5635 ffeste_V025_item (ffebld u, ffebld m, ffebld n, ffebld asv)
5637 ffeste_check_item_ ();
5639 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5641 fputc ('(', dmpout);
5643 fputc (',', dmpout);
5645 fputs (",U,", dmpout);
5647 fputs ("),", dmpout);
5648 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5654 /* DEFINE FILE statement -- end. */
5657 ffeste_V025_finish ()
5659 ffeste_check_finish_ ();
5661 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5662 fputc ('\n', dmpout);
5663 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5669 /* FIND statement. */
5672 ffeste_V026 (ffestpFindStmt *info)
5674 ffeste_check_simple_ ();
5676 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5677 fputs ("+ FIND (", dmpout);
5678 ffeste_subr_file_ ("UNIT", &info->find_spec[FFESTP_findixUNIT]);
5679 ffeste_subr_file_ ("REC", &info->find_spec[FFESTP_findixREC]);
5680 ffeste_subr_file_ ("ERR", &info->find_spec[FFESTP_findixERR]);
5681 ffeste_subr_file_ ("IOSTAT", &info->find_spec[FFESTP_findixIOSTAT]);
5682 fputs (")\n", dmpout);
5683 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5691 #ifdef ENABLE_CHECKING
5693 ffeste_terminate_2 (void)
5695 assert (! ffeste_top_block_);