1 /* ste.c -- Implementation File (module.c template V1.0)
2 Copyright (C) 1995, 1996 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
55 /* Externals defined here. */
58 /* Simple definitions and enumerations. */
62 FFESTE_stateletSIMPLE_, /* Expecting simple/start. */
63 FFESTE_stateletATTRIB_, /* Expecting attrib/item/itemstart. */
64 FFESTE_stateletITEM_, /* Expecting item/itemstart/finish. */
65 FFESTE_stateletITEMVALS_, /* Expecting itemvalue/itemendvals. */
69 /* Internal typedefs. */
72 /* Private include files. */
75 /* Internal structure definitions. */
78 /* Static objects accessed by functions in this module. */
80 static ffesteStatelet_ ffeste_statelet_ = FFESTE_stateletSIMPLE_;
81 #if FFECOM_targetCURRENT == FFECOM_targetGCC
82 static ffelab ffeste_label_formatdef_ = NULL;
83 static tree (*ffeste_io_driver_) (ffebld expr); /* do?io. */
84 static ffecomGfrt ffeste_io_endgfrt_; /* end function to call. */
85 static tree ffeste_io_abort_; /* abort-io label or NULL_TREE. */
86 static bool ffeste_io_abort_is_temp_; /* abort-io label is a temp. */
87 static tree ffeste_io_end_; /* END= label or NULL_TREE. */
88 static tree ffeste_io_err_; /* ERR= label or NULL_TREE. */
89 static tree ffeste_io_iostat_; /* IOSTAT= var or NULL_TREE. */
90 static bool ffeste_io_iostat_is_temp_; /* IOSTAT= var is a temp. */
93 /* Static functions (internal). */
95 #if FFECOM_targetCURRENT == FFECOM_targetGCC
96 static void ffeste_begin_iterdo_ (ffestw block, tree *tvar, tree *tincr,
97 tree *xitersvar, ffebld var,
98 ffebld start, ffelexToken start_token,
99 ffebld end, ffelexToken end_token,
100 ffebld incr, ffelexToken incr_token,
102 static void ffeste_end_iterdo_ (ffestw block, tree tvar, tree tincr,
104 static void ffeste_io_call_ (tree call, bool do_check);
105 static void ffeste_io_impdo_ (ffebld impdo, ffelexToken impdo_token);
106 static tree ffeste_io_dofio_ (ffebld expr);
107 static tree ffeste_io_dolio_ (ffebld expr);
108 static tree ffeste_io_douio_ (ffebld expr);
109 static tree ffeste_io_ialist_ (bool have_err, ffestvUnit unit,
110 ffebld unit_expr, int unit_dflt);
111 static tree ffeste_io_cilist_ (bool have_err, ffestvUnit unit,
112 ffebld unit_expr, int unit_dflt,
113 bool have_end, ffestvFormat format,
114 ffestpFile *format_spec, bool rec,
116 static tree ffeste_io_cllist_ (bool have_err, ffebld unit_expr,
117 ffestpFile *stat_spec);
118 static tree ffeste_io_icilist_ (bool have_err, ffebld unit_expr,
119 bool have_end, ffestvFormat format,
120 ffestpFile *format_spec);
121 static tree ffeste_io_inlist_ (bool have_err,
122 ffestpFile *unit_spec,
123 ffestpFile *file_spec,
124 ffestpFile *exist_spec,
125 ffestpFile *open_spec,
126 ffestpFile *number_spec,
127 ffestpFile *named_spec,
128 ffestpFile *name_spec,
129 ffestpFile *access_spec,
130 ffestpFile *sequential_spec,
131 ffestpFile *direct_spec,
132 ffestpFile *form_spec,
133 ffestpFile *formatted_spec,
134 ffestpFile *unformatted_spec,
135 ffestpFile *recl_spec,
136 ffestpFile *nextrec_spec,
137 ffestpFile *blank_spec);
138 static tree ffeste_io_olist_ (bool have_err, ffebld unit_expr,
139 ffestpFile *file_spec,
140 ffestpFile *stat_spec,
141 ffestpFile *access_spec,
142 ffestpFile *form_spec,
143 ffestpFile *recl_spec,
144 ffestpFile *blank_spec);
145 static void ffeste_subr_beru_ (ffestpBeruStmt *info, ffecomGfrt rt);
146 #elif FFECOM_targetCURRENT == FFECOM_targetFFE
147 static void ffeste_subr_file_ (const char *kw, ffestpFile *spec);
152 /* Internal macros. */
154 #if FFECOM_targetCURRENT == FFECOM_targetGCC
155 #define ffeste_emit_line_note_() \
156 emit_line_note (input_filename, lineno)
158 #define ffeste_check_simple_() \
159 assert(ffeste_statelet_ == FFESTE_stateletSIMPLE_)
160 #define ffeste_check_start_() \
161 assert(ffeste_statelet_ == FFESTE_stateletSIMPLE_); \
162 ffeste_statelet_ = FFESTE_stateletATTRIB_
163 #define ffeste_check_attrib_() \
164 assert(ffeste_statelet_ == FFESTE_stateletATTRIB_)
165 #define ffeste_check_item_() \
166 assert(ffeste_statelet_ == FFESTE_stateletATTRIB_ \
167 || ffeste_statelet_ == FFESTE_stateletITEM_); \
168 ffeste_statelet_ = FFESTE_stateletITEM_
169 #define ffeste_check_item_startvals_() \
170 assert(ffeste_statelet_ == FFESTE_stateletATTRIB_ \
171 || ffeste_statelet_ == FFESTE_stateletITEM_); \
172 ffeste_statelet_ = FFESTE_stateletITEMVALS_
173 #define ffeste_check_item_value_() \
174 assert(ffeste_statelet_ == FFESTE_stateletITEMVALS_)
175 #define ffeste_check_item_endvals_() \
176 assert(ffeste_statelet_ == FFESTE_stateletITEMVALS_); \
177 ffeste_statelet_ = FFESTE_stateletITEM_
178 #define ffeste_check_finish_() \
179 assert(ffeste_statelet_ == FFESTE_stateletATTRIB_ \
180 || ffeste_statelet_ == FFESTE_stateletITEM_); \
181 ffeste_statelet_ = FFESTE_stateletSIMPLE_
183 #define ffeste_f2c_init_charnolen_(Exp,Init,Spec) \
186 if ((Spec)->kw_or_val_present) \
187 Exp = ffecom_arg_ptr_to_const_expr ((Spec)->u.expr, &ignore); \
189 Exp = null_pointer_node; \
194 Init = null_pointer_node; \
199 #define ffeste_f2c_init_char_(Exp,Init,Lenexp,Leninit,Spec) \
202 if ((Spec)->kw_or_val_present) \
203 Exp = ffecom_arg_ptr_to_const_expr ((Spec)->u.expr, &Lenexp); \
206 Exp = null_pointer_node; \
207 Lenexp = ffecom_f2c_ftnlen_zero_node; \
213 Init = null_pointer_node; \
220 Leninit = ffecom_f2c_ftnlen_zero_node; \
225 #define ffeste_f2c_init_flag_(Flag,Init) \
228 Init = convert (ffecom_f2c_flag_type_node, \
229 (Flag) ? integer_one_node : integer_zero_node); \
232 #define ffeste_f2c_init_format_(Exp,Init,Spec) \
235 Exp = ffecom_arg_ptr_to_const_expr ((Spec)->u.expr, NULL); \
240 Init = null_pointer_node; \
245 #define ffeste_f2c_init_int_(Exp,Init,Spec) \
248 if ((Spec)->kw_or_val_present) \
249 Exp = ffecom_const_expr ((Spec)->u.expr); \
251 Exp = ffecom_integer_zero_node; \
256 Init = ffecom_integer_zero_node; \
261 #define ffeste_f2c_init_ptrtoint_(Exp,Init,Spec) \
264 if ((Spec)->kw_or_val_present) \
265 Exp = ffecom_ptr_to_const_expr ((Spec)->u.expr); \
267 Exp = null_pointer_node; \
272 Init = null_pointer_node; \
277 #define ffeste_f2c_init_next_(Init) \
280 TREE_CHAIN (initn) = build_tree_list ((field = TREE_CHAIN (field)), \
282 initn = TREE_CHAIN(initn); \
285 #define ffeste_f2c_prepare_charnolen_(Spec,Exp) \
289 ffecom_prepare_arg_ptr_to_expr ((Spec)->u.expr); \
292 #define ffeste_f2c_prepare_char_(Spec,Exp) \
296 ffecom_prepare_arg_ptr_to_expr ((Spec)->u.expr); \
299 #define ffeste_f2c_prepare_format_(Spec,Exp) \
303 ffecom_prepare_arg_ptr_to_expr ((Spec)->u.expr); \
306 #define ffeste_f2c_prepare_int_(Spec,Exp) \
310 ffecom_prepare_expr ((Spec)->u.expr); \
313 #define ffeste_f2c_prepare_ptrtoint_(Spec,Exp) \
317 ffecom_prepare_ptr_to_expr ((Spec)->u.expr); \
320 #define ffeste_f2c_compile_(Field,Exp) \
326 exz = ffecom_modify (void_type_node, \
327 ffecom_2 (COMPONENT_REF, TREE_TYPE (Field), \
330 expand_expr_stmt (exz); \
334 #define ffeste_f2c_compile_charnolen_(Field,Spec,Exp) \
340 exq = ffecom_arg_ptr_to_expr ((Spec)->u.expr, &ignore); \
341 ffeste_f2c_compile_ ((Field), exq); \
345 #define ffeste_f2c_compile_char_(Field,Lenfield,Spec,Exp,Lenexp) \
349 tree lenexq = (Lenexp); \
350 int need_exq = (! exq); \
351 int need_lenexq = (! lenexq); \
352 if (need_exq || need_lenexq) \
354 exq = ffecom_arg_ptr_to_expr ((Spec)->u.expr, &lenexq); \
356 ffeste_f2c_compile_ ((Field), exq); \
358 ffeste_f2c_compile_ ((Lenfield), lenexq); \
362 #define ffeste_f2c_compile_format_(Field,Spec,Exp) \
368 exq = ffecom_arg_ptr_to_expr ((Spec)->u.expr, NULL); \
369 ffeste_f2c_compile_ ((Field), exq); \
373 #define ffeste_f2c_compile_int_(Field,Spec,Exp) \
379 exq = ffecom_expr ((Spec)->u.expr); \
380 ffeste_f2c_compile_ ((Field), exq); \
384 #define ffeste_f2c_compile_ptrtoint_(Field,Spec,Exp) \
390 exq = ffecom_ptr_to_expr ((Spec)->u.expr); \
391 ffeste_f2c_compile_ ((Field), exq); \
395 /* Start a Fortran block. */
397 #ifdef ENABLE_CHECKING
399 typedef struct gbe_block
401 struct gbe_block *outer;
404 char *input_filename;
408 gbe_block ffeste_top_block_ = NULL;
411 ffeste_start_block_ (ffestw block)
413 gbe_block b = xmalloc (sizeof (*b));
415 b->outer = ffeste_top_block_;
418 b->input_filename = input_filename;
421 ffeste_top_block_ = b;
423 ffecom_start_compstmt ();
426 /* End a Fortran block. */
429 ffeste_end_block_ (ffestw block)
431 gbe_block b = ffeste_top_block_;
434 assert (! b->is_stmt);
435 assert (b->block == block);
436 assert (! b->is_stmt);
438 ffeste_top_block_ = b->outer;
444 ffecom_end_compstmt ();
447 /* Start a Fortran statement.
449 Starts a back-end block, so temporaries can be managed, clean-ups
450 properly handled, etc. Nesting of statements *is* allowed -- the
451 handling of I/O items, even implied-DO I/O lists, within a READ,
452 PRINT, or WRITE statement is one example. */
455 ffeste_start_stmt_(void)
457 gbe_block b = xmalloc (sizeof (*b));
459 b->outer = ffeste_top_block_;
462 b->input_filename = input_filename;
465 ffeste_top_block_ = b;
467 ffecom_start_compstmt ();
470 /* End a Fortran statement. */
473 ffeste_end_stmt_(void)
475 gbe_block b = ffeste_top_block_;
480 ffeste_top_block_ = b->outer;
486 ffecom_end_compstmt ();
489 #else /* ! defined (ENABLE_CHECKING) */
491 #define ffeste_start_block_(b) ffecom_start_compstmt ()
492 #define ffeste_end_block_(b) \
495 clear_momentary (); \
496 ffecom_end_compstmt (); \
498 #define ffeste_start_stmt_() ffeste_start_block_(NULL)
499 #define ffeste_end_stmt_() ffeste_end_block_(NULL)
501 #endif /* ! defined (ENABLE_CHECKING) */
503 /* Begin an iterative DO loop. Pass the block to start if applicable.
505 NOTE: Does _two_ push_momentary () calls, which the caller must
506 undo (by calling ffeste_end_iterdo_). */
508 #if FFECOM_targetCURRENT == FFECOM_targetGCC
510 ffeste_begin_iterdo_ (ffestw block, tree *xtvar, tree *xtincr,
511 tree *xitersvar, ffebld var,
512 ffebld start, ffelexToken start_token,
513 ffebld end, ffelexToken end_token,
514 ffebld incr, ffelexToken incr_token,
524 struct nesting *expanded_loop;
526 /* Want to have tvar, tincr, and niters for the whole loop body. */
529 ffeste_start_block_ (block);
531 ffeste_start_stmt_ ();
533 niters = ffecom_make_tempvar (block ? "do" : "impdo",
534 ffecom_integer_type_node,
535 FFETARGET_charactersizeNONE, -1);
537 ffecom_prepare_expr (incr);
538 ffecom_prepare_expr_rw (NULL_TREE, var);
540 ffecom_prepare_end ();
542 tvar = ffecom_expr_rw (NULL_TREE, var);
543 tincr = ffecom_expr (incr);
545 if (TREE_CODE (tvar) == ERROR_MARK
546 || TREE_CODE (tincr) == ERROR_MARK)
550 ffeste_end_block_ (block);
551 ffestw_set_do_tvar (block, error_mark_node);
556 *xtvar = error_mark_node;
561 /* Check whether incr is known to be zero, complain and fix. */
563 if (integer_zerop (tincr) || real_zerop (tincr))
565 ffebad_start (FFEBAD_DO_STEP_ZERO);
566 ffebad_here (0, ffelex_token_where_line (incr_token),
567 ffelex_token_where_column (incr_token));
570 tincr = convert (TREE_TYPE (tvar), integer_one_node);
573 tincr_saved = ffecom_save_tree (tincr);
575 preserve_momentary ();
577 /* Want to have tstart, tend for just this statement. */
579 ffeste_start_stmt_ ();
581 ffecom_prepare_expr (start);
582 ffecom_prepare_expr (end);
584 ffecom_prepare_end ();
586 tstart = ffecom_expr (start);
587 tend = ffecom_expr (end);
589 if (TREE_CODE (tstart) == ERROR_MARK
590 || TREE_CODE (tend) == ERROR_MARK)
596 ffeste_end_block_ (block);
597 ffestw_set_do_tvar (block, error_mark_node);
602 *xtvar = error_mark_node;
607 /* For warnings only, nothing else happens here. */
611 if (! ffe_is_onetrip ())
613 try = ffecom_2 (MINUS_EXPR, TREE_TYPE (tvar),
617 try = ffecom_2 (PLUS_EXPR, TREE_TYPE (tvar),
621 if (TREE_CODE (TREE_TYPE (tvar)) != REAL_TYPE)
622 try = ffecom_2 (TRUNC_DIV_EXPR, integer_type_node, try,
625 try = convert (integer_type_node,
626 ffecom_2 (RDIV_EXPR, TREE_TYPE (tvar),
630 /* Warn if loop never executed, since we've done the evaluation
631 of the unofficial iteration count already. */
633 try = ffecom_truth_value (ffecom_2 (LE_EXPR, integer_type_node,
635 convert (TREE_TYPE (tvar),
636 integer_zero_node)));
638 if (integer_onep (try))
640 ffebad_start (FFEBAD_DO_NULL);
641 ffebad_here (0, ffelex_token_where_line (start_token),
642 ffelex_token_where_column (start_token));
648 /* Warn if end plus incr would overflow. */
650 try = ffecom_2 (PLUS_EXPR, TREE_TYPE (tvar),
654 if ((TREE_CODE_CLASS (TREE_CODE (try)) == 'c')
655 && TREE_CONSTANT_OVERFLOW (try))
657 ffebad_start (FFEBAD_DO_END_OVERFLOW);
658 ffebad_here (0, ffelex_token_where_line (end_token),
659 ffelex_token_where_column (end_token));
665 /* Do the initial assignment into the DO var. */
667 tstart = ffecom_save_tree (tstart);
669 expr = ffecom_2 (MINUS_EXPR, TREE_TYPE (tvar),
673 if (! ffe_is_onetrip ())
675 expr = ffecom_2 (PLUS_EXPR, TREE_TYPE (expr),
677 convert (TREE_TYPE (expr), tincr_saved));
680 if (TREE_CODE (TREE_TYPE (tvar)) != REAL_TYPE)
681 expr = ffecom_2 (TRUNC_DIV_EXPR, TREE_TYPE (expr),
685 expr = ffecom_2 (RDIV_EXPR, TREE_TYPE (expr),
689 #if 1 /* New, F90-approved approach: convert to default INTEGER. */
690 if (TREE_TYPE (tvar) != error_mark_node)
691 expr = convert (ffecom_integer_type_node, expr);
692 #else /* Old approach; convert to INTEGER unless that's a narrowing. */
693 if ((TREE_TYPE (tvar) != error_mark_node)
694 && ((TREE_CODE (TREE_TYPE (tvar)) != INTEGER_TYPE)
695 || ((TYPE_SIZE (TREE_TYPE (tvar)) != NULL_TREE)
696 && ((TREE_CODE (TYPE_SIZE (TREE_TYPE (tvar)))
698 || (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (tvar)))
699 <= TREE_INT_CST_LOW (TYPE_SIZE (ffecom_integer_type_node)))))))
700 /* Convert unless promoting INTEGER type of any kind downward to
701 default INTEGER; else leave as, say, INTEGER*8 (long long int). */
702 expr = convert (ffecom_integer_type_node, expr);
705 assert (TYPE_MAIN_VARIANT (TREE_TYPE (niters))
706 == TYPE_MAIN_VARIANT (TREE_TYPE (expr)));
708 expr = ffecom_modify (void_type_node, niters, expr);
709 expand_expr_stmt (expr);
711 expr = ffecom_modify (void_type_node, tvar, tstart);
712 expand_expr_stmt (expr);
716 expanded_loop = expand_start_loop_continue_elsewhere (!! block);
718 ffestw_set_do_hook (block, expanded_loop);
720 if (! ffe_is_onetrip ())
722 expr = ffecom_truth_value
723 (ffecom_2 (GE_EXPR, integer_type_node,
724 ffecom_2 (PREDECREMENT_EXPR,
727 convert (TREE_TYPE (niters),
728 ffecom_integer_one_node)),
729 convert (TREE_TYPE (niters),
730 ffecom_integer_zero_node)));
732 expand_exit_loop_if_false (0, expr);
737 ffestw_set_do_tvar (block, tvar);
738 ffestw_set_do_incr_saved (block, tincr_saved);
739 ffestw_set_do_count_var (block, niters);
744 *xtincr = tincr_saved;
751 /* End an iterative DO loop. Pass the same iteration variable and increment
752 value trees that were generated in the paired _begin_ call. */
754 #if FFECOM_targetCURRENT == FFECOM_targetGCC
756 ffeste_end_iterdo_ (ffestw block, tree tvar, tree tincr, tree itersvar)
759 tree niters = itersvar;
761 if (tvar == error_mark_node)
764 expand_loop_continue_here ();
766 ffeste_start_stmt_ ();
768 if (ffe_is_onetrip ())
770 expr = ffecom_truth_value
771 (ffecom_2 (GE_EXPR, integer_type_node,
772 ffecom_2 (PREDECREMENT_EXPR,
775 convert (TREE_TYPE (niters),
776 ffecom_integer_one_node)),
777 convert (TREE_TYPE (niters),
778 ffecom_integer_zero_node)));
780 expand_exit_loop_if_false (0, expr);
783 expr = ffecom_modify (void_type_node, tvar,
784 ffecom_2 (PLUS_EXPR, TREE_TYPE (tvar),
787 expand_expr_stmt (expr);
789 /* Lose the stuff we just built. */
794 /* Lose the tvar and incr_saved trees. */
796 ffeste_end_block_ (block);
802 /* Generate call to run-time I/O routine. */
804 #if FFECOM_targetCURRENT == FFECOM_targetGCC
806 ffeste_io_call_ (tree call, bool do_check)
808 /* Generate the call and optional assignment into iostat var. */
810 TREE_SIDE_EFFECTS (call) = 1;
811 if (ffeste_io_iostat_ != NULL_TREE)
812 call = ffecom_modify (do_check ? NULL_TREE : void_type_node,
813 ffeste_io_iostat_, call);
814 expand_expr_stmt (call);
817 || ffeste_io_abort_ == NULL_TREE
818 || TREE_CODE (ffeste_io_abort_) == ERROR_MARK)
821 /* Generate optional test. */
823 expand_start_cond (ffecom_truth_value (ffeste_io_iostat_), 0);
824 expand_goto (ffeste_io_abort_);
829 /* Handle implied-DO in I/O list.
831 Expands code to start up the DO loop. Then for each item in the
832 DO loop, handles appropriately (possibly including recursively calling
833 itself). Then expands code to end the DO loop. */
835 #if FFECOM_targetCURRENT == FFECOM_targetGCC
837 ffeste_io_impdo_ (ffebld impdo, ffelexToken impdo_token)
839 ffebld var = ffebld_head (ffebld_right (impdo));
840 ffebld start = ffebld_head (ffebld_trail (ffebld_right (impdo)));
841 ffebld end = ffebld_head (ffebld_trail (ffebld_trail
842 (ffebld_right (impdo))));
843 ffebld incr = ffebld_head (ffebld_trail (ffebld_trail
844 (ffebld_trail (ffebld_right (impdo)))));
853 incr = ffebld_new_conter (ffebld_constant_new_integerdefault_val (1));
854 ffebld_set_info (incr, ffeinfo_new
855 (FFEINFO_basictypeINTEGER,
856 FFEINFO_kindtypeINTEGERDEFAULT,
859 FFEINFO_whereCONSTANT,
860 FFETARGET_charactersizeNONE));
863 /* Start the DO loop. */
865 start = ffeexpr_convert_expr (start, impdo_token, var, impdo_token,
867 end = ffeexpr_convert_expr (end, impdo_token, var, impdo_token,
869 incr = ffeexpr_convert_expr (incr, impdo_token, var, impdo_token,
872 ffeste_begin_iterdo_ (NULL, &tvar, &tincr, &titervar, var,
878 /* Handle the list of items. */
880 for (list = ffebld_left (impdo); list != NULL; list = ffebld_trail (list))
882 item = ffebld_head (list);
886 /* Strip parens off items such as in "READ *,(A)". This is really a bug
887 in the user's code, but I've been told lots of code does this. */
888 while (ffebld_op (item) == FFEBLD_opPAREN)
889 item = ffebld_left (item);
891 if (ffebld_op (item) == FFEBLD_opANY)
894 if (ffebld_op (item) == FFEBLD_opIMPDO)
895 ffeste_io_impdo_ (item, impdo_token);
898 ffeste_start_stmt_ ();
900 ffecom_prepare_arg_ptr_to_expr (item);
902 ffecom_prepare_end ();
904 ffeste_io_call_ ((*ffeste_io_driver_) (item), TRUE);
910 /* Generate end of implied-do construct. */
912 ffeste_end_iterdo_ (NULL, tvar, tincr, titervar);
916 /* I/O driver for formatted I/O item (do_fio)
918 Returns a tree for a CALL_EXPR to the do_fio function, which handles
919 a formatted I/O list item, along with the appropriate arguments for
920 the function. It is up to the caller to set the TREE_SIDE_EFFECTS flag
921 for the CALL_EXPR, expand (emit) the expression, emit any assignment
922 of the result to an IOSTAT= variable, and emit any checking of the
923 result for errors. */
925 #if FFECOM_targetCURRENT == FFECOM_targetGCC
927 ffeste_io_dofio_ (ffebld expr)
937 bt = ffeinfo_basictype (ffebld_info (expr));
938 kt = ffeinfo_kindtype (ffebld_info (expr));
940 if ((bt == FFEINFO_basictypeANY)
941 || (kt == FFEINFO_kindtypeANY))
942 return error_mark_node;
944 if (bt == FFEINFO_basictypeCOMPLEX)
947 bt = FFEINFO_basictypeREAL;
952 variable = ffecom_arg_ptr_to_expr (expr, &size);
954 if ((variable == error_mark_node)
955 || (size == error_mark_node))
956 return error_mark_node;
958 if (size == NULL_TREE) /* Already filled in for CHARACTER type. */
959 { /* "(ftnlen) sizeof(type)" */
960 size = size_binop (CEIL_DIV_EXPR,
961 TYPE_SIZE (ffecom_tree_type[bt][kt]),
962 size_int (TYPE_PRECISION (char_type_node)));
963 #if 0 /* Assume that while it is possible that char * is wider than
964 ftnlen, no object in Fortran space can get big enough for its
965 size to be wider than ftnlen. I really hope nobody wastes
966 time debugging a case where it can! */
967 assert (TYPE_PRECISION (ffecom_f2c_ftnlen_type_node)
968 >= TYPE_PRECISION (TREE_TYPE (size)));
970 size = convert (ffecom_f2c_ftnlen_type_node, size);
973 if (ffeinfo_rank (ffebld_info (expr)) == 0
974 || TREE_CODE (TREE_TYPE (TREE_TYPE (variable))) != ARRAY_TYPE)
976 = is_complex ? ffecom_f2c_ftnlen_two_node : ffecom_f2c_ftnlen_one_node;
979 num_elements = size_binop (CEIL_DIV_EXPR,
980 TYPE_SIZE (TREE_TYPE (TREE_TYPE (variable))),
982 num_elements = size_binop (CEIL_DIV_EXPR,
984 size_int (TYPE_PRECISION
986 num_elements = convert (ffecom_f2c_ftnlen_type_node,
991 = ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
994 variable = convert (string_type_node, variable);
996 arglist = build_tree_list (NULL_TREE, num_elements);
997 TREE_CHAIN (arglist) = build_tree_list (NULL_TREE, variable);
998 TREE_CHAIN (TREE_CHAIN (arglist)) = build_tree_list (NULL_TREE, size);
1000 return ffecom_call_gfrt (FFECOM_gfrtDOFIO, arglist, NULL_TREE);
1004 /* I/O driver for list-directed I/O item (do_lio)
1006 Returns a tree for a CALL_EXPR to the do_lio function, which handles
1007 a list-directed I/O list item, along with the appropriate arguments for
1008 the function. It is up to the caller to set the TREE_SIDE_EFFECTS flag
1009 for the CALL_EXPR, expand (emit) the expression, emit any assignment
1010 of the result to an IOSTAT= variable, and emit any checking of the
1011 result for errors. */
1013 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1015 ffeste_io_dolio_ (ffebld expr)
1022 ffeinfoBasictype bt;
1026 bt = ffeinfo_basictype (ffebld_info (expr));
1027 kt = ffeinfo_kindtype (ffebld_info (expr));
1029 if ((bt == FFEINFO_basictypeANY)
1030 || (kt == FFEINFO_kindtypeANY))
1031 return error_mark_node;
1033 tc = ffecom_f2c_typecode (bt, kt);
1035 type_id = build_int_2 (tc, 0);
1038 = ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnint_type_node,
1039 convert (ffecom_f2c_ftnint_type_node,
1042 variable = ffecom_arg_ptr_to_expr (expr, &size);
1044 if ((type_id == error_mark_node)
1045 || (variable == error_mark_node)
1046 || (size == error_mark_node))
1047 return error_mark_node;
1049 if (size == NULL_TREE) /* Already filled in for CHARACTER type. */
1050 { /* "(ftnlen) sizeof(type)" */
1051 size = size_binop (CEIL_DIV_EXPR,
1052 TYPE_SIZE (ffecom_tree_type[bt][kt]),
1053 size_int (TYPE_PRECISION (char_type_node)));
1054 #if 0 /* Assume that while it is possible that char * is wider than
1055 ftnlen, no object in Fortran space can get big enough for its
1056 size to be wider than ftnlen. I really hope nobody wastes
1057 time debugging a case where it can! */
1058 assert (TYPE_PRECISION (ffecom_f2c_ftnlen_type_node)
1059 >= TYPE_PRECISION (TREE_TYPE (size)));
1061 size = convert (ffecom_f2c_ftnlen_type_node, size);
1064 if (ffeinfo_rank (ffebld_info (expr)) == 0
1065 || TREE_CODE (TREE_TYPE (TREE_TYPE (variable))) != ARRAY_TYPE)
1066 num_elements = ffecom_integer_one_node;
1069 num_elements = size_binop (CEIL_DIV_EXPR,
1070 TYPE_SIZE (TREE_TYPE (TREE_TYPE (variable))),
1072 num_elements = size_binop (CEIL_DIV_EXPR,
1074 size_int (TYPE_PRECISION
1076 num_elements = convert (ffecom_f2c_ftnlen_type_node,
1081 = ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
1084 variable = convert (string_type_node, variable);
1086 arglist = build_tree_list (NULL_TREE, type_id);
1087 TREE_CHAIN (arglist) = build_tree_list (NULL_TREE, num_elements);
1088 TREE_CHAIN (TREE_CHAIN (arglist)) = build_tree_list (NULL_TREE, variable);
1089 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist)))
1090 = build_tree_list (NULL_TREE, size);
1092 return ffecom_call_gfrt (FFECOM_gfrtDOLIO, arglist, NULL_TREE);
1096 /* I/O driver for unformatted I/O item (do_uio)
1098 Returns a tree for a CALL_EXPR to the do_uio function, which handles
1099 an unformatted I/O list item, along with the appropriate arguments for
1100 the function. It is up to the caller to set the TREE_SIDE_EFFECTS flag
1101 for the CALL_EXPR, expand (emit) the expression, emit any assignment
1102 of the result to an IOSTAT= variable, and emit any checking of the
1103 result for errors. */
1105 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1107 ffeste_io_douio_ (ffebld expr)
1113 ffeinfoBasictype bt;
1117 bt = ffeinfo_basictype (ffebld_info (expr));
1118 kt = ffeinfo_kindtype (ffebld_info (expr));
1120 if ((bt == FFEINFO_basictypeANY)
1121 || (kt == FFEINFO_kindtypeANY))
1122 return error_mark_node;
1124 if (bt == FFEINFO_basictypeCOMPLEX)
1127 bt = FFEINFO_basictypeREAL;
1132 variable = ffecom_arg_ptr_to_expr (expr, &size);
1134 if ((variable == error_mark_node)
1135 || (size == error_mark_node))
1136 return error_mark_node;
1138 if (size == NULL_TREE) /* Already filled in for CHARACTER type. */
1139 { /* "(ftnlen) sizeof(type)" */
1140 size = size_binop (CEIL_DIV_EXPR,
1141 TYPE_SIZE (ffecom_tree_type[bt][kt]),
1142 size_int (TYPE_PRECISION (char_type_node)));
1143 #if 0 /* Assume that while it is possible that char * is wider than
1144 ftnlen, no object in Fortran space can get big enough for its
1145 size to be wider than ftnlen. I really hope nobody wastes
1146 time debugging a case where it can! */
1147 assert (TYPE_PRECISION (ffecom_f2c_ftnlen_type_node)
1148 >= TYPE_PRECISION (TREE_TYPE (size)));
1150 size = convert (ffecom_f2c_ftnlen_type_node, size);
1153 if (ffeinfo_rank (ffebld_info (expr)) == 0
1154 || TREE_CODE (TREE_TYPE (TREE_TYPE (variable))) != ARRAY_TYPE)
1156 = is_complex ? ffecom_f2c_ftnlen_two_node : ffecom_f2c_ftnlen_one_node;
1159 num_elements = size_binop (CEIL_DIV_EXPR,
1160 TYPE_SIZE (TREE_TYPE (TREE_TYPE (variable))),
1162 num_elements = size_binop (CEIL_DIV_EXPR, num_elements,
1163 size_int (TYPE_PRECISION
1165 num_elements = convert (ffecom_f2c_ftnlen_type_node,
1170 = ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
1173 variable = convert (string_type_node, variable);
1175 arglist = build_tree_list (NULL_TREE, num_elements);
1176 TREE_CHAIN (arglist) = build_tree_list (NULL_TREE, variable);
1177 TREE_CHAIN (TREE_CHAIN (arglist)) = build_tree_list (NULL_TREE, size);
1179 return ffecom_call_gfrt (FFECOM_gfrtDOUIO, arglist, NULL_TREE);
1183 /* Make arglist with ptr to BACKSPACE/ENDFILE/REWIND control list.
1185 Returns a tree suitable as an argument list containing a pointer to
1186 a BACKSPACE/ENDFILE/REWIND control list. First, generates that control
1187 list, if necessary, along with any static and run-time initializations
1188 that are needed as specified by the arguments to this function.
1190 Must ensure that all expressions are prepared before being evaluated,
1191 for any whose evaluation might result in the generation of temporaries.
1193 Note that this means this function causes a transition, within the
1194 current block being code-generated via the back end, from the
1195 declaration of variables (temporaries) to the expanding of expressions,
1198 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1200 ffeste_io_ialist_ (bool have_err,
1205 static tree f2c_alist_struct = NULL_TREE;
1211 bool constantp = TRUE;
1212 static tree errfield, unitfield;
1213 tree errinit, unitinit;
1215 static int mynumber = 0;
1217 if (f2c_alist_struct == NULL_TREE)
1221 push_obstacks_nochange ();
1222 end_temporary_allocation ();
1224 ref = make_node (RECORD_TYPE);
1226 errfield = ffecom_decl_field (ref, NULL_TREE, "err",
1227 ffecom_f2c_flag_type_node);
1228 unitfield = ffecom_decl_field (ref, errfield, "unit",
1229 ffecom_f2c_ftnint_type_node);
1231 TYPE_FIELDS (ref) = errfield;
1234 resume_temporary_allocation ();
1237 f2c_alist_struct = ref;
1240 /* Try to do as much compile-time initialization of the structure
1241 as possible, to save run time. */
1243 ffeste_f2c_init_flag_ (have_err, errinit);
1247 case FFESTV_unitNONE:
1248 case FFESTV_unitASTERISK:
1249 unitinit = build_int_2 (unit_dflt, 0);
1253 case FFESTV_unitINTEXPR:
1254 unitexp = ffecom_const_expr (unit_expr);
1259 unitinit = ffecom_integer_zero_node;
1265 assert ("bad unit spec" == NULL);
1266 unitinit = ffecom_integer_zero_node;
1271 inits = build_tree_list ((field = TYPE_FIELDS (f2c_alist_struct)), errinit);
1273 ffeste_f2c_init_next_ (unitinit);
1275 inits = build (CONSTRUCTOR, f2c_alist_struct, NULL_TREE, inits);
1276 TREE_CONSTANT (inits) = constantp ? 1 : 0;
1277 TREE_STATIC (inits) = 1;
1279 yes = suspend_momentary ();
1281 t = build_decl (VAR_DECL,
1282 ffecom_get_invented_identifier ("__g77_alist_%d", NULL,
1285 TREE_STATIC (t) = 1;
1286 t = ffecom_start_decl (t, 1);
1287 ffecom_finish_decl (t, inits, 0);
1289 resume_momentary (yes);
1291 /* Prepare run-time expressions. */
1294 ffecom_prepare_expr (unit_expr);
1296 ffecom_prepare_end ();
1298 /* Now evaluate run-time expressions as needed. */
1302 unitexp = ffecom_expr (unit_expr);
1303 ffeste_f2c_compile_ (unitfield, unitexp);
1306 ttype = build_pointer_type (TREE_TYPE (t));
1307 t = ffecom_1 (ADDR_EXPR, ttype, t);
1309 t = build_tree_list (NULL_TREE, t);
1315 /* Make arglist with ptr to external-I/O control list.
1317 Returns a tree suitable as an argument list containing a pointer to
1318 an external-I/O control list. First, generates that control
1319 list, if necessary, along with any static and run-time initializations
1320 that are needed as specified by the arguments to this function.
1322 Must ensure that all expressions are prepared before being evaluated,
1323 for any whose evaluation might result in the generation of temporaries.
1325 Note that this means this function causes a transition, within the
1326 current block being code-generated via the back end, from the
1327 declaration of variables (temporaries) to the expanding of expressions,
1330 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1332 ffeste_io_cilist_ (bool have_err,
1337 ffestvFormat format,
1338 ffestpFile *format_spec,
1342 static tree f2c_cilist_struct = NULL_TREE;
1348 bool constantp = TRUE;
1349 static tree errfield, unitfield, endfield, formatfield, recfield;
1350 tree errinit, unitinit, endinit, formatinit, recinit;
1351 tree unitexp, formatexp, recexp;
1352 static int mynumber = 0;
1354 if (f2c_cilist_struct == NULL_TREE)
1358 push_obstacks_nochange ();
1359 end_temporary_allocation ();
1361 ref = make_node (RECORD_TYPE);
1363 errfield = ffecom_decl_field (ref, NULL_TREE, "err",
1364 ffecom_f2c_flag_type_node);
1365 unitfield = ffecom_decl_field (ref, errfield, "unit",
1366 ffecom_f2c_ftnint_type_node);
1367 endfield = ffecom_decl_field (ref, unitfield, "end",
1368 ffecom_f2c_flag_type_node);
1369 formatfield = ffecom_decl_field (ref, endfield, "format",
1371 recfield = ffecom_decl_field (ref, formatfield, "rec",
1372 ffecom_f2c_ftnint_type_node);
1374 TYPE_FIELDS (ref) = errfield;
1377 resume_temporary_allocation ();
1380 f2c_cilist_struct = ref;
1383 /* Try to do as much compile-time initialization of the structure
1384 as possible, to save run time. */
1386 ffeste_f2c_init_flag_ (have_err, errinit);
1390 case FFESTV_unitNONE:
1391 case FFESTV_unitASTERISK:
1392 unitinit = build_int_2 (unit_dflt, 0);
1396 case FFESTV_unitINTEXPR:
1397 unitexp = ffecom_const_expr (unit_expr);
1402 unitinit = ffecom_integer_zero_node;
1408 assert ("bad unit spec" == NULL);
1409 unitinit = ffecom_integer_zero_node;
1416 case FFESTV_formatNONE:
1417 formatinit = null_pointer_node;
1418 formatexp = formatinit;
1421 case FFESTV_formatLABEL:
1422 formatexp = error_mark_node;
1423 formatinit = ffecom_lookup_label (format_spec->u.label);
1424 if ((formatinit == NULL_TREE)
1425 || (TREE_CODE (formatinit) == ERROR_MARK))
1427 formatinit = ffecom_1 (ADDR_EXPR,
1428 build_pointer_type (void_type_node),
1430 TREE_CONSTANT (formatinit) = 1;
1433 case FFESTV_formatCHAREXPR:
1434 formatexp = ffecom_arg_ptr_to_const_expr (format_spec->u.expr, NULL);
1436 formatinit = formatexp;
1439 formatinit = null_pointer_node;
1444 case FFESTV_formatASTERISK:
1445 formatinit = null_pointer_node;
1446 formatexp = formatinit;
1449 case FFESTV_formatINTEXPR:
1450 formatinit = null_pointer_node;
1451 formatexp = ffecom_expr_assign (format_spec->u.expr);
1452 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (formatexp)))
1453 < GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
1454 error ("ASSIGNed FORMAT specifier is too small");
1455 formatexp = convert (string_type_node, formatexp);
1458 case FFESTV_formatNAMELIST:
1459 formatinit = ffecom_expr (format_spec->u.expr);
1460 formatexp = formatinit;
1464 assert ("bad format spec" == NULL);
1465 formatinit = integer_zero_node;
1466 formatexp = formatinit;
1470 ffeste_f2c_init_flag_ (have_end, endinit);
1473 recexp = ffecom_const_expr (rec_expr);
1475 recexp = ffecom_integer_zero_node;
1480 recinit = ffecom_integer_zero_node;
1484 inits = build_tree_list ((field = TYPE_FIELDS (f2c_cilist_struct)), errinit);
1486 ffeste_f2c_init_next_ (unitinit);
1487 ffeste_f2c_init_next_ (endinit);
1488 ffeste_f2c_init_next_ (formatinit);
1489 ffeste_f2c_init_next_ (recinit);
1491 inits = build (CONSTRUCTOR, f2c_cilist_struct, NULL_TREE, inits);
1492 TREE_CONSTANT (inits) = constantp ? 1 : 0;
1493 TREE_STATIC (inits) = 1;
1495 yes = suspend_momentary ();
1497 t = build_decl (VAR_DECL,
1498 ffecom_get_invented_identifier ("__g77_cilist_%d", NULL,
1501 TREE_STATIC (t) = 1;
1502 t = ffecom_start_decl (t, 1);
1503 ffecom_finish_decl (t, inits, 0);
1505 resume_momentary (yes);
1507 /* Prepare run-time expressions. */
1510 ffecom_prepare_expr (unit_expr);
1513 ffecom_prepare_arg_ptr_to_expr (format_spec->u.expr);
1516 ffecom_prepare_expr (rec_expr);
1518 ffecom_prepare_end ();
1520 /* Now evaluate run-time expressions as needed. */
1524 unitexp = ffecom_expr (unit_expr);
1525 ffeste_f2c_compile_ (unitfield, unitexp);
1530 formatexp = ffecom_arg_ptr_to_expr (format_spec->u.expr, NULL);
1531 ffeste_f2c_compile_ (formatfield, formatexp);
1533 else if (format == FFESTV_formatINTEXPR)
1534 ffeste_f2c_compile_ (formatfield, formatexp);
1538 recexp = ffecom_expr (rec_expr);
1539 ffeste_f2c_compile_ (recfield, recexp);
1542 ttype = build_pointer_type (TREE_TYPE (t));
1543 t = ffecom_1 (ADDR_EXPR, ttype, t);
1545 t = build_tree_list (NULL_TREE, t);
1551 /* Make arglist with ptr to CLOSE control list.
1553 Returns a tree suitable as an argument list containing a pointer to
1554 a CLOSE-statement control list. First, generates that control
1555 list, if necessary, along with any static and run-time initializations
1556 that are needed as specified by the arguments to this function.
1558 Must ensure that all expressions are prepared before being evaluated,
1559 for any whose evaluation might result in the generation of temporaries.
1561 Note that this means this function causes a transition, within the
1562 current block being code-generated via the back end, from the
1563 declaration of variables (temporaries) to the expanding of expressions,
1566 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1568 ffeste_io_cllist_ (bool have_err,
1570 ffestpFile *stat_spec)
1572 static tree f2c_close_struct = NULL_TREE;
1578 tree ignore; /* Ignore length info for certain fields. */
1579 bool constantp = TRUE;
1580 static tree errfield, unitfield, statfield;
1581 tree errinit, unitinit, statinit;
1582 tree unitexp, statexp;
1583 static int mynumber = 0;
1585 if (f2c_close_struct == NULL_TREE)
1589 push_obstacks_nochange ();
1590 end_temporary_allocation ();
1592 ref = make_node (RECORD_TYPE);
1594 errfield = ffecom_decl_field (ref, NULL_TREE, "err",
1595 ffecom_f2c_flag_type_node);
1596 unitfield = ffecom_decl_field (ref, errfield, "unit",
1597 ffecom_f2c_ftnint_type_node);
1598 statfield = ffecom_decl_field (ref, unitfield, "stat",
1601 TYPE_FIELDS (ref) = errfield;
1604 resume_temporary_allocation ();
1607 f2c_close_struct = ref;
1610 /* Try to do as much compile-time initialization of the structure
1611 as possible, to save run time. */
1613 ffeste_f2c_init_flag_ (have_err, errinit);
1615 unitexp = ffecom_const_expr (unit_expr);
1620 unitinit = ffecom_integer_zero_node;
1624 ffeste_f2c_init_charnolen_ (statexp, statinit, stat_spec);
1626 inits = build_tree_list ((field = TYPE_FIELDS (f2c_close_struct)), errinit);
1628 ffeste_f2c_init_next_ (unitinit);
1629 ffeste_f2c_init_next_ (statinit);
1631 inits = build (CONSTRUCTOR, f2c_close_struct, NULL_TREE, inits);
1632 TREE_CONSTANT (inits) = constantp ? 1 : 0;
1633 TREE_STATIC (inits) = 1;
1635 yes = suspend_momentary ();
1637 t = build_decl (VAR_DECL,
1638 ffecom_get_invented_identifier ("__g77_cllist_%d", NULL,
1641 TREE_STATIC (t) = 1;
1642 t = ffecom_start_decl (t, 1);
1643 ffecom_finish_decl (t, inits, 0);
1645 resume_momentary (yes);
1647 /* Prepare run-time expressions. */
1650 ffecom_prepare_expr (unit_expr);
1653 ffecom_prepare_arg_ptr_to_expr (stat_spec->u.expr);
1655 ffecom_prepare_end ();
1657 /* Now evaluate run-time expressions as needed. */
1661 unitexp = ffecom_expr (unit_expr);
1662 ffeste_f2c_compile_ (unitfield, unitexp);
1665 ffeste_f2c_compile_charnolen_ (statfield, stat_spec, statexp);
1667 ttype = build_pointer_type (TREE_TYPE (t));
1668 t = ffecom_1 (ADDR_EXPR, ttype, t);
1670 t = build_tree_list (NULL_TREE, t);
1676 /* Make arglist with ptr to internal-I/O control list.
1678 Returns a tree suitable as an argument list containing a pointer to
1679 an internal-I/O control list. First, generates that control
1680 list, if necessary, along with any static and run-time initializations
1681 that are needed as specified by the arguments to this function.
1683 Must ensure that all expressions are prepared before being evaluated,
1684 for any whose evaluation might result in the generation of temporaries.
1686 Note that this means this function causes a transition, within the
1687 current block being code-generated via the back end, from the
1688 declaration of variables (temporaries) to the expanding of expressions,
1691 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1693 ffeste_io_icilist_ (bool have_err,
1696 ffestvFormat format,
1697 ffestpFile *format_spec)
1699 static tree f2c_icilist_struct = NULL_TREE;
1705 bool constantp = TRUE;
1706 static tree errfield, unitfield, endfield, formatfield, unitlenfield,
1708 tree errinit, unitinit, endinit, formatinit, unitleninit, unitnuminit;
1709 tree unitexp, formatexp, unitlenexp, unitnumexp;
1710 static int mynumber = 0;
1712 if (f2c_icilist_struct == NULL_TREE)
1716 push_obstacks_nochange ();
1717 end_temporary_allocation ();
1719 ref = make_node (RECORD_TYPE);
1721 errfield = ffecom_decl_field (ref, NULL_TREE, "err",
1722 ffecom_f2c_flag_type_node);
1723 unitfield = ffecom_decl_field (ref, errfield, "unit",
1725 endfield = ffecom_decl_field (ref, unitfield, "end",
1726 ffecom_f2c_flag_type_node);
1727 formatfield = ffecom_decl_field (ref, endfield, "format",
1729 unitlenfield = ffecom_decl_field (ref, formatfield, "unitlen",
1730 ffecom_f2c_ftnint_type_node);
1731 unitnumfield = ffecom_decl_field (ref, unitlenfield, "unitnum",
1732 ffecom_f2c_ftnint_type_node);
1734 TYPE_FIELDS (ref) = errfield;
1737 resume_temporary_allocation ();
1740 f2c_icilist_struct = ref;
1743 /* Try to do as much compile-time initialization of the structure
1744 as possible, to save run time. */
1746 ffeste_f2c_init_flag_ (have_err, errinit);
1748 unitexp = ffecom_arg_ptr_to_const_expr (unit_expr, &unitlenexp);
1753 unitinit = null_pointer_node;
1757 unitleninit = unitlenexp;
1760 unitleninit = ffecom_integer_zero_node;
1764 /* Now see if we can fully initialize the number of elements, or
1765 if we have to compute that at run time. */
1766 if (ffeinfo_rank (ffebld_info (unit_expr)) == 0
1768 && TREE_CODE (TREE_TYPE (TREE_TYPE (unitexp))) != ARRAY_TYPE))
1770 /* Not an array, so just one element. */
1771 unitnuminit = ffecom_integer_one_node;
1772 unitnumexp = unitnuminit;
1774 else if (unitexp && unitlenexp)
1776 /* An array, but all the info is constant, so compute now. */
1777 unitnuminit = size_binop (CEIL_DIV_EXPR,
1778 TYPE_SIZE (TREE_TYPE (TREE_TYPE (unitexp))),
1780 unitnuminit = size_binop (CEIL_DIV_EXPR,
1782 size_int (TYPE_PRECISION
1784 unitnumexp = unitnuminit;
1788 /* Put off computing until run time. */
1789 unitnuminit = ffecom_integer_zero_node;
1790 unitnumexp = NULL_TREE;
1796 case FFESTV_formatNONE:
1797 formatinit = null_pointer_node;
1798 formatexp = formatinit;
1801 case FFESTV_formatLABEL:
1802 formatexp = error_mark_node;
1803 formatinit = ffecom_lookup_label (format_spec->u.label);
1804 if ((formatinit == NULL_TREE)
1805 || (TREE_CODE (formatinit) == ERROR_MARK))
1807 formatinit = ffecom_1 (ADDR_EXPR,
1808 build_pointer_type (void_type_node),
1810 TREE_CONSTANT (formatinit) = 1;
1813 case FFESTV_formatCHAREXPR:
1814 ffeste_f2c_init_format_ (formatexp, formatinit, format_spec);
1817 case FFESTV_formatASTERISK:
1818 formatinit = null_pointer_node;
1819 formatexp = formatinit;
1822 case FFESTV_formatINTEXPR:
1823 formatinit = null_pointer_node;
1824 formatexp = ffecom_expr_assign (format_spec->u.expr);
1825 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (formatexp)))
1826 < GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
1827 error ("ASSIGNed FORMAT specifier is too small");
1828 formatexp = convert (string_type_node, formatexp);
1832 assert ("bad format spec" == NULL);
1833 formatinit = ffecom_integer_zero_node;
1834 formatexp = formatinit;
1838 ffeste_f2c_init_flag_ (have_end, endinit);
1840 inits = build_tree_list ((field = TYPE_FIELDS (f2c_icilist_struct)),
1843 ffeste_f2c_init_next_ (unitinit);
1844 ffeste_f2c_init_next_ (endinit);
1845 ffeste_f2c_init_next_ (formatinit);
1846 ffeste_f2c_init_next_ (unitleninit);
1847 ffeste_f2c_init_next_ (unitnuminit);
1849 inits = build (CONSTRUCTOR, f2c_icilist_struct, NULL_TREE, inits);
1850 TREE_CONSTANT (inits) = constantp ? 1 : 0;
1851 TREE_STATIC (inits) = 1;
1853 yes = suspend_momentary ();
1855 t = build_decl (VAR_DECL,
1856 ffecom_get_invented_identifier ("__g77_icilist_%d", NULL,
1858 f2c_icilist_struct);
1859 TREE_STATIC (t) = 1;
1860 t = ffecom_start_decl (t, 1);
1861 ffecom_finish_decl (t, inits, 0);
1863 resume_momentary (yes);
1865 /* Prepare run-time expressions. */
1868 ffecom_prepare_arg_ptr_to_expr (unit_expr);
1870 ffeste_f2c_prepare_format_ (format_spec, formatexp);
1872 ffecom_prepare_end ();
1874 /* Now evaluate run-time expressions as needed. */
1876 if (! unitexp || ! unitlenexp)
1878 int need_unitexp = (! unitexp);
1879 int need_unitlenexp = (! unitlenexp);
1881 unitexp = ffecom_arg_ptr_to_expr (unit_expr, &unitlenexp);
1883 ffeste_f2c_compile_ (unitfield, unitexp);
1884 if (need_unitlenexp)
1885 ffeste_f2c_compile_ (unitlenfield, unitlenexp);
1889 && unitexp != error_mark_node
1890 && unitlenexp != error_mark_node)
1892 unitnumexp = size_binop (CEIL_DIV_EXPR,
1893 TYPE_SIZE (TREE_TYPE (TREE_TYPE (unitexp))),
1895 unitnumexp = size_binop (CEIL_DIV_EXPR,
1897 size_int (TYPE_PRECISION
1899 ffeste_f2c_compile_ (unitnumfield, unitnumexp);
1902 if (format == FFESTV_formatINTEXPR)
1903 ffeste_f2c_compile_ (formatfield, formatexp);
1905 ffeste_f2c_compile_format_ (formatfield, format_spec, formatexp);
1907 ttype = build_pointer_type (TREE_TYPE (t));
1908 t = ffecom_1 (ADDR_EXPR, ttype, t);
1910 t = build_tree_list (NULL_TREE, t);
1916 /* Make arglist with ptr to INQUIRE control list
1918 Returns a tree suitable as an argument list containing a pointer to
1919 an INQUIRE-statement control list. First, generates that control
1920 list, if necessary, along with any static and run-time initializations
1921 that are needed as specified by the arguments to this function.
1923 Must ensure that all expressions are prepared before being evaluated,
1924 for any whose evaluation might result in the generation of temporaries.
1926 Note that this means this function causes a transition, within the
1927 current block being code-generated via the back end, from the
1928 declaration of variables (temporaries) to the expanding of expressions,
1931 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1933 ffeste_io_inlist_ (bool have_err,
1934 ffestpFile *unit_spec,
1935 ffestpFile *file_spec,
1936 ffestpFile *exist_spec,
1937 ffestpFile *open_spec,
1938 ffestpFile *number_spec,
1939 ffestpFile *named_spec,
1940 ffestpFile *name_spec,
1941 ffestpFile *access_spec,
1942 ffestpFile *sequential_spec,
1943 ffestpFile *direct_spec,
1944 ffestpFile *form_spec,
1945 ffestpFile *formatted_spec,
1946 ffestpFile *unformatted_spec,
1947 ffestpFile *recl_spec,
1948 ffestpFile *nextrec_spec,
1949 ffestpFile *blank_spec)
1951 static tree f2c_inquire_struct = NULL_TREE;
1957 bool constantp = TRUE;
1958 static tree errfield, unitfield, filefield, filelenfield, existfield,
1959 openfield, numberfield, namedfield, namefield, namelenfield, accessfield,
1960 accesslenfield, sequentialfield, sequentiallenfield, directfield, directlenfield,
1961 formfield, formlenfield, formattedfield, formattedlenfield, unformattedfield,
1962 unformattedlenfield, reclfield, nextrecfield, blankfield, blanklenfield;
1963 tree errinit, unitinit, fileinit, fileleninit, existinit, openinit, numberinit,
1964 namedinit, nameinit, nameleninit, accessinit, accessleninit, sequentialinit,
1965 sequentialleninit, directinit, directleninit, forminit, formleninit,
1966 formattedinit, formattedleninit, unformattedinit, unformattedleninit,
1967 reclinit, nextrecinit, blankinit, blankleninit;
1969 unitexp, fileexp, filelenexp, existexp, openexp, numberexp, namedexp,
1970 nameexp, namelenexp, accessexp, accesslenexp, sequentialexp, sequentiallenexp,
1971 directexp, directlenexp, formexp, formlenexp, formattedexp, formattedlenexp,
1972 unformattedexp, unformattedlenexp, reclexp, nextrecexp, blankexp, blanklenexp;
1973 static int mynumber = 0;
1975 if (f2c_inquire_struct == NULL_TREE)
1979 push_obstacks_nochange ();
1980 end_temporary_allocation ();
1982 ref = make_node (RECORD_TYPE);
1984 errfield = ffecom_decl_field (ref, NULL_TREE, "err",
1985 ffecom_f2c_flag_type_node);
1986 unitfield = ffecom_decl_field (ref, errfield, "unit",
1987 ffecom_f2c_ftnint_type_node);
1988 filefield = ffecom_decl_field (ref, unitfield, "file",
1990 filelenfield = ffecom_decl_field (ref, filefield, "filelen",
1991 ffecom_f2c_ftnlen_type_node);
1992 existfield = ffecom_decl_field (ref, filelenfield, "exist",
1993 ffecom_f2c_ptr_to_ftnint_type_node);
1994 openfield = ffecom_decl_field (ref, existfield, "open",
1995 ffecom_f2c_ptr_to_ftnint_type_node);
1996 numberfield = ffecom_decl_field (ref, openfield, "number",
1997 ffecom_f2c_ptr_to_ftnint_type_node);
1998 namedfield = ffecom_decl_field (ref, numberfield, "named",
1999 ffecom_f2c_ptr_to_ftnint_type_node);
2000 namefield = ffecom_decl_field (ref, namedfield, "name",
2002 namelenfield = ffecom_decl_field (ref, namefield, "namelen",
2003 ffecom_f2c_ftnlen_type_node);
2004 accessfield = ffecom_decl_field (ref, namelenfield, "access",
2006 accesslenfield = ffecom_decl_field (ref, accessfield, "accesslen",
2007 ffecom_f2c_ftnlen_type_node);
2008 sequentialfield = ffecom_decl_field (ref, accesslenfield, "sequential",
2010 sequentiallenfield = ffecom_decl_field (ref, sequentialfield,
2012 ffecom_f2c_ftnlen_type_node);
2013 directfield = ffecom_decl_field (ref, sequentiallenfield, "direct",
2015 directlenfield = ffecom_decl_field (ref, directfield, "directlen",
2016 ffecom_f2c_ftnlen_type_node);
2017 formfield = ffecom_decl_field (ref, directlenfield, "form",
2019 formlenfield = ffecom_decl_field (ref, formfield, "formlen",
2020 ffecom_f2c_ftnlen_type_node);
2021 formattedfield = ffecom_decl_field (ref, formlenfield, "formatted",
2023 formattedlenfield = ffecom_decl_field (ref, formattedfield,
2025 ffecom_f2c_ftnlen_type_node);
2026 unformattedfield = ffecom_decl_field (ref, formattedlenfield,
2029 unformattedlenfield = ffecom_decl_field (ref, unformattedfield,
2031 ffecom_f2c_ftnlen_type_node);
2032 reclfield = ffecom_decl_field (ref, unformattedlenfield, "recl",
2033 ffecom_f2c_ptr_to_ftnint_type_node);
2034 nextrecfield = ffecom_decl_field (ref, reclfield, "nextrec",
2035 ffecom_f2c_ptr_to_ftnint_type_node);
2036 blankfield = ffecom_decl_field (ref, nextrecfield, "blank",
2038 blanklenfield = ffecom_decl_field (ref, blankfield, "blanklen",
2039 ffecom_f2c_ftnlen_type_node);
2041 TYPE_FIELDS (ref) = errfield;
2044 resume_temporary_allocation ();
2047 f2c_inquire_struct = ref;
2050 /* Try to do as much compile-time initialization of the structure
2051 as possible, to save run time. */
2053 ffeste_f2c_init_flag_ (have_err, errinit);
2054 ffeste_f2c_init_int_ (unitexp, unitinit, unit_spec);
2055 ffeste_f2c_init_char_ (fileexp, fileinit, filelenexp, fileleninit,
2057 ffeste_f2c_init_ptrtoint_ (existexp, existinit, exist_spec);
2058 ffeste_f2c_init_ptrtoint_ (openexp, openinit, open_spec);
2059 ffeste_f2c_init_ptrtoint_ (numberexp, numberinit, number_spec);
2060 ffeste_f2c_init_ptrtoint_ (namedexp, namedinit, named_spec);
2061 ffeste_f2c_init_char_ (nameexp, nameinit, namelenexp, nameleninit,
2063 ffeste_f2c_init_char_ (accessexp, accessinit, accesslenexp,
2064 accessleninit, access_spec);
2065 ffeste_f2c_init_char_ (sequentialexp, sequentialinit, sequentiallenexp,
2066 sequentialleninit, sequential_spec);
2067 ffeste_f2c_init_char_ (directexp, directinit, directlenexp,
2068 directleninit, direct_spec);
2069 ffeste_f2c_init_char_ (formexp, forminit, formlenexp, formleninit,
2071 ffeste_f2c_init_char_ (formattedexp, formattedinit,
2072 formattedlenexp, formattedleninit, formatted_spec);
2073 ffeste_f2c_init_char_ (unformattedexp, unformattedinit, unformattedlenexp,
2074 unformattedleninit, unformatted_spec);
2075 ffeste_f2c_init_ptrtoint_ (reclexp, reclinit, recl_spec);
2076 ffeste_f2c_init_ptrtoint_ (nextrecexp, nextrecinit, nextrec_spec);
2077 ffeste_f2c_init_char_ (blankexp, blankinit, blanklenexp,
2078 blankleninit, blank_spec);
2080 inits = build_tree_list ((field = TYPE_FIELDS (f2c_inquire_struct)),
2083 ffeste_f2c_init_next_ (unitinit);
2084 ffeste_f2c_init_next_ (fileinit);
2085 ffeste_f2c_init_next_ (fileleninit);
2086 ffeste_f2c_init_next_ (existinit);
2087 ffeste_f2c_init_next_ (openinit);
2088 ffeste_f2c_init_next_ (numberinit);
2089 ffeste_f2c_init_next_ (namedinit);
2090 ffeste_f2c_init_next_ (nameinit);
2091 ffeste_f2c_init_next_ (nameleninit);
2092 ffeste_f2c_init_next_ (accessinit);
2093 ffeste_f2c_init_next_ (accessleninit);
2094 ffeste_f2c_init_next_ (sequentialinit);
2095 ffeste_f2c_init_next_ (sequentialleninit);
2096 ffeste_f2c_init_next_ (directinit);
2097 ffeste_f2c_init_next_ (directleninit);
2098 ffeste_f2c_init_next_ (forminit);
2099 ffeste_f2c_init_next_ (formleninit);
2100 ffeste_f2c_init_next_ (formattedinit);
2101 ffeste_f2c_init_next_ (formattedleninit);
2102 ffeste_f2c_init_next_ (unformattedinit);
2103 ffeste_f2c_init_next_ (unformattedleninit);
2104 ffeste_f2c_init_next_ (reclinit);
2105 ffeste_f2c_init_next_ (nextrecinit);
2106 ffeste_f2c_init_next_ (blankinit);
2107 ffeste_f2c_init_next_ (blankleninit);
2109 inits = build (CONSTRUCTOR, f2c_inquire_struct, NULL_TREE, inits);
2110 TREE_CONSTANT (inits) = constantp ? 1 : 0;
2111 TREE_STATIC (inits) = 1;
2113 yes = suspend_momentary ();
2115 t = build_decl (VAR_DECL,
2116 ffecom_get_invented_identifier ("__g77_inlist_%d", NULL,
2118 f2c_inquire_struct);
2119 TREE_STATIC (t) = 1;
2120 t = ffecom_start_decl (t, 1);
2121 ffecom_finish_decl (t, inits, 0);
2123 resume_momentary (yes);
2125 /* Prepare run-time expressions. */
2127 ffeste_f2c_prepare_int_ (unit_spec, unitexp);
2128 ffeste_f2c_prepare_char_ (file_spec, fileexp);
2129 ffeste_f2c_prepare_ptrtoint_ (exist_spec, existexp);
2130 ffeste_f2c_prepare_ptrtoint_ (open_spec, openexp);
2131 ffeste_f2c_prepare_ptrtoint_ (number_spec, numberexp);
2132 ffeste_f2c_prepare_ptrtoint_ (named_spec, namedexp);
2133 ffeste_f2c_prepare_char_ (name_spec, nameexp);
2134 ffeste_f2c_prepare_char_ (access_spec, accessexp);
2135 ffeste_f2c_prepare_char_ (sequential_spec, sequentialexp);
2136 ffeste_f2c_prepare_char_ (direct_spec, directexp);
2137 ffeste_f2c_prepare_char_ (form_spec, formexp);
2138 ffeste_f2c_prepare_char_ (formatted_spec, formattedexp);
2139 ffeste_f2c_prepare_char_ (unformatted_spec, unformattedexp);
2140 ffeste_f2c_prepare_ptrtoint_ (recl_spec, reclexp);
2141 ffeste_f2c_prepare_ptrtoint_ (nextrec_spec, nextrecexp);
2142 ffeste_f2c_prepare_char_ (blank_spec, blankexp);
2144 ffecom_prepare_end ();
2146 /* Now evaluate run-time expressions as needed. */
2148 ffeste_f2c_compile_int_ (unitfield, unit_spec, unitexp);
2149 ffeste_f2c_compile_char_ (filefield, filelenfield, file_spec,
2150 fileexp, filelenexp);
2151 ffeste_f2c_compile_ptrtoint_ (existfield, exist_spec, existexp);
2152 ffeste_f2c_compile_ptrtoint_ (openfield, open_spec, openexp);
2153 ffeste_f2c_compile_ptrtoint_ (numberfield, number_spec, numberexp);
2154 ffeste_f2c_compile_ptrtoint_ (namedfield, named_spec, namedexp);
2155 ffeste_f2c_compile_char_ (namefield, namelenfield, name_spec, nameexp,
2157 ffeste_f2c_compile_char_ (accessfield, accesslenfield, access_spec,
2158 accessexp, accesslenexp);
2159 ffeste_f2c_compile_char_ (sequentialfield, sequentiallenfield,
2160 sequential_spec, sequentialexp,
2162 ffeste_f2c_compile_char_ (directfield, directlenfield, direct_spec,
2163 directexp, directlenexp);
2164 ffeste_f2c_compile_char_ (formfield, formlenfield, form_spec, formexp,
2166 ffeste_f2c_compile_char_ (formattedfield, formattedlenfield, formatted_spec,
2167 formattedexp, formattedlenexp);
2168 ffeste_f2c_compile_char_ (unformattedfield, unformattedlenfield,
2169 unformatted_spec, unformattedexp,
2171 ffeste_f2c_compile_ptrtoint_ (reclfield, recl_spec, reclexp);
2172 ffeste_f2c_compile_ptrtoint_ (nextrecfield, nextrec_spec, nextrecexp);
2173 ffeste_f2c_compile_char_ (blankfield, blanklenfield, blank_spec, blankexp,
2176 ttype = build_pointer_type (TREE_TYPE (t));
2177 t = ffecom_1 (ADDR_EXPR, ttype, t);
2179 t = build_tree_list (NULL_TREE, t);
2185 /* Make arglist with ptr to OPEN control list
2187 Returns a tree suitable as an argument list containing a pointer to
2188 an OPEN-statement control list. First, generates that control
2189 list, if necessary, along with any static and run-time initializations
2190 that are needed as specified by the arguments to this function.
2192 Must ensure that all expressions are prepared before being evaluated,
2193 for any whose evaluation might result in the generation of temporaries.
2195 Note that this means this function causes a transition, within the
2196 current block being code-generated via the back end, from the
2197 declaration of variables (temporaries) to the expanding of expressions,
2200 #if FFECOM_targetCURRENT == FFECOM_targetGCC
2202 ffeste_io_olist_ (bool have_err,
2204 ffestpFile *file_spec,
2205 ffestpFile *stat_spec,
2206 ffestpFile *access_spec,
2207 ffestpFile *form_spec,
2208 ffestpFile *recl_spec,
2209 ffestpFile *blank_spec)
2211 static tree f2c_open_struct = NULL_TREE;
2217 tree ignore; /* Ignore length info for certain fields. */
2218 bool constantp = TRUE;
2219 static tree errfield, unitfield, filefield, filelenfield, statfield,
2220 accessfield, formfield, reclfield, blankfield;
2221 tree errinit, unitinit, fileinit, fileleninit, statinit, accessinit,
2222 forminit, reclinit, blankinit;
2224 unitexp, fileexp, filelenexp, statexp, accessexp, formexp, reclexp,
2226 static int mynumber = 0;
2228 if (f2c_open_struct == NULL_TREE)
2232 push_obstacks_nochange ();
2233 end_temporary_allocation ();
2235 ref = make_node (RECORD_TYPE);
2237 errfield = ffecom_decl_field (ref, NULL_TREE, "err",
2238 ffecom_f2c_flag_type_node);
2239 unitfield = ffecom_decl_field (ref, errfield, "unit",
2240 ffecom_f2c_ftnint_type_node);
2241 filefield = ffecom_decl_field (ref, unitfield, "file",
2243 filelenfield = ffecom_decl_field (ref, filefield, "filelen",
2244 ffecom_f2c_ftnlen_type_node);
2245 statfield = ffecom_decl_field (ref, filelenfield, "stat",
2247 accessfield = ffecom_decl_field (ref, statfield, "access",
2249 formfield = ffecom_decl_field (ref, accessfield, "form",
2251 reclfield = ffecom_decl_field (ref, formfield, "recl",
2252 ffecom_f2c_ftnint_type_node);
2253 blankfield = ffecom_decl_field (ref, reclfield, "blank",
2256 TYPE_FIELDS (ref) = errfield;
2259 resume_temporary_allocation ();
2262 f2c_open_struct = ref;
2265 /* Try to do as much compile-time initialization of the structure
2266 as possible, to save run time. */
2268 ffeste_f2c_init_flag_ (have_err, errinit);
2270 unitexp = ffecom_const_expr (unit_expr);
2275 unitinit = ffecom_integer_zero_node;
2279 ffeste_f2c_init_char_ (fileexp, fileinit, filelenexp, fileleninit,
2281 ffeste_f2c_init_charnolen_ (statexp, statinit, stat_spec);
2282 ffeste_f2c_init_charnolen_ (accessexp, accessinit, access_spec);
2283 ffeste_f2c_init_charnolen_ (formexp, forminit, form_spec);
2284 ffeste_f2c_init_int_ (reclexp, reclinit, recl_spec);
2285 ffeste_f2c_init_charnolen_ (blankexp, blankinit, blank_spec);
2287 inits = build_tree_list ((field = TYPE_FIELDS (f2c_open_struct)), errinit);
2289 ffeste_f2c_init_next_ (unitinit);
2290 ffeste_f2c_init_next_ (fileinit);
2291 ffeste_f2c_init_next_ (fileleninit);
2292 ffeste_f2c_init_next_ (statinit);
2293 ffeste_f2c_init_next_ (accessinit);
2294 ffeste_f2c_init_next_ (forminit);
2295 ffeste_f2c_init_next_ (reclinit);
2296 ffeste_f2c_init_next_ (blankinit);
2298 inits = build (CONSTRUCTOR, f2c_open_struct, NULL_TREE, inits);
2299 TREE_CONSTANT (inits) = constantp ? 1 : 0;
2300 TREE_STATIC (inits) = 1;
2302 yes = suspend_momentary ();
2304 t = build_decl (VAR_DECL,
2305 ffecom_get_invented_identifier ("__g77_olist_%d", NULL,
2308 TREE_STATIC (t) = 1;
2309 t = ffecom_start_decl (t, 1);
2310 ffecom_finish_decl (t, inits, 0);
2312 resume_momentary (yes);
2314 /* Prepare run-time expressions. */
2317 ffecom_prepare_expr (unit_expr);
2319 ffeste_f2c_prepare_char_ (file_spec, fileexp);
2320 ffeste_f2c_prepare_charnolen_ (stat_spec, statexp);
2321 ffeste_f2c_prepare_charnolen_ (access_spec, accessexp);
2322 ffeste_f2c_prepare_charnolen_ (form_spec, formexp);
2323 ffeste_f2c_prepare_int_ (recl_spec, reclexp);
2324 ffeste_f2c_prepare_charnolen_ (blank_spec, blankexp);
2326 ffecom_prepare_end ();
2328 /* Now evaluate run-time expressions as needed. */
2332 unitexp = ffecom_expr (unit_expr);
2333 ffeste_f2c_compile_ (unitfield, unitexp);
2336 ffeste_f2c_compile_char_ (filefield, filelenfield, file_spec, fileexp,
2338 ffeste_f2c_compile_charnolen_ (statfield, stat_spec, statexp);
2339 ffeste_f2c_compile_charnolen_ (accessfield, access_spec, accessexp);
2340 ffeste_f2c_compile_charnolen_ (formfield, form_spec, formexp);
2341 ffeste_f2c_compile_int_ (reclfield, recl_spec, reclexp);
2342 ffeste_f2c_compile_charnolen_ (blankfield, blank_spec, blankexp);
2344 ttype = build_pointer_type (TREE_TYPE (t));
2345 t = ffecom_1 (ADDR_EXPR, ttype, t);
2347 t = build_tree_list (NULL_TREE, t);
2353 /* Display file-statement specifier. */
2355 #if FFECOM_targetCURRENT == FFECOM_targetFFE
2357 ffeste_subr_file_ (const char *kw, ffestpFile *spec)
2359 if (!spec->kw_or_val_present)
2362 if (spec->value_present)
2364 fputc ('=', dmpout);
2365 if (spec->value_is_label)
2367 assert (spec->value_is_label == 2); /* Temporary checking only. */
2368 fprintf (dmpout, "%" ffelabValue_f "u",
2369 ffelab_value (spec->u.label));
2372 ffebld_dump (spec->u.expr);
2374 fputc (',', dmpout);
2378 /* Generate code for BACKSPACE/ENDFILE/REWIND. */
2380 #if FFECOM_targetCURRENT == FFECOM_targetGCC
2382 ffeste_subr_beru_ (ffestpBeruStmt *info, ffecomGfrt rt)
2388 ffeste_emit_line_note_ ();
2390 #define specified(something) (info->beru_spec[something].kw_or_val_present)
2392 iostat = specified (FFESTP_beruixIOSTAT);
2393 errl = specified (FFESTP_beruixERR);
2397 /* ~~For now, we assume the unit number is specified and is not ASTERISK,
2398 because the FFE doesn't support BACKSPACE(*) and rejects a BACKSPACE
2399 without any unit specifier. f2c, however, supports the former
2400 construct. When it is time to add this feature to the FFE, which
2401 probably is fairly easy, ffestc_R919 and company will want to pass an
2402 ffestvUnit indicator of FFESTV_unitINTEXPR or _unitASTERISK to
2403 ffeste_R919 and company, and they will want to pass that same value to
2404 this function, and that argument will replace the constant _unitINTEXPR_
2405 in the call below. Right now, the default unit number, 6, is ignored. */
2407 ffeste_start_stmt_ ();
2411 /* Have ERR= specification. */
2415 = ffecom_lookup_label
2416 (info->beru_spec[FFESTP_beruixERR].u.label);
2417 ffeste_io_abort_is_temp_ = FALSE;
2421 /* No ERR= specification. */
2423 ffeste_io_err_ = NULL_TREE;
2425 if ((ffeste_io_abort_is_temp_ = iostat))
2426 ffeste_io_abort_ = ffecom_temp_label ();
2428 ffeste_io_abort_ = NULL_TREE;
2433 /* Have IOSTAT= specification. */
2435 ffeste_io_iostat_is_temp_ = FALSE;
2436 ffeste_io_iostat_ = ffecom_expr
2437 (info->beru_spec[FFESTP_beruixIOSTAT].u.expr);
2439 else if (ffeste_io_abort_ != NULL_TREE)
2441 /* Have no IOSTAT= but have ERR=. */
2443 ffeste_io_iostat_is_temp_ = TRUE;
2445 = ffecom_make_tempvar ("beru", ffecom_integer_type_node,
2446 FFETARGET_charactersizeNONE, -1);
2450 /* No IOSTAT= or ERR= specification. */
2452 ffeste_io_iostat_is_temp_ = FALSE;
2453 ffeste_io_iostat_ = NULL_TREE;
2456 /* Now prescan, then convert, all the arguments. */
2458 alist = ffeste_io_ialist_ (errl || iostat, FFESTV_unitINTEXPR,
2459 info->beru_spec[FFESTP_beruixUNIT].u.expr, 6);
2461 /* Don't generate "if (iostat != 0) goto label;" if label is temp abort
2462 label, since we're gonna fall through to there anyway. */
2464 ffeste_io_call_ (ffecom_call_gfrt (rt, alist, NULL_TREE),
2465 ! ffeste_io_abort_is_temp_);
2467 /* If we've got a temp label, generate its code here. */
2469 if (ffeste_io_abort_is_temp_)
2471 DECL_INITIAL (ffeste_io_abort_) = error_mark_node;
2473 expand_label (ffeste_io_abort_);
2475 assert (ffeste_io_err_ == NULL_TREE);
2478 ffeste_end_stmt_ ();
2484 Also invoked by _labeldef_branch_finish_ (or, in cases
2485 of errors, other _labeldef_ functions) when the label definition is
2486 for a DO-target (LOOPEND) label, once per matching/outstanding DO
2487 block on the stack. */
2490 ffeste_do (ffestw block)
2492 #if FFECOM_targetCURRENT == FFECOM_targetFFE
2493 fputs ("+ END_DO\n", dmpout);
2494 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
2495 ffeste_emit_line_note_ ();
2497 if (ffestw_do_tvar (block) == 0)
2499 expand_end_loop (); /* DO WHILE and just DO. */
2501 ffeste_end_block_ (block);
2504 ffeste_end_iterdo_ (block,
2505 ffestw_do_tvar (block),
2506 ffestw_do_incr_saved (block),
2507 ffestw_do_count_var (block));
2513 /* End of statement following logical IF.
2515 Applies to *only* logical IF, not to IF-THEN. */
2520 #if FFECOM_targetCURRENT == FFECOM_targetFFE
2521 fputs ("+ END_IF\n", dmpout); /* Also see ffeste_R806. */
2522 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
2523 ffeste_emit_line_note_ ();
2527 ffeste_end_block_ (NULL);
2533 /* Generate "code" for branch label definition. */
2536 ffeste_labeldef_branch (ffelab label)
2538 #if FFECOM_targetCURRENT == FFECOM_targetFFE
2539 fprintf (dmpout, "+ label %lu\n", ffelab_value (label));
2540 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
2544 glabel = ffecom_lookup_label (label);
2545 assert (glabel != NULL_TREE);
2546 if (TREE_CODE (glabel) == ERROR_MARK)
2549 assert (DECL_INITIAL (glabel) == NULL_TREE);
2551 DECL_INITIAL (glabel) = error_mark_node;
2552 DECL_SOURCE_FILE (glabel) = ffelab_definition_filename (label);
2553 DECL_SOURCE_LINE (glabel) = ffelab_definition_filelinenum (label);
2557 expand_label (glabel);
2564 /* Generate "code" for FORMAT label definition. */
2567 ffeste_labeldef_format (ffelab label)
2569 #if FFECOM_targetCURRENT == FFECOM_targetFFE
2570 fprintf (dmpout, "$ label %lu\n", ffelab_value (label));
2571 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
2572 ffeste_label_formatdef_ = label;
2578 /* Assignment statement (outside of WHERE). */
2581 ffeste_R737A (ffebld dest, ffebld source)
2583 ffeste_check_simple_ ();
2585 #if FFECOM_targetCURRENT == FFECOM_targetFFE
2586 fputs ("+ let ", dmpout);
2588 fputs ("=", dmpout);
2589 ffebld_dump (source);
2590 fputc ('\n', dmpout);
2591 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
2592 ffeste_emit_line_note_ ();
2594 ffeste_start_stmt_ ();
2596 ffecom_expand_let_stmt (dest, source);
2598 ffeste_end_stmt_ ();
2604 /* Block IF (IF-THEN) statement. */
2607 ffeste_R803 (ffestw block, ffebld expr)
2609 ffeste_check_simple_ ();
2611 #if FFECOM_targetCURRENT == FFECOM_targetFFE
2612 fputs ("+ IF_block (", dmpout);
2614 fputs (")\n", dmpout);
2615 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
2619 ffeste_emit_line_note_ ();
2621 ffeste_start_block_ (block);
2623 temp = ffecom_make_tempvar ("ifthen", integer_type_node,
2624 FFETARGET_charactersizeNONE, -1);
2626 ffeste_start_stmt_ ();
2628 ffecom_prepare_expr (expr);
2630 if (ffecom_prepare_end ())
2634 result = ffecom_modify (void_type_node,
2636 ffecom_truth_value (ffecom_expr (expr)));
2638 expand_expr_stmt (result);
2640 ffeste_end_stmt_ ();
2644 ffeste_end_stmt_ ();
2646 temp = ffecom_truth_value (ffecom_expr (expr));
2649 expand_start_cond (temp, 0);
2651 /* No fake `else' constructs introduced (yet). */
2652 ffestw_set_ifthen_fake_else (block, 0);
2659 /* ELSE IF statement. */
2662 ffeste_R804 (ffestw block, ffebld expr)
2664 ffeste_check_simple_ ();
2666 #if FFECOM_targetCURRENT == FFECOM_targetFFE
2667 fputs ("+ ELSE_IF (", dmpout);
2669 fputs (")\n", dmpout);
2670 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
2674 ffeste_emit_line_note_ ();
2676 /* Since ELSEIF(expr) might require preparations for expr,
2677 implement as ELSE; prepare-expr; IF (expr) THEN ...; ENDIF. */
2679 expand_start_else ();
2681 ffeste_start_block_ (block);
2683 temp = ffecom_make_tempvar ("elseif", integer_type_node,
2684 FFETARGET_charactersizeNONE, -1);
2686 ffeste_start_stmt_ ();
2688 ffecom_prepare_expr (expr);
2690 if (ffecom_prepare_end ())
2694 result = ffecom_modify (void_type_node,
2696 ffecom_truth_value (ffecom_expr (expr)));
2698 expand_expr_stmt (result);
2700 ffeste_end_stmt_ ();
2704 /* In this case, we could probably have used expand_start_elseif
2705 instead, saving the need for a fake `else' construct. But,
2706 until it's clear that'd improve performance, it's easier this
2707 way, since we have to expand_start_else before we get to this
2708 test, given the current design. */
2710 ffeste_end_stmt_ ();
2712 temp = ffecom_truth_value (ffecom_expr (expr));
2715 expand_start_cond (temp, 0);
2717 /* Increment number of fake `else' constructs introduced. */
2718 ffestw_set_ifthen_fake_else (block,
2719 ffestw_ifthen_fake_else (block) + 1);
2726 /* ELSE statement. */
2729 ffeste_R805 (ffestw block UNUSED)
2731 ffeste_check_simple_ ();
2733 #if FFECOM_targetCURRENT == FFECOM_targetFFE
2734 fputs ("+ ELSE\n", dmpout);
2735 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
2736 ffeste_emit_line_note_ ();
2738 expand_start_else ();
2744 /* END IF statement. */
2747 ffeste_R806 (ffestw block)
2749 #if FFECOM_targetCURRENT == FFECOM_targetFFE
2750 fputs ("+ END_IF_then\n", dmpout); /* Also see ffeste_shriek_if_. */
2751 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
2753 int i = ffestw_ifthen_fake_else (block) + 1;
2755 ffeste_emit_line_note_ ();
2761 ffeste_end_block_ (block);
2769 /* Logical IF statement. */
2772 ffeste_R807 (ffebld expr)
2774 ffeste_check_simple_ ();
2776 #if FFECOM_targetCURRENT == FFECOM_targetFFE
2777 fputs ("+ IF_logical (", dmpout);
2779 fputs (")\n", dmpout);
2780 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
2784 ffeste_emit_line_note_ ();
2786 ffeste_start_block_ (NULL);
2788 temp = ffecom_make_tempvar ("if", integer_type_node,
2789 FFETARGET_charactersizeNONE, -1);
2791 ffeste_start_stmt_ ();
2793 ffecom_prepare_expr (expr);
2795 if (ffecom_prepare_end ())
2799 result = ffecom_modify (void_type_node,
2801 ffecom_truth_value (ffecom_expr (expr)));
2803 expand_expr_stmt (result);
2805 ffeste_end_stmt_ ();
2809 ffeste_end_stmt_ ();
2811 temp = ffecom_truth_value (ffecom_expr (expr));
2814 expand_start_cond (temp, 0);
2821 /* SELECT CASE statement. */
2824 ffeste_R809 (ffestw block, ffebld expr)
2826 ffeste_check_simple_ ();
2828 #if FFECOM_targetCURRENT == FFECOM_targetFFE
2829 fputs ("+ SELECT_CASE (", dmpout);
2831 fputs (")\n", dmpout);
2832 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
2833 ffeste_emit_line_note_ ();
2835 ffeste_start_block_ (block);
2838 || (ffeinfo_basictype (ffebld_info (expr))
2839 == FFEINFO_basictypeANY))
2840 ffestw_set_select_texpr (block, error_mark_node);
2841 else if (ffeinfo_basictype (ffebld_info (expr))
2842 == FFEINFO_basictypeCHARACTER)
2844 /* ~~~Someday handle CHARACTER*1, CHARACTER*N */
2846 ffebad_start_msg ("SELECT CASE on CHARACTER type (at %0) not supported -- sorry",
2847 FFEBAD_severityFATAL);
2848 ffebad_here (0, ffestw_line (block), ffestw_col (block));
2850 ffestw_set_select_texpr (block, error_mark_node);
2857 result = ffecom_make_tempvar ("select", ffecom_type_expr (expr),
2858 ffeinfo_size (ffebld_info (expr)),
2861 ffeste_start_stmt_ ();
2863 ffecom_prepare_expr (expr);
2865 ffecom_prepare_end ();
2867 texpr = ffecom_expr (expr);
2869 assert (TYPE_MAIN_VARIANT (TREE_TYPE (texpr))
2870 == TYPE_MAIN_VARIANT (TREE_TYPE (result)));
2872 texpr = ffecom_modify (void_type_node,
2875 expand_expr_stmt (texpr);
2877 ffeste_end_stmt_ ();
2879 expand_start_case (1, result, TREE_TYPE (result),
2880 "SELECT CASE statement");
2881 ffestw_set_select_texpr (block, texpr);
2882 ffestw_set_select_break (block, FALSE);
2891 If casenum is 0, it's CASE DEFAULT. Else it's the case ranges at
2892 the start of the first_stmt list in the select object at the top of
2893 the stack that match casenum. */
2896 ffeste_R810 (ffestw block, unsigned long casenum)
2898 ffestwSelect s = ffestw_select (block);
2901 ffeste_check_simple_ ();
2903 if (s->first_stmt == (ffestwCase) &s->first_rel)
2908 #if FFECOM_targetCURRENT == FFECOM_targetFFE
2909 if ((c == NULL) || (casenum != c->casenum))
2911 if (casenum == 0) /* Intentional CASE DEFAULT. */
2912 fputs ("+ CASE_DEFAULT", dmpout);
2918 fputs ("+ CASE (", dmpout);
2922 fputc (',', dmpout);
2926 ffebld_constant_dump (c->low);
2927 if (c->low != c->high)
2929 fputc (':', dmpout);
2930 if (c->high != NULL)
2931 ffebld_constant_dump (c->high);
2935 c->previous_stmt->previous_stmt->next_stmt = c;
2936 c->previous_stmt = c->previous_stmt->previous_stmt;
2938 while ((c != (ffestwCase) &s->first_rel) && (casenum == c->casenum));
2939 fputc (')', dmpout);
2942 fputc ('\n', dmpout);
2943 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
2951 ffeste_emit_line_note_ ();
2953 if (ffestw_select_texpr (block) == error_mark_node)
2956 /* ~~~Someday handle CHARACTER*1, CHARACTER*N */
2958 tlabel = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
2960 if (ffestw_select_break (block))
2961 expand_exit_something ();
2963 ffestw_set_select_break (block, TRUE);
2965 if ((c == NULL) || (casenum != c->casenum))
2967 if (casenum == 0) /* Intentional CASE DEFAULT. */
2969 pushok = pushcase (NULL_TREE, 0, tlabel, &duplicate);
2970 assert (pushok == 0);
2976 texprlow = (c->low == NULL) ? NULL_TREE
2977 : ffecom_constantunion (&ffebld_constant_union (c->low), s->type,
2978 s->kindtype, ffecom_tree_type[s->type][s->kindtype]);
2979 if (c->low != c->high)
2981 texprhigh = (c->high == NULL) ? NULL_TREE
2982 : ffecom_constantunion (&ffebld_constant_union (c->high),
2983 s->type, s->kindtype, ffecom_tree_type[s->type][s->kindtype]);
2984 pushok = pushcase_range (texprlow, texprhigh, convert,
2985 tlabel, &duplicate);
2988 pushok = pushcase (texprlow, convert, tlabel, &duplicate);
2989 assert (pushok == 0);
2992 c->previous_stmt->previous_stmt->next_stmt = c;
2993 c->previous_stmt = c->previous_stmt->previous_stmt;
2995 while ((c != (ffestwCase) &s->first_rel) && (casenum == c->casenum));
3004 /* END SELECT statement. */
3007 ffeste_R811 (ffestw block)
3009 #if FFECOM_targetCURRENT == FFECOM_targetFFE
3010 fputs ("+ END_SELECT\n", dmpout);
3011 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
3012 ffeste_emit_line_note_ ();
3014 /* ~~~Someday handle CHARACTER*1, CHARACTER*N */
3016 if (TREE_CODE (ffestw_select_texpr (block)) != ERROR_MARK)
3017 expand_end_case (ffestw_select_texpr (block));
3019 ffeste_end_block_ (block);
3025 /* Iterative DO statement. */
3028 ffeste_R819A (ffestw block, ffelab label UNUSED, ffebld var,
3029 ffebld start, ffelexToken start_token,
3030 ffebld end, ffelexToken end_token,
3031 ffebld incr, ffelexToken incr_token)
3033 ffeste_check_simple_ ();
3035 #if FFECOM_targetCURRENT == FFECOM_targetFFE
3036 if ((ffebld_op (incr) == FFEBLD_opCONTER)
3037 && (ffebld_constant_is_zero (ffebld_conter (incr))))
3039 ffebad_start (FFEBAD_DO_STEP_ZERO);
3040 ffebad_here (0, ffelex_token_where_line (incr_token),
3041 ffelex_token_where_column (incr_token));
3042 ffebad_string ("Iterative DO loop");
3044 /* Don't bother replacing it with 1 yet. */
3048 fputs ("+ DO_iterative_nonlabeled (", dmpout);
3050 fprintf (dmpout, "+ DO_iterative_labeled %lu (", ffelab_value (label));
3052 fputc ('=', dmpout);
3053 ffebld_dump (start);
3054 fputc (',', dmpout);
3056 fputc (',', dmpout);
3058 fputs (")\n", dmpout);
3059 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
3061 ffeste_emit_line_note_ ();
3063 ffeste_begin_iterdo_ (block, NULL, NULL, NULL,
3068 "Iterative DO loop");
3075 /* DO WHILE statement. */
3078 ffeste_R819B (ffestw block, ffelab label UNUSED, ffebld expr)
3080 ffeste_check_simple_ ();
3082 #if FFECOM_targetCURRENT == FFECOM_targetFFE
3084 fputs ("+ DO_WHILE_nonlabeled (", dmpout);
3086 fprintf (dmpout, "+ DO_WHILE_labeled %lu (", ffelab_value (label));
3088 fputs (")\n", dmpout);
3089 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
3093 ffeste_emit_line_note_ ();
3095 ffeste_start_block_ (block);
3099 struct nesting *loop;
3101 result = ffecom_make_tempvar ("dowhile", integer_type_node,
3102 FFETARGET_charactersizeNONE, -1);
3103 loop = expand_start_loop (1);
3105 ffeste_start_stmt_ ();
3107 ffecom_prepare_expr (expr);
3109 ffecom_prepare_end ();
3111 result = ffecom_modify (void_type_node,
3113 ffecom_truth_value (ffecom_expr (expr)));
3114 expand_expr_stmt (result);
3116 ffeste_end_stmt_ ();
3118 ffestw_set_do_hook (block, loop);
3119 expand_exit_loop_if_false (0, result);
3122 ffestw_set_do_hook (block, expand_start_loop (1));
3124 ffestw_set_do_tvar (block, NULL_TREE);
3131 /* END DO statement.
3133 This is the MIL-STD 1753 END DO. It's syntactic sugar, similar to
3134 CONTINUE (except that it has to have a label that is the target of
3135 one or more iterative DO statement), not the Fortran-90 structured
3136 END DO, which is handled elsewhere, as is the actual mechanism of
3137 ending an iterative DO statement, even one that ends at a label. */
3142 ffeste_check_simple_ ();
3144 #if FFECOM_targetCURRENT == FFECOM_targetFFE
3145 fputs ("+ END_DO_sugar\n", dmpout);
3146 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
3147 ffeste_emit_line_note_ ();
3155 /* CYCLE statement. */
3158 ffeste_R834 (ffestw block)
3160 ffeste_check_simple_ ();
3162 #if FFECOM_targetCURRENT == FFECOM_targetFFE
3163 fprintf (dmpout, "+ CYCLE block #%lu\n", ffestw_blocknum (block));
3164 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
3165 ffeste_emit_line_note_ ();
3167 expand_continue_loop (ffestw_do_hook (block));
3173 /* EXIT statement. */
3176 ffeste_R835 (ffestw block)
3178 ffeste_check_simple_ ();
3180 #if FFECOM_targetCURRENT == FFECOM_targetFFE
3181 fprintf (dmpout, "+ EXIT block #%lu\n", ffestw_blocknum (block));
3182 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
3183 ffeste_emit_line_note_ ();
3185 expand_exit_loop (ffestw_do_hook (block));
3191 /* GOTO statement. */
3194 ffeste_R836 (ffelab label)
3196 ffeste_check_simple_ ();
3198 #if FFECOM_targetCURRENT == FFECOM_targetFFE
3199 fprintf (dmpout, "+ GOTO %lu\n", ffelab_value (label));
3200 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
3204 ffeste_emit_line_note_ ();
3206 glabel = ffecom_lookup_label (label);
3207 if ((glabel != NULL_TREE)
3208 && (TREE_CODE (glabel) != ERROR_MARK))
3210 expand_goto (glabel);
3211 TREE_USED (glabel) = 1;
3219 /* Computed GOTO statement. */
3222 ffeste_R837 (ffelab *labels, int count, ffebld expr)
3226 ffeste_check_simple_ ();
3228 #if FFECOM_targetCURRENT == FFECOM_targetFFE
3229 fputs ("+ CGOTO (", dmpout);
3230 for (i = 0; i < count; ++i)
3233 fputc (',', dmpout);
3234 fprintf (dmpout, "%" ffelabValue_f "u", ffelab_value (labels[i]));
3236 fputs ("),", dmpout);
3238 fputc ('\n', dmpout);
3239 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
3247 ffeste_emit_line_note_ ();
3249 ffeste_start_stmt_ ();
3251 ffecom_prepare_expr (expr);
3253 ffecom_prepare_end ();
3255 texpr = ffecom_expr (expr);
3257 expand_start_case (0, texpr, TREE_TYPE (texpr), "computed GOTO statement");
3259 for (i = 0; i < count; ++i)
3261 value = build_int_2 (i + 1, 0);
3262 tlabel = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
3264 pushok = pushcase (value, convert, tlabel, &duplicate);
3265 assert (pushok == 0);
3267 tlabel = ffecom_lookup_label (labels[i]);
3268 if ((tlabel == NULL_TREE)
3269 || (TREE_CODE (tlabel) == ERROR_MARK))
3272 expand_goto (tlabel);
3273 TREE_USED (tlabel) = 1;
3275 expand_end_case (texpr);
3277 ffeste_end_stmt_ ();
3284 /* ASSIGN statement. */
3287 ffeste_R838 (ffelab label, ffebld target)
3289 ffeste_check_simple_ ();
3291 #if FFECOM_targetCURRENT == FFECOM_targetFFE
3292 fprintf (dmpout, "+ ASSIGN %lu TO ", ffelab_value (label));
3293 ffebld_dump (target);
3294 fputc ('\n', dmpout);
3295 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
3301 ffeste_emit_line_note_ ();
3303 /* No need to call ffeste_start_stmt_(), as the sorts of expressions
3304 seen here should never require use of temporaries. */
3306 label_tree = ffecom_lookup_label (label);
3307 if ((label_tree != NULL_TREE)
3308 && (TREE_CODE (label_tree) != ERROR_MARK))
3310 label_tree = ffecom_1 (ADDR_EXPR,
3311 build_pointer_type (void_type_node),
3313 TREE_CONSTANT (label_tree) = 1;
3315 target_tree = ffecom_expr_assign_w (target);
3316 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (target_tree)))
3317 < GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (label_tree))))
3318 error ("ASSIGN to variable that is too small");
3320 label_tree = convert (TREE_TYPE (target_tree), label_tree);
3322 expr_tree = ffecom_modify (void_type_node,
3325 expand_expr_stmt (expr_tree);
3335 /* Assigned GOTO statement. */
3338 ffeste_R839 (ffebld target)
3340 ffeste_check_simple_ ();
3342 #if FFECOM_targetCURRENT == FFECOM_targetFFE
3343 fputs ("+ AGOTO ", dmpout);
3344 ffebld_dump (target);
3345 fputc ('\n', dmpout);
3346 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
3350 ffeste_emit_line_note_ ();
3352 /* No need to call ffeste_start_stmt_(), as the sorts of expressions
3353 seen here should never require use of temporaries. */
3355 t = ffecom_expr_assign (target);
3356 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (t)))
3357 < GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
3358 error ("ASSIGNed GOTO target variable is too small");
3360 expand_computed_goto (convert (TREE_TYPE (null_pointer_node), t));
3369 /* Arithmetic IF statement. */
3372 ffeste_R840 (ffebld expr, ffelab neg, ffelab zero, ffelab pos)
3374 ffeste_check_simple_ ();
3376 #if FFECOM_targetCURRENT == FFECOM_targetFFE
3377 fputs ("+ IF_arithmetic (", dmpout);
3379 fprintf (dmpout, ") %" ffelabValue_f "u,%" ffelabValue_f "u,%" ffelabValue_f "u\n",
3380 ffelab_value (neg), ffelab_value (zero), ffelab_value (pos));
3381 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
3383 tree gneg = ffecom_lookup_label (neg);
3384 tree gzero = ffecom_lookup_label (zero);
3385 tree gpos = ffecom_lookup_label (pos);
3388 ffeste_emit_line_note_ ();
3390 if ((gneg == NULL_TREE) || (gzero == NULL_TREE) || (gpos == NULL_TREE))
3392 if ((TREE_CODE (gneg) == ERROR_MARK)
3393 || (TREE_CODE (gzero) == ERROR_MARK)
3394 || (TREE_CODE (gpos) == ERROR_MARK))
3397 ffeste_start_stmt_ ();
3399 ffecom_prepare_expr (expr);
3401 ffecom_prepare_end ();
3406 expand_goto (gzero);
3409 /* IF (expr.LE.0) THEN GOTO neg/zero ELSE GOTO pos. */
3410 texpr = ffecom_expr (expr);
3411 texpr = ffecom_2 (LE_EXPR, integer_type_node,
3413 convert (TREE_TYPE (texpr),
3414 integer_zero_node));
3415 expand_start_cond (ffecom_truth_value (texpr), 0);
3416 expand_goto (gzero);
3417 expand_start_else ();
3422 else if (neg == pos)
3424 /* IF (expr.NE.0) THEN GOTO neg/pos ELSE GOTO zero. */
3425 texpr = ffecom_expr (expr);
3426 texpr = ffecom_2 (NE_EXPR, integer_type_node,
3428 convert (TREE_TYPE (texpr),
3429 integer_zero_node));
3430 expand_start_cond (ffecom_truth_value (texpr), 0);
3432 expand_start_else ();
3433 expand_goto (gzero);
3436 else if (zero == pos)
3438 /* IF (expr.GE.0) THEN GOTO zero/pos ELSE GOTO neg. */
3439 texpr = ffecom_expr (expr);
3440 texpr = ffecom_2 (GE_EXPR, integer_type_node,
3442 convert (TREE_TYPE (texpr),
3443 integer_zero_node));
3444 expand_start_cond (ffecom_truth_value (texpr), 0);
3445 expand_goto (gzero);
3446 expand_start_else ();
3452 /* Use a SAVE_EXPR in combo with:
3453 IF (expr.LT.0) THEN GOTO neg
3454 ELSEIF (expr.GT.0) THEN GOTO pos
3456 tree expr_saved = ffecom_save_tree (ffecom_expr (expr));
3458 texpr = ffecom_2 (LT_EXPR, integer_type_node,
3460 convert (TREE_TYPE (expr_saved),
3461 integer_zero_node));
3462 expand_start_cond (ffecom_truth_value (texpr), 0);
3464 texpr = ffecom_2 (GT_EXPR, integer_type_node,
3466 convert (TREE_TYPE (expr_saved),
3467 integer_zero_node));
3468 expand_start_elseif (ffecom_truth_value (texpr));
3470 expand_start_else ();
3471 expand_goto (gzero);
3475 ffeste_end_stmt_ ();
3482 /* CONTINUE statement. */
3487 ffeste_check_simple_ ();
3489 #if FFECOM_targetCURRENT == FFECOM_targetFFE
3490 fputs ("+ CONTINUE\n", dmpout);
3491 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
3492 ffeste_emit_line_note_ ();
3500 /* STOP statement. */
3503 ffeste_R842 (ffebld expr)
3505 ffeste_check_simple_ ();
3507 #if FFECOM_targetCURRENT == FFECOM_targetFFE
3510 fputs ("+ STOP\n", dmpout);
3514 fputs ("+ STOP_coded ", dmpout);
3516 fputc ('\n', dmpout);
3518 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
3523 ffeste_emit_line_note_ ();
3526 || (ffeinfo_basictype (ffebld_info (expr))
3527 == FFEINFO_basictypeANY))
3529 msg = ffelex_token_new_character ("", ffelex_token_where_line
3530 (ffesta_tokens[0]), ffelex_token_where_column
3531 (ffesta_tokens[0]));
3532 expr = ffebld_new_conter (ffebld_constant_new_characterdefault
3534 ffelex_token_kill (msg);
3535 ffebld_set_info (expr, ffeinfo_new (FFEINFO_basictypeCHARACTER,
3536 FFEINFO_kindtypeCHARACTERDEFAULT, 0, FFEINFO_kindENTITY,
3537 FFEINFO_whereCONSTANT, 0));
3539 else if (ffeinfo_basictype (ffebld_info (expr))
3540 == FFEINFO_basictypeINTEGER)
3544 assert (ffebld_op (expr) == FFEBLD_opCONTER);
3545 assert (ffeinfo_kindtype (ffebld_info (expr))
3546 == FFEINFO_kindtypeINTEGERDEFAULT);
3547 sprintf (num, "%" ffetargetIntegerDefault_f "d",
3548 ffebld_constant_integer1 (ffebld_conter (expr)));
3549 msg = ffelex_token_new_character (num, 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));
3561 assert (ffeinfo_basictype (ffebld_info (expr))
3562 == FFEINFO_basictypeCHARACTER);
3563 assert (ffebld_op (expr) == FFEBLD_opCONTER);
3564 assert (ffeinfo_kindtype (ffebld_info (expr))
3565 == FFEINFO_kindtypeCHARACTERDEFAULT);
3568 /* No need to call ffeste_start_stmt_(), as the sorts of expressions
3569 seen here should never require use of temporaries. */
3571 callit = ffecom_call_gfrt (FFECOM_gfrtSTOP,
3572 ffecom_list_ptr_to_expr (ffebld_new_item (expr, NULL)),
3574 TREE_SIDE_EFFECTS (callit) = 1;
3576 expand_expr_stmt (callit);
3585 /* PAUSE statement. */
3588 ffeste_R843 (ffebld expr)
3590 ffeste_check_simple_ ();
3592 #if FFECOM_targetCURRENT == FFECOM_targetFFE
3595 fputs ("+ PAUSE\n", dmpout);
3599 fputs ("+ PAUSE_coded ", dmpout);
3601 fputc ('\n', dmpout);
3603 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
3608 ffeste_emit_line_note_ ();
3611 || (ffeinfo_basictype (ffebld_info (expr))
3612 == FFEINFO_basictypeANY))
3614 msg = ffelex_token_new_character ("", ffelex_token_where_line
3615 (ffesta_tokens[0]), ffelex_token_where_column
3616 (ffesta_tokens[0]));
3617 expr = ffebld_new_conter (ffebld_constant_new_characterdefault
3619 ffelex_token_kill (msg);
3620 ffebld_set_info (expr, ffeinfo_new (FFEINFO_basictypeCHARACTER,
3621 FFEINFO_kindtypeCHARACTERDEFAULT, 0, FFEINFO_kindENTITY,
3622 FFEINFO_whereCONSTANT, 0));
3624 else if (ffeinfo_basictype (ffebld_info (expr))
3625 == FFEINFO_basictypeINTEGER)
3629 assert (ffebld_op (expr) == FFEBLD_opCONTER);
3630 assert (ffeinfo_kindtype (ffebld_info (expr))
3631 == FFEINFO_kindtypeINTEGERDEFAULT);
3632 sprintf (num, "%" ffetargetIntegerDefault_f "d",
3633 ffebld_constant_integer1 (ffebld_conter (expr)));
3634 msg = ffelex_token_new_character (num, ffelex_token_where_line
3635 (ffesta_tokens[0]), ffelex_token_where_column
3636 (ffesta_tokens[0]));
3637 expr = ffebld_new_conter (ffebld_constant_new_characterdefault
3639 ffelex_token_kill (msg);
3640 ffebld_set_info (expr, ffeinfo_new (FFEINFO_basictypeCHARACTER,
3641 FFEINFO_kindtypeCHARACTERDEFAULT, 0, FFEINFO_kindENTITY,
3642 FFEINFO_whereCONSTANT, 0));
3646 assert (ffeinfo_basictype (ffebld_info (expr))
3647 == FFEINFO_basictypeCHARACTER);
3648 assert (ffebld_op (expr) == FFEBLD_opCONTER);
3649 assert (ffeinfo_kindtype (ffebld_info (expr))
3650 == FFEINFO_kindtypeCHARACTERDEFAULT);
3653 /* No need to call ffeste_start_stmt_(), as the sorts of expressions
3654 seen here should never require use of temporaries. */
3656 callit = ffecom_call_gfrt (FFECOM_gfrtPAUSE,
3657 ffecom_list_ptr_to_expr (ffebld_new_item (expr, NULL)),
3659 TREE_SIDE_EFFECTS (callit) = 1;
3661 expand_expr_stmt (callit);
3665 #if 0 /* Old approach for phantom g77 run-time
3670 ffeste_emit_line_note_ ();
3673 callit = ffecom_call_gfrt (FFECOM_gfrtPAUSENIL, NULL_TREE, NULL_TREE);
3674 else if (ffeinfo_basictype (ffebld_info (expr))
3675 == FFEINFO_basictypeINTEGER)
3676 callit = ffecom_call_gfrt (FFECOM_gfrtPAUSEINT,
3677 ffecom_list_ptr_to_expr (ffebld_new_item (expr, NULL)),
3679 else if (ffeinfo_basictype (ffebld_info (expr))
3680 == FFEINFO_basictypeCHARACTER)
3681 callit = ffecom_call_gfrt (FFECOM_gfrtPAUSECHAR,
3682 ffecom_list_ptr_to_expr (ffebld_new_item (expr, NULL)),
3686 TREE_SIDE_EFFECTS (callit) = 1;
3688 expand_expr_stmt (callit);
3698 /* OPEN statement. */
3701 ffeste_R904 (ffestpOpenStmt *info)
3703 ffeste_check_simple_ ();
3705 #if FFECOM_targetCURRENT == FFECOM_targetFFE
3706 fputs ("+ OPEN (", dmpout);
3707 ffeste_subr_file_ ("UNIT", &info->open_spec[FFESTP_openixUNIT]);
3708 ffeste_subr_file_ ("ACCESS", &info->open_spec[FFESTP_openixACCESS]);
3709 ffeste_subr_file_ ("ACTION", &info->open_spec[FFESTP_openixACTION]);
3710 ffeste_subr_file_ ("ASSOCIATEVARIABLE", &info->open_spec[FFESTP_openixASSOCIATEVARIABLE]);
3711 ffeste_subr_file_ ("BLANK", &info->open_spec[FFESTP_openixBLANK]);
3712 ffeste_subr_file_ ("BLOCKSIZE", &info->open_spec[FFESTP_openixBLOCKSIZE]);
3713 ffeste_subr_file_ ("BUFFERCOUNT", &info->open_spec[FFESTP_openixBUFFERCOUNT]);
3714 ffeste_subr_file_ ("CARRIAGECONTROL", &info->open_spec[FFESTP_openixCARRIAGECONTROL]);
3715 ffeste_subr_file_ ("DEFAULTFILE", &info->open_spec[FFESTP_openixDEFAULTFILE]);
3716 ffeste_subr_file_ ("DELIM", &info->open_spec[FFESTP_openixDELIM]);
3717 ffeste_subr_file_ ("DISPOSE", &info->open_spec[FFESTP_openixDISPOSE]);
3718 ffeste_subr_file_ ("ERR", &info->open_spec[FFESTP_openixERR]);
3719 ffeste_subr_file_ ("EXTENDSIZE", &info->open_spec[FFESTP_openixEXTENDSIZE]);
3720 ffeste_subr_file_ ("FILE", &info->open_spec[FFESTP_openixFILE]);
3721 ffeste_subr_file_ ("FORM", &info->open_spec[FFESTP_openixFORM]);
3722 ffeste_subr_file_ ("INITIALSIZE", &info->open_spec[FFESTP_openixINITIALSIZE]);
3723 ffeste_subr_file_ ("IOSTAT", &info->open_spec[FFESTP_openixIOSTAT]);
3724 ffeste_subr_file_ ("KEY", &info->open_spec[FFESTP_openixKEY]);
3725 ffeste_subr_file_ ("MAXREC", &info->open_spec[FFESTP_openixMAXREC]);
3726 ffeste_subr_file_ ("NOSPANBLOCKS", &info->open_spec[FFESTP_openixNOSPANBLOCKS]);
3727 ffeste_subr_file_ ("ORGANIZATION", &info->open_spec[FFESTP_openixORGANIZATION]);
3728 ffeste_subr_file_ ("PAD", &info->open_spec[FFESTP_openixPAD]);
3729 ffeste_subr_file_ ("POSITION", &info->open_spec[FFESTP_openixPOSITION]);
3730 ffeste_subr_file_ ("READONLY", &info->open_spec[FFESTP_openixREADONLY]);
3731 ffeste_subr_file_ ("RECL", &info->open_spec[FFESTP_openixRECL]);
3732 ffeste_subr_file_ ("RECORDTYPE", &info->open_spec[FFESTP_openixRECORDTYPE]);
3733 ffeste_subr_file_ ("SHARED", &info->open_spec[FFESTP_openixSHARED]);
3734 ffeste_subr_file_ ("STATUS", &info->open_spec[FFESTP_openixSTATUS]);
3735 ffeste_subr_file_ ("USEROPEN", &info->open_spec[FFESTP_openixUSEROPEN]);
3736 fputs (")\n", dmpout);
3737 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
3743 ffeste_emit_line_note_ ();
3745 #define specified(something) (info->open_spec[something].kw_or_val_present)
3747 iostat = specified (FFESTP_openixIOSTAT);
3748 errl = specified (FFESTP_openixERR);
3752 ffeste_start_stmt_ ();
3758 = ffecom_lookup_label
3759 (info->open_spec[FFESTP_openixERR].u.label);
3760 ffeste_io_abort_is_temp_ = FALSE;
3764 ffeste_io_err_ = NULL_TREE;
3766 if ((ffeste_io_abort_is_temp_ = iostat))
3767 ffeste_io_abort_ = ffecom_temp_label ();
3769 ffeste_io_abort_ = NULL_TREE;
3774 /* Have IOSTAT= specification. */
3776 ffeste_io_iostat_is_temp_ = FALSE;
3777 ffeste_io_iostat_ = ffecom_expr
3778 (info->open_spec[FFESTP_openixIOSTAT].u.expr);
3780 else if (ffeste_io_abort_ != NULL_TREE)
3782 /* Have no IOSTAT= but have ERR=. */
3784 ffeste_io_iostat_is_temp_ = TRUE;
3786 = ffecom_make_tempvar ("open", ffecom_integer_type_node,
3787 FFETARGET_charactersizeNONE, -1);
3791 /* No IOSTAT= or ERR= specification. */
3793 ffeste_io_iostat_is_temp_ = FALSE;
3794 ffeste_io_iostat_ = NULL_TREE;
3797 /* Now prescan, then convert, all the arguments. */
3799 args = ffeste_io_olist_ (errl || iostat,
3800 info->open_spec[FFESTP_openixUNIT].u.expr,
3801 &info->open_spec[FFESTP_openixFILE],
3802 &info->open_spec[FFESTP_openixSTATUS],
3803 &info->open_spec[FFESTP_openixACCESS],
3804 &info->open_spec[FFESTP_openixFORM],
3805 &info->open_spec[FFESTP_openixRECL],
3806 &info->open_spec[FFESTP_openixBLANK]);
3808 /* Don't generate "if (iostat != 0) goto label;" if label is temp abort
3809 label, since we're gonna fall through to there anyway. */
3811 ffeste_io_call_ (ffecom_call_gfrt (FFECOM_gfrtFOPEN, args, NULL_TREE),
3812 ! ffeste_io_abort_is_temp_);
3814 /* If we've got a temp label, generate its code here. */
3816 if (ffeste_io_abort_is_temp_)
3818 DECL_INITIAL (ffeste_io_abort_) = error_mark_node;
3820 expand_label (ffeste_io_abort_);
3822 assert (ffeste_io_err_ == NULL_TREE);
3825 ffeste_end_stmt_ ();
3832 /* CLOSE statement. */
3835 ffeste_R907 (ffestpCloseStmt *info)
3837 ffeste_check_simple_ ();
3839 #if FFECOM_targetCURRENT == FFECOM_targetFFE
3840 fputs ("+ CLOSE (", dmpout);
3841 ffeste_subr_file_ ("UNIT", &info->close_spec[FFESTP_closeixUNIT]);
3842 ffeste_subr_file_ ("ERR", &info->close_spec[FFESTP_closeixERR]);
3843 ffeste_subr_file_ ("IOSTAT", &info->close_spec[FFESTP_closeixIOSTAT]);
3844 ffeste_subr_file_ ("STATUS", &info->close_spec[FFESTP_closeixSTATUS]);
3845 fputs (")\n", dmpout);
3846 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
3852 ffeste_emit_line_note_ ();
3854 #define specified(something) (info->close_spec[something].kw_or_val_present)
3856 iostat = specified (FFESTP_closeixIOSTAT);
3857 errl = specified (FFESTP_closeixERR);
3861 ffeste_start_stmt_ ();
3867 = ffecom_lookup_label
3868 (info->close_spec[FFESTP_closeixERR].u.label);
3869 ffeste_io_abort_is_temp_ = FALSE;
3873 ffeste_io_err_ = NULL_TREE;
3875 if ((ffeste_io_abort_is_temp_ = iostat))
3876 ffeste_io_abort_ = ffecom_temp_label ();
3878 ffeste_io_abort_ = NULL_TREE;
3883 /* Have IOSTAT= specification. */
3885 ffeste_io_iostat_is_temp_ = FALSE;
3886 ffeste_io_iostat_ = ffecom_expr
3887 (info->close_spec[FFESTP_closeixIOSTAT].u.expr);
3889 else if (ffeste_io_abort_ != NULL_TREE)
3891 /* Have no IOSTAT= but have ERR=. */
3893 ffeste_io_iostat_is_temp_ = TRUE;
3895 = ffecom_make_tempvar ("close", ffecom_integer_type_node,
3896 FFETARGET_charactersizeNONE, -1);
3900 /* No IOSTAT= or ERR= specification. */
3902 ffeste_io_iostat_is_temp_ = FALSE;
3903 ffeste_io_iostat_ = NULL_TREE;
3906 /* Now prescan, then convert, all the arguments. */
3908 args = ffeste_io_cllist_ (errl || iostat,
3909 info->close_spec[FFESTP_closeixUNIT].u.expr,
3910 &info->close_spec[FFESTP_closeixSTATUS]);
3912 /* Don't generate "if (iostat != 0) goto label;" if label is temp abort
3913 label, since we're gonna fall through to there anyway. */
3915 ffeste_io_call_ (ffecom_call_gfrt (FFECOM_gfrtFCLOS, args, NULL_TREE),
3916 ! ffeste_io_abort_is_temp_);
3918 /* If we've got a temp label, generate its code here. */
3920 if (ffeste_io_abort_is_temp_)
3922 DECL_INITIAL (ffeste_io_abort_) = error_mark_node;
3924 expand_label (ffeste_io_abort_);
3926 assert (ffeste_io_err_ == NULL_TREE);
3929 ffeste_end_stmt_ ();
3936 /* READ(...) statement -- start. */
3939 ffeste_R909_start (ffestpReadStmt *info, bool only_format UNUSED,
3940 ffestvUnit unit, ffestvFormat format, bool rec,
3943 ffeste_check_start_ ();
3945 #if FFECOM_targetCURRENT == FFECOM_targetFFE
3948 case FFESTV_formatNONE:
3950 fputs ("+ READ_ufdac", dmpout);
3952 fputs ("+ READ_ufidx", dmpout);
3954 fputs ("+ READ_ufseq", dmpout);
3957 case FFESTV_formatLABEL:
3958 case FFESTV_formatCHAREXPR:
3959 case FFESTV_formatINTEXPR:
3961 fputs ("+ READ_fmdac", dmpout);
3963 fputs ("+ READ_fmidx", dmpout);
3964 else if (unit == FFESTV_unitCHAREXPR)
3965 fputs ("+ READ_fmint", dmpout);
3967 fputs ("+ READ_fmseq", dmpout);
3970 case FFESTV_formatASTERISK:
3971 if (unit == FFESTV_unitCHAREXPR)
3972 fputs ("+ READ_lsint", dmpout);
3974 fputs ("+ READ_lsseq", dmpout);
3977 case FFESTV_formatNAMELIST:
3978 fputs ("+ READ_nlseq", dmpout);
3982 assert ("Unexpected kind of format item in R909 READ" == NULL);
3987 fputc (' ', dmpout);
3988 ffeste_subr_file_ ("FORMAT", &info->read_spec[FFESTP_readixFORMAT]);
3989 fputc (' ', dmpout);
3994 fputs (" (", dmpout);
3995 ffeste_subr_file_ ("UNIT", &info->read_spec[FFESTP_readixUNIT]);
3996 ffeste_subr_file_ ("FORMAT", &info->read_spec[FFESTP_readixFORMAT]);
3997 ffeste_subr_file_ ("ADVANCE", &info->read_spec[FFESTP_readixADVANCE]);
3998 ffeste_subr_file_ ("EOR", &info->read_spec[FFESTP_readixEOR]);
3999 ffeste_subr_file_ ("ERR", &info->read_spec[FFESTP_readixERR]);
4000 ffeste_subr_file_ ("END", &info->read_spec[FFESTP_readixEND]);
4001 ffeste_subr_file_ ("IOSTAT", &info->read_spec[FFESTP_readixIOSTAT]);
4002 ffeste_subr_file_ ("KEYEQ", &info->read_spec[FFESTP_readixKEYEQ]);
4003 ffeste_subr_file_ ("KEYGE", &info->read_spec[FFESTP_readixKEYGE]);
4004 ffeste_subr_file_ ("KEYGT", &info->read_spec[FFESTP_readixKEYGT]);
4005 ffeste_subr_file_ ("KEYID", &info->read_spec[FFESTP_readixKEYID]);
4006 ffeste_subr_file_ ("NULLS", &info->read_spec[FFESTP_readixNULLS]);
4007 ffeste_subr_file_ ("REC", &info->read_spec[FFESTP_readixREC]);
4008 ffeste_subr_file_ ("SIZE", &info->read_spec[FFESTP_readixSIZE]);
4009 fputs (") ", dmpout);
4010 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
4012 ffeste_emit_line_note_ ();
4022 /* First determine the start, per-item, and end run-time functions to
4023 call. The per-item function is picked by choosing an ffeste function
4024 to call to handle a given item; it knows how to generate a call to the
4025 appropriate run-time function, and is called an "I/O driver". */
4029 case FFESTV_formatNONE: /* no FMT= */
4030 ffeste_io_driver_ = ffeste_io_douio_;
4032 start = FFECOM_gfrtSRDUE, end = FFECOM_gfrtERDUE;
4035 start = FFECOM_gfrtSRIUE, end = FFECOM_gfrtERIUE;
4038 start = FFECOM_gfrtSRSUE, end = FFECOM_gfrtERSUE;
4041 case FFESTV_formatLABEL: /* FMT=10 */
4042 case FFESTV_formatCHAREXPR: /* FMT='(I10)' */
4043 case FFESTV_formatINTEXPR: /* FMT=I [after ASSIGN 10 TO I] */
4044 ffeste_io_driver_ = ffeste_io_dofio_;
4046 start = FFECOM_gfrtSRDFE, end = FFECOM_gfrtERDFE;
4049 start = FFECOM_gfrtSRIFE, end = FFECOM_gfrtERIFE;
4051 else if (unit == FFESTV_unitCHAREXPR)
4052 start = FFECOM_gfrtSRSFI, end = FFECOM_gfrtERSFI;
4054 start = FFECOM_gfrtSRSFE, end = FFECOM_gfrtERSFE;
4057 case FFESTV_formatASTERISK: /* FMT=* */
4058 ffeste_io_driver_ = ffeste_io_dolio_;
4059 if (unit == FFESTV_unitCHAREXPR)
4060 start = FFECOM_gfrtSRSLI, end = FFECOM_gfrtERSLI;
4062 start = FFECOM_gfrtSRSLE, end = FFECOM_gfrtERSLE;
4065 case FFESTV_formatNAMELIST: /* FMT=FOO or NML=FOO [NAMELIST
4067 ffeste_io_driver_ = NULL; /* No start or driver function. */
4068 start = FFECOM_gfrtSRSNE, end = FFECOM_gfrt;
4072 assert ("Weird stuff" == NULL);
4073 start = FFECOM_gfrt, end = FFECOM_gfrt;
4076 ffeste_io_endgfrt_ = end;
4078 #define specified(something) (info->read_spec[something].kw_or_val_present)
4080 iostat = specified (FFESTP_readixIOSTAT);
4081 errl = specified (FFESTP_readixERR);
4082 endl = specified (FFESTP_readixEND);
4086 ffeste_start_stmt_ ();
4090 /* Have ERR= specification. */
4093 = ffecom_lookup_label (info->read_spec[FFESTP_readixERR].u.label);
4097 /* Have both ERR= and END=. Need a temp label to handle both. */
4099 = ffecom_lookup_label (info->read_spec[FFESTP_readixEND].u.label);
4100 ffeste_io_abort_is_temp_ = TRUE;
4101 ffeste_io_abort_ = ffecom_temp_label ();
4105 /* Have ERR= but no END=. */
4106 ffeste_io_end_ = NULL_TREE;
4107 if ((ffeste_io_abort_is_temp_ = iostat))
4108 ffeste_io_abort_ = ffecom_temp_label ();
4110 ffeste_io_abort_ = ffeste_io_err_;
4115 /* No ERR= specification. */
4117 ffeste_io_err_ = NULL_TREE;
4120 /* Have END= but no ERR=. */
4122 = ffecom_lookup_label (info->read_spec[FFESTP_readixEND].u.label);
4123 if ((ffeste_io_abort_is_temp_ = iostat))
4124 ffeste_io_abort_ = ffecom_temp_label ();
4126 ffeste_io_abort_ = ffeste_io_end_;
4130 /* Have no ERR= or END=. */
4132 ffeste_io_end_ = NULL_TREE;
4133 if ((ffeste_io_abort_is_temp_ = iostat))
4134 ffeste_io_abort_ = ffecom_temp_label ();
4136 ffeste_io_abort_ = NULL_TREE;
4142 /* Have IOSTAT= specification. */
4144 ffeste_io_iostat_is_temp_ = FALSE;
4146 = ffecom_expr (info->read_spec[FFESTP_readixIOSTAT].u.expr);
4148 else if (ffeste_io_abort_ != NULL_TREE)
4150 /* Have no IOSTAT= but have ERR= and/or END=. */
4152 ffeste_io_iostat_is_temp_ = TRUE;
4154 = ffecom_make_tempvar ("read", ffecom_integer_type_node,
4155 FFETARGET_charactersizeNONE, -1);
4159 /* No IOSTAT=, ERR=, or END= specification. */
4161 ffeste_io_iostat_is_temp_ = FALSE;
4162 ffeste_io_iostat_ = NULL_TREE;
4165 /* Now prescan, then convert, all the arguments. */
4167 if (unit == FFESTV_unitCHAREXPR)
4168 cilist = ffeste_io_icilist_ (errl || iostat,
4169 info->read_spec[FFESTP_readixUNIT].u.expr,
4170 endl || iostat, format,
4171 &info->read_spec[FFESTP_readixFORMAT]);
4173 cilist = ffeste_io_cilist_ (errl || iostat, unit,
4174 info->read_spec[FFESTP_readixUNIT].u.expr,
4175 5, endl || iostat, format,
4176 &info->read_spec[FFESTP_readixFORMAT],
4178 info->read_spec[FFESTP_readixREC].u.expr);
4180 /* If there is no end function, then there are no item functions (i.e.
4181 it's a NAMELIST), and vice versa by the way. In this situation, don't
4182 generate the "if (iostat != 0) goto label;" if the label is temp abort
4183 label, since we're gonna fall through to there anyway. */
4185 ffeste_io_call_ (ffecom_call_gfrt (start, cilist, NULL_TREE),
4186 (! ffeste_io_abort_is_temp_) || (end != FFECOM_gfrt));
4193 /* READ statement -- I/O item. */
4196 ffeste_R909_item (ffebld expr, ffelexToken expr_token)
4198 ffeste_check_item_ ();
4200 #if FFECOM_targetCURRENT == FFECOM_targetFFE
4202 fputc (',', dmpout);
4203 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
4207 /* Strip parens off items such as in "READ *,(A)". This is really a bug
4208 in the user's code, but I've been told lots of code does this. */
4209 while (ffebld_op (expr) == FFEBLD_opPAREN)
4210 expr = ffebld_left (expr);
4212 if (ffebld_op (expr) == FFEBLD_opANY)
4215 if (ffebld_op (expr) == FFEBLD_opIMPDO)
4216 ffeste_io_impdo_ (expr, expr_token);
4219 ffeste_start_stmt_ ();
4221 ffecom_prepare_arg_ptr_to_expr (expr);
4223 ffecom_prepare_end ();
4225 ffeste_io_call_ ((*ffeste_io_driver_) (expr), TRUE);
4227 ffeste_end_stmt_ ();
4234 /* READ statement -- end. */
4237 ffeste_R909_finish ()
4239 ffeste_check_finish_ ();
4241 #if FFECOM_targetCURRENT == FFECOM_targetFFE
4242 fputc ('\n', dmpout);
4243 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
4245 /* Don't generate "if (iostat != 0) goto label;" if label is temp abort
4246 label, since we're gonna fall through to there anyway. */
4248 if (ffeste_io_endgfrt_ != FFECOM_gfrt)
4249 ffeste_io_call_ (ffecom_call_gfrt (ffeste_io_endgfrt_, NULL_TREE,
4251 ! ffeste_io_abort_is_temp_);
4253 /* If we've got a temp label, generate its code here and have it fan out
4254 to the END= or ERR= label as appropriate. */
4256 if (ffeste_io_abort_is_temp_)
4258 DECL_INITIAL (ffeste_io_abort_) = error_mark_node;
4260 expand_label (ffeste_io_abort_);
4262 /* "if (iostat<0) goto end_label;". */
4264 if ((ffeste_io_end_ != NULL_TREE)
4265 && (TREE_CODE (ffeste_io_end_) != ERROR_MARK))
4267 expand_start_cond (ffecom_truth_value
4268 (ffecom_2 (LT_EXPR, integer_type_node,
4270 ffecom_integer_zero_node)),
4272 expand_goto (ffeste_io_end_);
4276 /* "if (iostat>0) goto err_label;". */
4278 if ((ffeste_io_err_ != NULL_TREE)
4279 && (TREE_CODE (ffeste_io_err_) != ERROR_MARK))
4281 expand_start_cond (ffecom_truth_value
4282 (ffecom_2 (GT_EXPR, integer_type_node,
4284 ffecom_integer_zero_node)),
4286 expand_goto (ffeste_io_err_);
4291 ffeste_end_stmt_ ();
4297 /* WRITE statement -- start. */
4300 ffeste_R910_start (ffestpWriteStmt *info, ffestvUnit unit,
4301 ffestvFormat format, bool rec)
4303 ffeste_check_start_ ();
4305 #if FFECOM_targetCURRENT == FFECOM_targetFFE
4308 case FFESTV_formatNONE:
4310 fputs ("+ WRITE_ufdac (", dmpout);
4312 fputs ("+ WRITE_ufseq_or_idx (", dmpout);
4315 case FFESTV_formatLABEL:
4316 case FFESTV_formatCHAREXPR:
4317 case FFESTV_formatINTEXPR:
4319 fputs ("+ WRITE_fmdac (", dmpout);
4320 else if (unit == FFESTV_unitCHAREXPR)
4321 fputs ("+ WRITE_fmint (", dmpout);
4323 fputs ("+ WRITE_fmseq_or_idx (", dmpout);
4326 case FFESTV_formatASTERISK:
4327 if (unit == FFESTV_unitCHAREXPR)
4328 fputs ("+ WRITE_lsint (", dmpout);
4330 fputs ("+ WRITE_lsseq (", dmpout);
4333 case FFESTV_formatNAMELIST:
4334 fputs ("+ WRITE_nlseq (", dmpout);
4338 assert ("Unexpected kind of format item in R910 WRITE" == NULL);
4341 ffeste_subr_file_ ("UNIT", &info->write_spec[FFESTP_writeixUNIT]);
4342 ffeste_subr_file_ ("FORMAT", &info->write_spec[FFESTP_writeixFORMAT]);
4343 ffeste_subr_file_ ("ADVANCE", &info->write_spec[FFESTP_writeixADVANCE]);
4344 ffeste_subr_file_ ("EOR", &info->write_spec[FFESTP_writeixEOR]);
4345 ffeste_subr_file_ ("ERR", &info->write_spec[FFESTP_writeixERR]);
4346 ffeste_subr_file_ ("IOSTAT", &info->write_spec[FFESTP_writeixIOSTAT]);
4347 ffeste_subr_file_ ("REC", &info->write_spec[FFESTP_writeixREC]);
4348 fputs (") ", dmpout);
4349 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
4351 ffeste_emit_line_note_ ();
4360 /* First determine the start, per-item, and end run-time functions to
4361 call. The per-item function is picked by choosing an ffeste function
4362 to call to handle a given item; it knows how to generate a call to the
4363 appropriate run-time function, and is called an "I/O driver". */
4367 case FFESTV_formatNONE: /* no FMT= */
4368 ffeste_io_driver_ = ffeste_io_douio_;
4370 start = FFECOM_gfrtSWDUE, end = FFECOM_gfrtEWDUE;
4372 start = FFECOM_gfrtSWSUE, end = FFECOM_gfrtEWSUE;
4375 case FFESTV_formatLABEL: /* FMT=10 */
4376 case FFESTV_formatCHAREXPR: /* FMT='(I10)' */
4377 case FFESTV_formatINTEXPR: /* FMT=I [after ASSIGN 10 TO I] */
4378 ffeste_io_driver_ = ffeste_io_dofio_;
4380 start = FFECOM_gfrtSWDFE, end = FFECOM_gfrtEWDFE;
4381 else if (unit == FFESTV_unitCHAREXPR)
4382 start = FFECOM_gfrtSWSFI, end = FFECOM_gfrtEWSFI;
4384 start = FFECOM_gfrtSWSFE, end = FFECOM_gfrtEWSFE;
4387 case FFESTV_formatASTERISK: /* FMT=* */
4388 ffeste_io_driver_ = ffeste_io_dolio_;
4389 if (unit == FFESTV_unitCHAREXPR)
4390 start = FFECOM_gfrtSWSLI, end = FFECOM_gfrtEWSLI;
4392 start = FFECOM_gfrtSWSLE, end = FFECOM_gfrtEWSLE;
4395 case FFESTV_formatNAMELIST: /* FMT=FOO or NML=FOO [NAMELIST
4397 ffeste_io_driver_ = NULL; /* No start or driver function. */
4398 start = FFECOM_gfrtSWSNE, end = FFECOM_gfrt;
4402 assert ("Weird stuff" == NULL);
4403 start = FFECOM_gfrt, end = FFECOM_gfrt;
4406 ffeste_io_endgfrt_ = end;
4408 #define specified(something) (info->write_spec[something].kw_or_val_present)
4410 iostat = specified (FFESTP_writeixIOSTAT);
4411 errl = specified (FFESTP_writeixERR);
4415 ffeste_start_stmt_ ();
4417 ffeste_io_end_ = NULL_TREE;
4421 /* Have ERR= specification. */
4425 = ffecom_lookup_label
4426 (info->write_spec[FFESTP_writeixERR].u.label);
4427 ffeste_io_abort_is_temp_ = FALSE;
4431 /* No ERR= specification. */
4433 ffeste_io_err_ = NULL_TREE;
4435 if ((ffeste_io_abort_is_temp_ = iostat))
4436 ffeste_io_abort_ = ffecom_temp_label ();
4438 ffeste_io_abort_ = NULL_TREE;
4443 /* Have IOSTAT= specification. */
4445 ffeste_io_iostat_is_temp_ = FALSE;
4446 ffeste_io_iostat_ = ffecom_expr
4447 (info->write_spec[FFESTP_writeixIOSTAT].u.expr);
4449 else if (ffeste_io_abort_ != NULL_TREE)
4451 /* Have no IOSTAT= but have ERR=. */
4453 ffeste_io_iostat_is_temp_ = TRUE;
4455 = ffecom_make_tempvar ("write", ffecom_integer_type_node,
4456 FFETARGET_charactersizeNONE, -1);
4460 /* No IOSTAT= or ERR= specification. */
4462 ffeste_io_iostat_is_temp_ = FALSE;
4463 ffeste_io_iostat_ = NULL_TREE;
4466 /* Now prescan, then convert, all the arguments. */
4468 if (unit == FFESTV_unitCHAREXPR)
4469 cilist = ffeste_io_icilist_ (errl || iostat,
4470 info->write_spec[FFESTP_writeixUNIT].u.expr,
4472 &info->write_spec[FFESTP_writeixFORMAT]);
4474 cilist = ffeste_io_cilist_ (errl || iostat, unit,
4475 info->write_spec[FFESTP_writeixUNIT].u.expr,
4477 &info->write_spec[FFESTP_writeixFORMAT],
4479 info->write_spec[FFESTP_writeixREC].u.expr);
4481 /* If there is no end function, then there are no item functions (i.e.
4482 it's a NAMELIST), and vice versa by the way. In this situation, don't
4483 generate the "if (iostat != 0) goto label;" if the label is temp abort
4484 label, since we're gonna fall through to there anyway. */
4486 ffeste_io_call_ (ffecom_call_gfrt (start, cilist, NULL_TREE),
4487 (! ffeste_io_abort_is_temp_) || (end != FFECOM_gfrt));
4494 /* WRITE statement -- I/O item. */
4497 ffeste_R910_item (ffebld expr, ffelexToken expr_token)
4499 ffeste_check_item_ ();
4501 #if FFECOM_targetCURRENT == FFECOM_targetFFE
4503 fputc (',', dmpout);
4504 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
4508 if (ffebld_op (expr) == FFEBLD_opANY)
4511 if (ffebld_op (expr) == FFEBLD_opIMPDO)
4512 ffeste_io_impdo_ (expr, expr_token);
4515 ffeste_start_stmt_ ();
4517 ffecom_prepare_arg_ptr_to_expr (expr);
4519 ffecom_prepare_end ();
4521 ffeste_io_call_ ((*ffeste_io_driver_) (expr), TRUE);
4523 ffeste_end_stmt_ ();
4530 /* WRITE statement -- end. */
4533 ffeste_R910_finish ()
4535 ffeste_check_finish_ ();
4537 #if FFECOM_targetCURRENT == FFECOM_targetFFE
4538 fputc ('\n', dmpout);
4539 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
4541 /* Don't generate "if (iostat != 0) goto label;" if label is temp abort
4542 label, since we're gonna fall through to there anyway. */
4544 if (ffeste_io_endgfrt_ != FFECOM_gfrt)
4545 ffeste_io_call_ (ffecom_call_gfrt (ffeste_io_endgfrt_, NULL_TREE,
4547 ! ffeste_io_abort_is_temp_);
4549 /* If we've got a temp label, generate its code here. */
4551 if (ffeste_io_abort_is_temp_)
4553 DECL_INITIAL (ffeste_io_abort_) = error_mark_node;
4555 expand_label (ffeste_io_abort_);
4557 assert (ffeste_io_err_ == NULL_TREE);
4560 ffeste_end_stmt_ ();
4566 /* PRINT statement -- start. */
4569 ffeste_R911_start (ffestpPrintStmt *info, ffestvFormat format)
4571 ffeste_check_start_ ();
4573 #if FFECOM_targetCURRENT == FFECOM_targetFFE
4576 case FFESTV_formatLABEL:
4577 case FFESTV_formatCHAREXPR:
4578 case FFESTV_formatINTEXPR:
4579 fputs ("+ PRINT_fm ", dmpout);
4582 case FFESTV_formatASTERISK:
4583 fputs ("+ PRINT_ls ", dmpout);
4586 case FFESTV_formatNAMELIST:
4587 fputs ("+ PRINT_nl ", dmpout);
4591 assert ("Unexpected kind of format item in R911 PRINT" == NULL);
4593 ffeste_subr_file_ ("FORMAT", &info->print_spec[FFESTP_printixFORMAT]);
4594 fputc (' ', dmpout);
4595 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
4597 ffeste_emit_line_note_ ();
4604 /* First determine the start, per-item, and end run-time functions to
4605 call. The per-item function is picked by choosing an ffeste function
4606 to call to handle a given item; it knows how to generate a call to the
4607 appropriate run-time function, and is called an "I/O driver". */
4611 case FFESTV_formatLABEL: /* FMT=10 */
4612 case FFESTV_formatCHAREXPR: /* FMT='(I10)' */
4613 case FFESTV_formatINTEXPR: /* FMT=I [after ASSIGN 10 TO I] */
4614 ffeste_io_driver_ = ffeste_io_dofio_;
4615 start = FFECOM_gfrtSWSFE, end = FFECOM_gfrtEWSFE;
4618 case FFESTV_formatASTERISK: /* FMT=* */
4619 ffeste_io_driver_ = ffeste_io_dolio_;
4620 start = FFECOM_gfrtSWSLE, end = FFECOM_gfrtEWSLE;
4623 case FFESTV_formatNAMELIST: /* FMT=FOO or NML=FOO [NAMELIST
4625 ffeste_io_driver_ = NULL; /* No start or driver function. */
4626 start = FFECOM_gfrtSWSNE, end = FFECOM_gfrt;
4630 assert ("Weird stuff" == NULL);
4631 start = FFECOM_gfrt, end = FFECOM_gfrt;
4634 ffeste_io_endgfrt_ = end;
4636 ffeste_start_stmt_ ();
4638 ffeste_io_end_ = NULL_TREE;
4639 ffeste_io_err_ = NULL_TREE;
4640 ffeste_io_abort_ = NULL_TREE;
4641 ffeste_io_abort_is_temp_ = FALSE;
4642 ffeste_io_iostat_is_temp_ = FALSE;
4643 ffeste_io_iostat_ = NULL_TREE;
4645 /* Now prescan, then convert, all the arguments. */
4647 cilist = ffeste_io_cilist_ (FALSE, FFESTV_unitNONE, NULL, 6, FALSE, format,
4648 &info->print_spec[FFESTP_printixFORMAT], FALSE, NULL);
4650 /* If there is no end function, then there are no item functions (i.e.
4651 it's a NAMELIST), and vice versa by the way. In this situation, don't
4652 generate the "if (iostat != 0) goto label;" if the label is temp abort
4653 label, since we're gonna fall through to there anyway. */
4655 ffeste_io_call_ (ffecom_call_gfrt (start, cilist, NULL_TREE),
4656 (! ffeste_io_abort_is_temp_) || (end != FFECOM_gfrt));
4663 /* PRINT statement -- I/O item. */
4666 ffeste_R911_item (ffebld expr, ffelexToken expr_token)
4668 ffeste_check_item_ ();
4670 #if FFECOM_targetCURRENT == FFECOM_targetFFE
4672 fputc (',', dmpout);
4673 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
4677 if (ffebld_op (expr) == FFEBLD_opANY)
4680 if (ffebld_op (expr) == FFEBLD_opIMPDO)
4681 ffeste_io_impdo_ (expr, expr_token);
4684 ffeste_start_stmt_ ();
4686 ffecom_prepare_arg_ptr_to_expr (expr);
4688 ffecom_prepare_end ();
4690 ffeste_io_call_ ((*ffeste_io_driver_) (expr), TRUE);
4692 ffeste_end_stmt_ ();
4699 /* PRINT statement -- end. */
4702 ffeste_R911_finish ()
4704 ffeste_check_finish_ ();
4706 #if FFECOM_targetCURRENT == FFECOM_targetFFE
4707 fputc ('\n', dmpout);
4708 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
4710 if (ffeste_io_endgfrt_ != FFECOM_gfrt)
4711 ffeste_io_call_ (ffecom_call_gfrt (ffeste_io_endgfrt_, NULL_TREE,
4715 ffeste_end_stmt_ ();
4721 /* BACKSPACE statement. */
4724 ffeste_R919 (ffestpBeruStmt *info)
4726 ffeste_check_simple_ ();
4728 #if FFECOM_targetCURRENT == FFECOM_targetFFE
4729 fputs ("+ BACKSPACE (", dmpout);
4730 ffeste_subr_file_ ("UNIT", &info->beru_spec[FFESTP_beruixUNIT]);
4731 ffeste_subr_file_ ("ERR", &info->beru_spec[FFESTP_beruixERR]);
4732 ffeste_subr_file_ ("IOSTAT", &info->beru_spec[FFESTP_beruixIOSTAT]);
4733 fputs (")\n", dmpout);
4734 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
4735 ffeste_subr_beru_ (info, FFECOM_gfrtFBACK);
4741 /* ENDFILE statement. */
4744 ffeste_R920 (ffestpBeruStmt *info)
4746 ffeste_check_simple_ ();
4748 #if FFECOM_targetCURRENT == FFECOM_targetFFE
4749 fputs ("+ ENDFILE (", dmpout);
4750 ffeste_subr_file_ ("UNIT", &info->beru_spec[FFESTP_beruixUNIT]);
4751 ffeste_subr_file_ ("ERR", &info->beru_spec[FFESTP_beruixERR]);
4752 ffeste_subr_file_ ("IOSTAT", &info->beru_spec[FFESTP_beruixIOSTAT]);
4753 fputs (")\n", dmpout);
4754 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
4755 ffeste_subr_beru_ (info, FFECOM_gfrtFEND);
4761 /* REWIND statement. */
4764 ffeste_R921 (ffestpBeruStmt *info)
4766 ffeste_check_simple_ ();
4768 #if FFECOM_targetCURRENT == FFECOM_targetFFE
4769 fputs ("+ REWIND (", dmpout);
4770 ffeste_subr_file_ ("UNIT", &info->beru_spec[FFESTP_beruixUNIT]);
4771 ffeste_subr_file_ ("ERR", &info->beru_spec[FFESTP_beruixERR]);
4772 ffeste_subr_file_ ("IOSTAT", &info->beru_spec[FFESTP_beruixIOSTAT]);
4773 fputs (")\n", dmpout);
4774 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
4775 ffeste_subr_beru_ (info, FFECOM_gfrtFREW);
4781 /* INQUIRE statement (non-IOLENGTH version). */
4784 ffeste_R923A (ffestpInquireStmt *info, bool by_file UNUSED)
4786 ffeste_check_simple_ ();
4788 #if FFECOM_targetCURRENT == FFECOM_targetFFE
4791 fputs ("+ INQUIRE_file (", dmpout);
4792 ffeste_subr_file_ ("FILE", &info->inquire_spec[FFESTP_inquireixFILE]);
4796 fputs ("+ INQUIRE_unit (", dmpout);
4797 ffeste_subr_file_ ("UNIT", &info->inquire_spec[FFESTP_inquireixUNIT]);
4799 ffeste_subr_file_ ("ACCESS", &info->inquire_spec[FFESTP_inquireixACCESS]);
4800 ffeste_subr_file_ ("ACTION", &info->inquire_spec[FFESTP_inquireixACTION]);
4801 ffeste_subr_file_ ("BLANK", &info->inquire_spec[FFESTP_inquireixBLANK]);
4802 ffeste_subr_file_ ("CARRIAGECONTROL", &info->inquire_spec[FFESTP_inquireixCARRIAGECONTROL]);
4803 ffeste_subr_file_ ("DEFAULTFILE", &info->inquire_spec[FFESTP_inquireixDEFAULTFILE]);
4804 ffeste_subr_file_ ("DELIM", &info->inquire_spec[FFESTP_inquireixDELIM]);
4805 ffeste_subr_file_ ("DIRECT", &info->inquire_spec[FFESTP_inquireixDIRECT]);
4806 ffeste_subr_file_ ("ERR", &info->inquire_spec[FFESTP_inquireixERR]);
4807 ffeste_subr_file_ ("EXIST", &info->inquire_spec[FFESTP_inquireixEXIST]);
4808 ffeste_subr_file_ ("FORM", &info->inquire_spec[FFESTP_inquireixFORM]);
4809 ffeste_subr_file_ ("FORMATTED", &info->inquire_spec[FFESTP_inquireixFORMATTED]);
4810 ffeste_subr_file_ ("IOSTAT", &info->inquire_spec[FFESTP_inquireixIOSTAT]);
4811 ffeste_subr_file_ ("KEYED", &info->inquire_spec[FFESTP_inquireixKEYED]);
4812 ffeste_subr_file_ ("NAME", &info->inquire_spec[FFESTP_inquireixNAME]);
4813 ffeste_subr_file_ ("NAMED", &info->inquire_spec[FFESTP_inquireixNAMED]);
4814 ffeste_subr_file_ ("NEXTREC", &info->inquire_spec[FFESTP_inquireixNEXTREC]);
4815 ffeste_subr_file_ ("NUMBER", &info->inquire_spec[FFESTP_inquireixNUMBER]);
4816 ffeste_subr_file_ ("OPENED", &info->inquire_spec[FFESTP_inquireixOPENED]);
4817 ffeste_subr_file_ ("ORGANIZATION", &info->inquire_spec[FFESTP_inquireixORGANIZATION]);
4818 ffeste_subr_file_ ("PAD", &info->inquire_spec[FFESTP_inquireixPAD]);
4819 ffeste_subr_file_ ("POSITION", &info->inquire_spec[FFESTP_inquireixPOSITION]);
4820 ffeste_subr_file_ ("READ", &info->inquire_spec[FFESTP_inquireixREAD]);
4821 ffeste_subr_file_ ("READWRITE", &info->inquire_spec[FFESTP_inquireixREADWRITE]);
4822 ffeste_subr_file_ ("RECL", &info->inquire_spec[FFESTP_inquireixRECL]);
4823 ffeste_subr_file_ ("RECORDTYPE", &info->inquire_spec[FFESTP_inquireixRECORDTYPE]);
4824 ffeste_subr_file_ ("SEQUENTIAL", &info->inquire_spec[FFESTP_inquireixSEQUENTIAL]);
4825 ffeste_subr_file_ ("UNFORMATTED", &info->inquire_spec[FFESTP_inquireixUNFORMATTED]);
4826 ffeste_subr_file_ ("WRITE", &info->inquire_spec[FFESTP_inquireixWRITE]);
4827 fputs (")\n", dmpout);
4828 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
4834 ffeste_emit_line_note_ ();
4836 #define specified(something) (info->inquire_spec[something].kw_or_val_present)
4838 iostat = specified (FFESTP_inquireixIOSTAT);
4839 errl = specified (FFESTP_inquireixERR);
4843 ffeste_start_stmt_ ();
4849 = ffecom_lookup_label
4850 (info->inquire_spec[FFESTP_inquireixERR].u.label);
4851 ffeste_io_abort_is_temp_ = FALSE;
4855 ffeste_io_err_ = NULL_TREE;
4857 if ((ffeste_io_abort_is_temp_ = iostat))
4858 ffeste_io_abort_ = ffecom_temp_label ();
4860 ffeste_io_abort_ = NULL_TREE;
4865 /* Have IOSTAT= specification. */
4867 ffeste_io_iostat_is_temp_ = FALSE;
4868 ffeste_io_iostat_ = ffecom_expr
4869 (info->inquire_spec[FFESTP_inquireixIOSTAT].u.expr);
4871 else if (ffeste_io_abort_ != NULL_TREE)
4873 /* Have no IOSTAT= but have ERR=. */
4875 ffeste_io_iostat_is_temp_ = TRUE;
4877 = ffecom_make_tempvar ("inquire", ffecom_integer_type_node,
4878 FFETARGET_charactersizeNONE, -1);
4882 /* No IOSTAT= or ERR= specification. */
4884 ffeste_io_iostat_is_temp_ = FALSE;
4885 ffeste_io_iostat_ = NULL_TREE;
4888 /* Now prescan, then convert, all the arguments. */
4891 = ffeste_io_inlist_ (errl || iostat,
4892 &info->inquire_spec[FFESTP_inquireixUNIT],
4893 &info->inquire_spec[FFESTP_inquireixFILE],
4894 &info->inquire_spec[FFESTP_inquireixEXIST],
4895 &info->inquire_spec[FFESTP_inquireixOPENED],
4896 &info->inquire_spec[FFESTP_inquireixNUMBER],
4897 &info->inquire_spec[FFESTP_inquireixNAMED],
4898 &info->inquire_spec[FFESTP_inquireixNAME],
4899 &info->inquire_spec[FFESTP_inquireixACCESS],
4900 &info->inquire_spec[FFESTP_inquireixSEQUENTIAL],
4901 &info->inquire_spec[FFESTP_inquireixDIRECT],
4902 &info->inquire_spec[FFESTP_inquireixFORM],
4903 &info->inquire_spec[FFESTP_inquireixFORMATTED],
4904 &info->inquire_spec[FFESTP_inquireixUNFORMATTED],
4905 &info->inquire_spec[FFESTP_inquireixRECL],
4906 &info->inquire_spec[FFESTP_inquireixNEXTREC],
4907 &info->inquire_spec[FFESTP_inquireixBLANK]);
4909 /* Don't generate "if (iostat != 0) goto label;" if label is temp abort
4910 label, since we're gonna fall through to there anyway. */
4912 ffeste_io_call_ (ffecom_call_gfrt (FFECOM_gfrtFINQU, args, NULL_TREE),
4913 ! ffeste_io_abort_is_temp_);
4915 /* If we've got a temp label, generate its code here. */
4917 if (ffeste_io_abort_is_temp_)
4919 DECL_INITIAL (ffeste_io_abort_) = error_mark_node;
4921 expand_label (ffeste_io_abort_);
4923 assert (ffeste_io_err_ == NULL_TREE);
4926 ffeste_end_stmt_ ();
4933 /* INQUIRE(IOLENGTH=expr) statement -- start. */
4936 ffeste_R923B_start (ffestpInquireStmt *info UNUSED)
4938 ffeste_check_start_ ();
4940 #if FFECOM_targetCURRENT == FFECOM_targetFFE
4941 fputs ("+ INQUIRE (", dmpout);
4942 ffeste_subr_file_ ("IOLENGTH", &info->inquire_spec[FFESTP_inquireixIOLENGTH]);
4943 fputs (") ", dmpout);
4944 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
4945 assert ("INQUIRE(IOLENGTH=<var>) not implemented yet! ~~~" == NULL);
4947 ffeste_emit_line_note_ ();
4953 /* INQUIRE(IOLENGTH=expr) statement -- I/O item. */
4956 ffeste_R923B_item (ffebld expr UNUSED)
4958 ffeste_check_item_ ();
4960 #if FFECOM_targetCURRENT == FFECOM_targetFFE
4962 fputc (',', dmpout);
4963 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
4969 /* INQUIRE(IOLENGTH=expr) statement -- end. */
4972 ffeste_R923B_finish ()
4974 ffeste_check_finish_ ();
4976 #if FFECOM_targetCURRENT == FFECOM_targetFFE
4977 fputc ('\n', dmpout);
4978 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
4984 /* ffeste_R1001 -- FORMAT statement
4986 ffeste_R1001(format_list); */
4989 ffeste_R1001 (ffests s)
4991 ffeste_check_simple_ ();
4993 #if FFECOM_targetCURRENT == FFECOM_targetFFE
4994 fprintf (dmpout, "$ FORMAT %.*s\n", (int) ffests_length (s), ffests_text (s));
4995 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5002 assert (ffeste_label_formatdef_ != NULL);
5004 ffeste_emit_line_note_ ();
5006 t = build_string (ffests_length (s), ffests_text (s));
5009 = build_type_variant (build_array_type
5011 build_range_type (integer_type_node,
5013 build_int_2 (ffests_length (s),
5016 TREE_CONSTANT (t) = 1;
5017 TREE_STATIC (t) = 1;
5019 push_obstacks_nochange ();
5020 end_temporary_allocation ();
5022 var = ffecom_lookup_label (ffeste_label_formatdef_);
5023 if ((var != NULL_TREE)
5024 && (TREE_CODE (var) == VAR_DECL))
5026 DECL_INITIAL (var) = t;
5027 maxindex = build_int_2 (ffests_length (s) - 1, 0);
5028 ttype = TREE_TYPE (var);
5029 TYPE_DOMAIN (ttype) = build_range_type (integer_type_node,
5032 if (!TREE_TYPE (maxindex))
5033 TREE_TYPE (maxindex) = TYPE_DOMAIN (ttype);
5034 layout_type (ttype);
5035 rest_of_decl_compilation (var, NULL, 1, 0);
5037 expand_decl_init (var);
5040 resume_temporary_allocation ();
5043 ffeste_label_formatdef_ = NULL;
5055 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5056 fputs ("+ END_PROGRAM\n", dmpout);
5057 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5063 /* END BLOCK DATA. */
5068 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5069 fputs ("* END_BLOCK_DATA\n", dmpout);
5070 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5076 /* CALL statement. */
5079 ffeste_R1212 (ffebld expr)
5081 ffeste_check_simple_ ();
5083 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5084 fputs ("+ CALL ", dmpout);
5086 fputc ('\n', dmpout);
5087 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5089 ffebld args = ffebld_right (expr);
5091 ffebld labels = NULL; /* First in list of LABTERs. */
5092 ffebld prevlabels = NULL;
5093 ffebld prevargs = NULL;
5095 ffeste_emit_line_note_ ();
5097 /* Here we split the list at ffebld_right(expr) into two lists: one at
5098 ffebld_right(expr) consisting of all items that are not LABTERs, the
5099 other at labels consisting of all items that are LABTERs. Then, if
5100 the latter list is NULL, we have an ordinary call, else we have a call
5101 with alternate returns. */
5103 for (args = ffebld_right (expr); args != NULL; args = ffebld_trail (args))
5105 if (((arg = ffebld_head (args)) == NULL)
5106 || (ffebld_op (arg) != FFEBLD_opLABTER))
5108 if (prevargs == NULL)
5111 ffebld_set_right (expr, args);
5115 ffebld_set_trail (prevargs, args);
5121 if (prevlabels == NULL)
5123 prevlabels = labels = args;
5127 ffebld_set_trail (prevlabels, args);
5132 if (prevlabels == NULL)
5135 ffebld_set_trail (prevlabels, NULL);
5136 if (prevargs == NULL)
5137 ffebld_set_right (expr, NULL);
5139 ffebld_set_trail (prevargs, NULL);
5141 ffeste_start_stmt_ ();
5143 /* No temporaries are actually needed at this level, but we go
5144 through the motions anyway, just to be sure in case they do
5145 get made. Temporaries needed for arguments should be in the
5146 scopes of inner blocks, and if clean-up actions are supported,
5147 such as CALL-ing an intrinsic that writes to an argument of one
5148 type when a variable of a different type is provided (requiring
5149 assignment to the variable from a temporary after the library
5150 routine returns), the clean-up must be done by the expression
5151 evaluator, generally, to handle alternate returns (which we hope
5152 won't ever be supported by intrinsics, but might be a similar
5153 issue, such as CALL-ing an F90-style subroutine with an INTERFACE
5154 block). That implies the expression evaluator will have to
5155 recognize the need for its own temporary anyway, meaning it'll
5156 construct a block within the one constructed here. */
5158 ffecom_prepare_expr (expr);
5160 ffecom_prepare_end ();
5163 expand_expr_stmt (ffecom_expr (expr));
5174 texpr = ffecom_expr (expr);
5175 expand_start_case (0, texpr, TREE_TYPE (texpr), "CALL statement");
5177 for (caseno = 1, label = labels;
5179 ++caseno, label = ffebld_trail (label))
5181 value = build_int_2 (caseno, 0);
5182 tlabel = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
5184 pushok = pushcase (value, convert, tlabel, &duplicate);
5185 assert (pushok == 0);
5188 = ffecom_lookup_label (ffebld_labter (ffebld_head (label)));
5189 if ((tlabel == NULL_TREE)
5190 || (TREE_CODE (tlabel) == ERROR_MARK))
5192 TREE_USED (tlabel) = 1;
5193 expand_goto (tlabel);
5196 expand_end_case (texpr);
5199 ffeste_end_stmt_ ();
5211 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5212 fputs ("+ END_FUNCTION\n", dmpout);
5213 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5219 /* END SUBROUTINE. */
5224 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5225 fprintf (dmpout, "+ END_SUBROUTINE\n");
5226 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5232 /* ENTRY statement. */
5235 ffeste_R1226 (ffesymbol entry)
5237 ffeste_check_simple_ ();
5239 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5240 fprintf (dmpout, "+ ENTRY %s", ffesymbol_text (entry));
5241 if (ffesymbol_dummyargs (entry) != NULL)
5245 fputc ('(', dmpout);
5246 for (argh = ffesymbol_dummyargs (entry);
5248 argh = ffebld_trail (argh))
5250 assert (ffebld_head (argh) != NULL);
5251 switch (ffebld_op (ffebld_head (argh)))
5253 case FFEBLD_opSYMTER:
5254 fputs (ffesymbol_text (ffebld_symter (ffebld_head (argh))),
5259 fputc ('*', dmpout);
5263 fputc ('?', dmpout);
5264 ffebld_dump (ffebld_head (argh));
5265 fputc ('?', dmpout);
5268 if (ffebld_trail (argh) != NULL)
5269 fputc (',', dmpout);
5271 fputc (')', dmpout);
5273 fputc ('\n', dmpout);
5274 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5276 tree label = ffesymbol_hook (entry).length_tree;
5278 ffeste_emit_line_note_ ();
5280 if (label == error_mark_node)
5283 DECL_INITIAL (label) = error_mark_node;
5285 expand_label (label);
5292 /* RETURN statement. */
5295 ffeste_R1227 (ffestw block UNUSED, ffebld expr)
5297 ffeste_check_simple_ ();
5299 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5302 fputs ("+ RETURN\n", dmpout);
5306 fputs ("+ RETURN_alternate ", dmpout);
5308 fputc ('\n', dmpout);
5310 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5314 ffeste_emit_line_note_ ();
5316 ffeste_start_stmt_ ();
5318 ffecom_prepare_return_expr (expr);
5320 ffecom_prepare_end ();
5322 rtn = ffecom_return_expr (expr);
5324 if ((rtn == NULL_TREE)
5325 || (rtn == error_mark_node))
5326 expand_null_return ();
5329 tree result = DECL_RESULT (current_function_decl);
5331 if ((result != error_mark_node)
5332 && (TREE_TYPE (result) != error_mark_node))
5333 expand_return (ffecom_modify (NULL_TREE,
5335 convert (TREE_TYPE (result),
5338 expand_null_return ();
5341 ffeste_end_stmt_ ();
5348 /* REWRITE statement -- start. */
5352 ffeste_V018_start (ffestpRewriteStmt *info, ffestvFormat format)
5354 ffeste_check_start_ ();
5356 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5359 case FFESTV_formatNONE:
5360 fputs ("+ REWRITE_uf (", dmpout);
5363 case FFESTV_formatLABEL:
5364 case FFESTV_formatCHAREXPR:
5365 case FFESTV_formatINTEXPR:
5366 fputs ("+ REWRITE_fm (", dmpout);
5370 assert ("Unexpected kind of format item in V018 REWRITE" == NULL);
5372 ffeste_subr_file_ ("UNIT", &info->rewrite_spec[FFESTP_rewriteixUNIT]);
5373 ffeste_subr_file_ ("FMT", &info->rewrite_spec[FFESTP_rewriteixFMT]);
5374 ffeste_subr_file_ ("ERR", &info->rewrite_spec[FFESTP_rewriteixERR]);
5375 ffeste_subr_file_ ("IOSTAT", &info->rewrite_spec[FFESTP_rewriteixIOSTAT]);
5376 fputs (") ", dmpout);
5377 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5383 /* REWRITE statement -- I/O item. */
5386 ffeste_V018_item (ffebld expr)
5388 ffeste_check_item_ ();
5390 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5392 fputc (',', dmpout);
5393 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5399 /* REWRITE statement -- end. */
5402 ffeste_V018_finish ()
5404 ffeste_check_finish_ ();
5406 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5407 fputc ('\n', dmpout);
5408 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5414 /* ACCEPT statement -- start. */
5417 ffeste_V019_start (ffestpAcceptStmt *info, ffestvFormat format)
5419 ffeste_check_start_ ();
5421 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5424 case FFESTV_formatLABEL:
5425 case FFESTV_formatCHAREXPR:
5426 case FFESTV_formatINTEXPR:
5427 fputs ("+ ACCEPT_fm ", dmpout);
5430 case FFESTV_formatASTERISK:
5431 fputs ("+ ACCEPT_ls ", dmpout);
5434 case FFESTV_formatNAMELIST:
5435 fputs ("+ ACCEPT_nl ", dmpout);
5439 assert ("Unexpected kind of format item in V019 ACCEPT" == NULL);
5441 ffeste_subr_file_ ("FORMAT", &info->accept_spec[FFESTP_acceptixFORMAT]);
5442 fputc (' ', dmpout);
5443 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5449 /* ACCEPT statement -- I/O item. */
5452 ffeste_V019_item (ffebld expr)
5454 ffeste_check_item_ ();
5456 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5458 fputc (',', dmpout);
5459 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5465 /* ACCEPT statement -- end. */
5468 ffeste_V019_finish ()
5470 ffeste_check_finish_ ();
5472 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5473 fputc ('\n', dmpout);
5474 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5481 /* TYPE statement -- start. */
5484 ffeste_V020_start (ffestpTypeStmt *info UNUSED,
5485 ffestvFormat format UNUSED)
5487 ffeste_check_start_ ();
5489 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5492 case FFESTV_formatLABEL:
5493 case FFESTV_formatCHAREXPR:
5494 case FFESTV_formatINTEXPR:
5495 fputs ("+ TYPE_fm ", dmpout);
5498 case FFESTV_formatASTERISK:
5499 fputs ("+ TYPE_ls ", dmpout);
5502 case FFESTV_formatNAMELIST:
5503 fputs ("* TYPE_nl ", dmpout);
5507 assert ("Unexpected kind of format item in V020 TYPE" == NULL);
5509 ffeste_subr_file_ ("FORMAT", &info->type_spec[FFESTP_typeixFORMAT]);
5510 fputc (' ', dmpout);
5511 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5517 /* TYPE statement -- I/O item. */
5520 ffeste_V020_item (ffebld expr UNUSED)
5522 ffeste_check_item_ ();
5524 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5526 fputc (',', dmpout);
5527 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5533 /* TYPE statement -- end. */
5536 ffeste_V020_finish ()
5538 ffeste_check_finish_ ();
5540 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5541 fputc ('\n', dmpout);
5542 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5548 /* DELETE statement. */
5552 ffeste_V021 (ffestpDeleteStmt *info)
5554 ffeste_check_simple_ ();
5556 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5557 fputs ("+ DELETE (", dmpout);
5558 ffeste_subr_file_ ("UNIT", &info->delete_spec[FFESTP_deleteixUNIT]);
5559 ffeste_subr_file_ ("REC", &info->delete_spec[FFESTP_deleteixREC]);
5560 ffeste_subr_file_ ("ERR", &info->delete_spec[FFESTP_deleteixERR]);
5561 ffeste_subr_file_ ("IOSTAT", &info->delete_spec[FFESTP_deleteixIOSTAT]);
5562 fputs (")\n", dmpout);
5563 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5569 /* UNLOCK statement. */
5572 ffeste_V022 (ffestpBeruStmt *info)
5574 ffeste_check_simple_ ();
5576 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5577 fputs ("+ UNLOCK (", dmpout);
5578 ffeste_subr_file_ ("UNIT", &info->beru_spec[FFESTP_beruixUNIT]);
5579 ffeste_subr_file_ ("ERR", &info->beru_spec[FFESTP_beruixERR]);
5580 ffeste_subr_file_ ("IOSTAT", &info->beru_spec[FFESTP_beruixIOSTAT]);
5581 fputs (")\n", dmpout);
5582 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5588 /* ENCODE statement -- start. */
5591 ffeste_V023_start (ffestpVxtcodeStmt *info)
5593 ffeste_check_start_ ();
5595 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5596 fputs ("+ ENCODE (", dmpout);
5597 ffeste_subr_file_ ("C", &info->vxtcode_spec[FFESTP_vxtcodeixC]);
5598 ffeste_subr_file_ ("F", &info->vxtcode_spec[FFESTP_vxtcodeixF]);
5599 ffeste_subr_file_ ("B", &info->vxtcode_spec[FFESTP_vxtcodeixB]);
5600 ffeste_subr_file_ ("ERR", &info->vxtcode_spec[FFESTP_vxtcodeixERR]);
5601 ffeste_subr_file_ ("IOSTAT", &info->vxtcode_spec[FFESTP_vxtcodeixIOSTAT]);
5602 fputs (") ", dmpout);
5603 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5609 /* ENCODE statement -- I/O item. */
5612 ffeste_V023_item (ffebld expr)
5614 ffeste_check_item_ ();
5616 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5618 fputc (',', dmpout);
5619 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5625 /* ENCODE statement -- end. */
5628 ffeste_V023_finish ()
5630 ffeste_check_finish_ ();
5632 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5633 fputc ('\n', dmpout);
5634 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5640 /* DECODE statement -- start. */
5643 ffeste_V024_start (ffestpVxtcodeStmt *info)
5645 ffeste_check_start_ ();
5647 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5648 fputs ("+ DECODE (", dmpout);
5649 ffeste_subr_file_ ("C", &info->vxtcode_spec[FFESTP_vxtcodeixC]);
5650 ffeste_subr_file_ ("F", &info->vxtcode_spec[FFESTP_vxtcodeixF]);
5651 ffeste_subr_file_ ("B", &info->vxtcode_spec[FFESTP_vxtcodeixB]);
5652 ffeste_subr_file_ ("ERR", &info->vxtcode_spec[FFESTP_vxtcodeixERR]);
5653 ffeste_subr_file_ ("IOSTAT", &info->vxtcode_spec[FFESTP_vxtcodeixIOSTAT]);
5654 fputs (") ", dmpout);
5655 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5661 /* DECODE statement -- I/O item. */
5664 ffeste_V024_item (ffebld expr)
5666 ffeste_check_item_ ();
5668 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5670 fputc (',', dmpout);
5671 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5677 /* DECODE statement -- end. */
5680 ffeste_V024_finish ()
5682 ffeste_check_finish_ ();
5684 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5685 fputc ('\n', dmpout);
5686 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5692 /* DEFINEFILE statement -- start. */
5695 ffeste_V025_start ()
5697 ffeste_check_start_ ();
5699 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5700 fputs ("+ DEFINE_FILE ", dmpout);
5701 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5707 /* DEFINE FILE statement -- item. */
5710 ffeste_V025_item (ffebld u, ffebld m, ffebld n, ffebld asv)
5712 ffeste_check_item_ ();
5714 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5716 fputc ('(', dmpout);
5718 fputc (',', dmpout);
5720 fputs (",U,", dmpout);
5722 fputs ("),", dmpout);
5723 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5729 /* DEFINE FILE statement -- end. */
5732 ffeste_V025_finish ()
5734 ffeste_check_finish_ ();
5736 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5737 fputc ('\n', dmpout);
5738 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5744 /* FIND statement. */
5747 ffeste_V026 (ffestpFindStmt *info)
5749 ffeste_check_simple_ ();
5751 #if FFECOM_targetCURRENT == FFECOM_targetFFE
5752 fputs ("+ FIND (", dmpout);
5753 ffeste_subr_file_ ("UNIT", &info->find_spec[FFESTP_findixUNIT]);
5754 ffeste_subr_file_ ("REC", &info->find_spec[FFESTP_findixREC]);
5755 ffeste_subr_file_ ("ERR", &info->find_spec[FFESTP_findixERR]);
5756 ffeste_subr_file_ ("IOSTAT", &info->find_spec[FFESTP_findixIOSTAT]);
5757 fputs (")\n", dmpout);
5758 #elif FFECOM_targetCURRENT == FFECOM_targetGCC
5766 #ifdef ENABLE_CHECKING
5768 ffeste_terminate_2 (void)
5770 assert (! ffeste_top_block_);