• Main Page
  • Modules
  • Data Types
  • Files

osprey/be/com/wn_fio.cxx

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2006, 2007. QLogic Corporation. All Rights Reserved.
00003  */
00004 /*
00005  * Copyright 2003, 2004, 2005, 2006 PathScale, Inc.  All Rights Reserved.
00006  */
00007 
00008 /*
00009 
00010   Copyright (C) 2000, 2001 Silicon Graphics, Inc.  All Rights Reserved.
00011 
00012   This program is free software; you can redistribute it and/or modify it
00013   under the terms of version 2 of the GNU General Public License as
00014   published by the Free Software Foundation.
00015 
00016   This program is distributed in the hope that it would be useful, but
00017   WITHOUT ANY WARRANTY; without even the implied warranty of
00018   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00019 
00020   Further, this software is distributed without any warranty that it is
00021   free of the rightful claim of any third person regarding infringement 
00022   or the like.  Any license provided herein, whether implied or 
00023   otherwise, applies only to this software file.  Patent licenses, if 
00024   any, provided herein do not apply to combinations of this program with 
00025   other software, or any other product whatsoever.  
00026 
00027   You should have received a copy of the GNU General Public License along
00028   with this program; if not, write the Free Software Foundation, Inc., 59
00029   Temple Place - Suite 330, Boston MA 02111-1307, USA.
00030 
00031   Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
00032   Mountain View, CA 94043, or:
00033 
00034   http://www.sgi.com
00035 
00036   For further information regarding this notice, see:
00037 
00038   http://oss.sgi.com/projects/GenInfo/NoticeExplan
00039 
00040 */
00041 
00042 
00043 
00044 #define __STDC_LIMIT_MACROS
00045 #include <stdint.h>
00046 #ifdef USE_PCH
00047 #include "be_com_pch.h"
00048 #endif /* USE_PCH */
00049 #pragma hdrstop
00050 #if defined(BUILD_OS_DARWIN)
00051 #include <limits.h>
00052 #else /* defined(BUILD_OS_DARWIN) */
00053 #include <values.h>
00054 #endif /* defined(BUILD_OS_DARWIN) */
00055 #include <isam.h>
00056 #include "defs.h"
00057 #include "strtab.h"
00058 #include "stab.h"
00059 #include "wn.h"
00060 #include "wn_util.h"
00061 #include "wio.h"
00062 #include "config.h"
00063 #include "targ_sim.h"
00064 #include "targ_const.h"
00065 #include "targ_const_private.h"
00066 #include "const.h"
00067 #include "flags.h"
00068 #include "wn_lower.h"
00069 #include "srcpos.h"
00070 #include "stblock.h"
00071 #include "be_symtab.h"
00072 #include <isam.h>
00073 #include <wn_fio.h>
00074 #include "opt_points_to.h"
00075 #include "fb_whirl.h"
00076 
00077 #define STACK_LENGTH 25
00078 #define DIM_OFFSET 56
00079 #define DIM_SZ 24
00080 
00081 #define GLOBAL_LEVEL 1
00082 #define HOST_LEVEL GLOBAL_LEVEL + 1
00083 #define INTERNAL_LEVEL HOST_LEVEL + 1
00084 
00085 
00086 /* for use with the implied-do loop nesting type */
00087 #define NO_NESTING  0
00088 #define NESTED_DOPE 1 /* items inside an implied-do entry .  These
00089         ** need to be turned into dope vector
00090         ** when appropriate */
00091 #define NESTED_ITEM 2 /* I/O list items inside a do loop generated
00092         ** for an implied-do loop */
00093 
00094 #define FIRST_CALL(x) (x & 2)
00095 #define LAST_CALL(x)  (x & 1)
00096 static OPCODE opc_lda;
00097 static OPCODE opc_const;
00098 static INT32  fcd_size;
00099 static ST *stack_st = NULL;
00100 static TY_IDX stack_ty = (TY_IDX) 0;
00101 static ST *cilist_st = NULL;
00102 static WN *cr_iostat1 = NULL;
00103 static WN *cr_iostat2 = NULL;
00104 static WN *copyout_block = NULL;
00105 #define MAX_NESTED_IMPL 50
00106 static ST *impl_idx[MAX_NESTED_IMPL];
00107 static INT32 num_impl;
00108 static INT32 first_last;
00109 
00110 
00111 typedef struct impdo_info IMPDO_INFO;
00112 struct impdo_info {
00113    ST *index;
00114    struct impdo_info *next;
00115 };
00116 struct marked_set {
00117    ST *st;
00118    struct marked_set *next;
00119 };
00120 typedef struct marked_set MARKED_SET;
00121 static MARKED_SET *marked_set;
00122 
00123 #define Impdo_index(x) ((x)->index)
00124 #define Impdo_next(x) ((x)->next)
00125 #define Marked_st(x) ((x)->st)
00126 #define Marked_next(x) ((x)->next)
00127 #define WNOPR(w) (WN_operator(w))
00128 static BOOL cwh_io_analyse_io_item(WN *tree, IMPDO_INFO *impdo_set, INT32 mode);
00129 static BOOL cwh_io_analyse_expr(WN *tree, IMPDO_INFO *impdo_set, INT32 mode);
00130 static BOOL cwh_io_analyse_arr(WN *tree, IMPDO_INFO *impdo_set, INT32 mode);
00131 static INT32 cwh_io_analyse_index_expr(WN *tree, IMPDO_INFO *impdo_set, INT32 mode);
00132 static void cwh_stab_free_auxst(void);
00133 static INT32 member(ST *st, IMPDO_INFO *impdo_set);
00134 static INT32 cwh_io_search_implied_do_index(WN *tree, IMPDO_INFO *impdo_set);
00135 static WN * Substitute_1_For_Impdo_Index_Val(WN *tree, IMPDO_INFO *impdo);
00136 static void cwh_io_unmark(void);
00137 static void cwh_io_add_st_to_marked_set(ST *st);
00138 static BOOL OPCODE_has_aux(const OPCODE opc);
00139 static INT32 local_sequence; /* to distinguish different structs with same name */
00140 static char seq_buff[10];
00141 static IOLIB current_io_library;
00142 
00143 
00144 #define MAX_DIM   7
00145 static TY_IDX dope_vector_ty[ MAX_DIM+1 ];
00146 
00147 typedef enum {
00148 
00149   FIOOPER_NONE = 0,
00150   FIOOPER_FIRST = 1,
00151 
00152     /* F77 external I/O operations. */
00153 
00154     FIO_EXT_READ_FORMAT_start   = 1,
00155     FIO_EXT_READ_UNFORMAT_start = 2,
00156     FIO_EXT_READ_LIST_start     = 3,
00157     FIO_EXT_READ_NAMELIST_start = 4,
00158 
00159     FIO_EXT_WRITE_FORMAT_start   = 5,
00160     FIO_EXT_WRITE_UNFORMAT_start = 6,
00161     FIO_EXT_WRITE_LIST_start     = 7,
00162     FIO_EXT_WRITE_NAMELIST_start = 8,
00163 
00164     FIO_EXT_REWRITE_FORMAT_start   = 9,
00165     FIO_EXT_REWRITE_UNFORMAT_start = 10,
00166     FIO_EXT_REWRITE_LIST_start     = 11,
00167 
00168     FIO_EXT_READ_FORMAT_end   = 12,
00169     FIO_EXT_READ_UNFORMAT_end = 13,
00170     FIO_EXT_READ_LIST_end     = 14,
00171 
00172     FIO_EXT_WRITE_FORMAT_end   = 15,
00173     FIO_EXT_WRITE_UNFORMAT_end = 16,
00174     FIO_EXT_WRITE_LIST_end     = 17,
00175 
00176     FIO_EXT_REWRITE_FORMAT_end   = 18,
00177     FIO_EXT_REWRITE_UNFORMAT_end = 19,
00178     FIO_EXT_REWRITE_LIST_end     = 20,
00179 
00180     /* F77 internal I/O operations. */
00181 
00182     FIO_INT_READ_FORMAT_start = 21,
00183     FIO_INT_READ_LIST_start   = 22,
00184 
00185     FIO_INT_WRITE_FORMAT_start = 23,
00186     FIO_INT_WRITE_LIST_start   = 24,
00187 
00188     FIO_INT_READ_FORMAT_end = 25,
00189     FIO_INT_READ_LIST_end   = 26,
00190 
00191     FIO_INT_WRITE_FORMAT_end = 27,
00192     FIO_INT_WRITE_LIST_end   = 28,
00193 
00194     /* F77 direct I/O operations. */
00195 
00196     FIO_DIR_READ_FORMAT_start   = 29,
00197     FIO_DIR_READ_UNFORMAT_start = 30,
00198 
00199     FIO_DIR_WRITE_FORMAT_start   = 31,
00200     FIO_DIR_WRITE_UNFORMAT_start = 32,
00201 
00202     FIO_DIR_READ_FORMAT_end   = 33,
00203     FIO_DIR_READ_UNFORMAT_end = 34,
00204 
00205     FIO_DIR_WRITE_FORMAT_end   = 35,
00206     FIO_DIR_WRITE_UNFORMAT_end = 36,
00207 
00208     /* F77 file transfer operations */
00209 
00210     FIO_FORMAT_ADDR4_item  = 37,
00211     FIO_FORMAT_ADDR8_item  = 38,
00212     FIO_FORMAT_CHAR_item   = 39,
00213     FIO_FORMAT_I1_item     = 40,
00214     FIO_FORMAT_I2_item     = 41,
00215     FIO_FORMAT_I4_item     = 42,
00216     FIO_FORMAT_I8_item     = 43,
00217     FIO_FORMAT_L1_item     = 44,
00218     FIO_FORMAT_L2_item     = 45,
00219     FIO_FORMAT_L4_item     = 46,
00220     FIO_FORMAT_L8_item     = 47,
00221     FIO_FORMAT_R4_item     = 48,
00222     FIO_FORMAT_R8_item     = 49,
00223     FIO_FORMAT_R16_item    = 50,
00224     FIO_FORMAT_C4_item     = 51,
00225     FIO_FORMAT_C8_item     = 52,
00226     FIO_FORMAT_C16_item    = 53,
00227 
00228     FIO_FORMAT_ADDR4_value = 54,
00229     FIO_FORMAT_ADDR8_value = 55,
00230     FIO_FORMAT_CHAR_value  = 56,
00231     FIO_FORMAT_I1_value    = 57,
00232     FIO_FORMAT_I2_value    = 58,
00233     FIO_FORMAT_I4_value    = 59,
00234     FIO_FORMAT_I8_value    = 60,
00235     FIO_FORMAT_L1_value    = 61,
00236     FIO_FORMAT_L2_value    = 62,
00237     FIO_FORMAT_L4_value    = 63,
00238     FIO_FORMAT_L8_value    = 64,
00239     FIO_FORMAT_R4_value    = 65,
00240     FIO_FORMAT_R8_value    = 66,
00241     FIO_FORMAT_R16_value   = 67,
00242     FIO_FORMAT_C4_value    = 68,
00243     FIO_FORMAT_C8_value    = 69,
00244     FIO_FORMAT_C16_value   = 70,
00245 
00246     FIO_UNFORMAT_ADDR4_item  = 71,
00247     FIO_UNFORMAT_ADDR8_item  = 72,
00248     FIO_UNFORMAT_CHAR_item   = 73,
00249     FIO_UNFORMAT_I1_item     = 74,
00250     FIO_UNFORMAT_I2_item     = 75,
00251     FIO_UNFORMAT_I4_item     = 76,
00252     FIO_UNFORMAT_I8_item     = 77,
00253     FIO_UNFORMAT_L1_item     = 78,
00254     FIO_UNFORMAT_L2_item     = 79,
00255     FIO_UNFORMAT_L4_item     = 80,
00256     FIO_UNFORMAT_L8_item     = 81,
00257     FIO_UNFORMAT_R4_item     = 82,
00258     FIO_UNFORMAT_R8_item     = 83,
00259     FIO_UNFORMAT_R16_item    = 84,
00260     FIO_UNFORMAT_C4_item     = 85,
00261     FIO_UNFORMAT_C8_item     = 86,
00262     FIO_UNFORMAT_C16_item    = 87,
00263 
00264     FIO_UNFORMAT_ADDR4_value = 88,
00265     FIO_UNFORMAT_ADDR8_value = 89,
00266     FIO_UNFORMAT_CHAR_value  = 90,
00267     FIO_UNFORMAT_I1_value    = 91,
00268     FIO_UNFORMAT_I2_value    = 92,
00269     FIO_UNFORMAT_I4_value    = 93,
00270     FIO_UNFORMAT_I8_value    = 94,
00271     FIO_UNFORMAT_L1_value    = 95,
00272     FIO_UNFORMAT_L2_value    = 96,
00273     FIO_UNFORMAT_L4_value    = 97,
00274     FIO_UNFORMAT_L8_value    = 98,
00275     FIO_UNFORMAT_R4_value    = 99,
00276     FIO_UNFORMAT_R8_value    = 100,
00277     FIO_UNFORMAT_R16_value   = 101,
00278     FIO_UNFORMAT_C4_value    = 102,
00279     FIO_UNFORMAT_C8_value    = 103,
00280     FIO_UNFORMAT_C16_value   = 104,
00281 
00282     FIO_LIST_ADDR4_item  = 105,
00283     FIO_LIST_ADDR8_item  = 106,
00284     FIO_LIST_CHAR_item   = 107,
00285     FIO_LIST_I1_item     = 108,
00286     FIO_LIST_I2_item     = 109,
00287     FIO_LIST_I4_item     = 110,
00288     FIO_LIST_I8_item     = 111,
00289     FIO_LIST_L1_item     = 112,
00290     FIO_LIST_L2_item     = 113,
00291     FIO_LIST_L4_item     = 114,
00292     FIO_LIST_L8_item     = 115,
00293     FIO_LIST_R4_item     = 116,
00294     FIO_LIST_R8_item     = 117,
00295     FIO_LIST_R16_item    = 118,
00296     FIO_LIST_C4_item     = 119,
00297     FIO_LIST_C8_item     = 120,
00298     FIO_LIST_C16_item    = 121,
00299 
00300     FIO_LIST_ADDR4_value = 122,
00301     FIO_LIST_ADDR8_value = 123,
00302     FIO_LIST_CHAR_value  = 124,
00303     FIO_LIST_I1_value    = 125,
00304     FIO_LIST_I2_value    = 126,
00305     FIO_LIST_I4_value    = 127,
00306     FIO_LIST_I8_value    = 128,
00307     FIO_LIST_L1_value    = 129,
00308     FIO_LIST_L2_value    = 130,
00309     FIO_LIST_L4_value    = 131,
00310     FIO_LIST_L8_value    = 132,
00311     FIO_LIST_R4_value    = 133,
00312     FIO_LIST_R8_value    = 134,
00313     FIO_LIST_R16_value   = 135,
00314     FIO_LIST_C4_value    = 136,
00315     FIO_LIST_C8_value    = 137,
00316     FIO_LIST_C16_value   = 138,
00317 
00318     /* F77 other I/O operations. */
00319 
00320     FIO_BACKSPACE = 139,
00321     FIO_CLOSE     = 140,
00322     FIO_DELETE    = 141,
00323     FIO_ENDFILE   = 142,
00324     FIO_FIND      = 143,
00325     FIO_INQUIRE   = 144,
00326     FIO_OPEN      = 145,
00327     FIO_REWIND    = 146,
00328     FIO_UNLOCK    = 147,
00329     FIO_DEFINEFILE = 148,
00330 
00331     /* CRAY Library IO Operations */
00332     FIO_CR_READ_UNFORMATTED = 149,
00333     FIO_CR_WRITE_UNFORMATTED = 150,
00334     FIO_CR_READ_FORMATTED = 151,
00335     FIO_CR_WRITE_FORMATTED = 152,
00336     FIO_CR_READ_NAMELIST = 153,
00337     FIO_CR_WRITE_NAMELIST = 154,
00338     FIO_INQLENGTH = 155,
00339     FIO_CR_OPEN = 156,
00340     FIO_CR_CLOSE = 157,
00341     FIO_CR_ENDFILE = 158,
00342     FIO_CR_REWIND = 159,
00343     FIO_CR_INQUIRE = 160,
00344     FIO_CR_BACKSPACE = 161,
00345     FIO_CR_BUFFERIN = 162,
00346     FIO_CR_BUFFEROUT = 163,
00347 
00348   FIOOPER_LAST = 164
00349 
00350 } FIOOPER;
00351 
00352 typedef enum {
00353 
00354   FIOITEMTYPE_NONE = 0,
00355   FIOITEMTYPE_FIRST = 1,
00356 
00357     FIT_ADDRESS4  = 1,
00358     FIT_ADDRESS8  = 2,
00359     FIT_CHARACTER = 3,
00360     FIT_INTEGER1  = 4,
00361     FIT_INTEGER2  = 5,
00362     FIT_INTEGER4  = 6,
00363     FIT_INTEGER8  = 7,
00364     FIT_LOGICAL1  = 8,
00365     FIT_LOGICAL2  = 9,
00366     FIT_LOGICAL4  = 10,
00367     FIT_LOGICAL8  = 11,
00368     FIT_REAL4     = 12,
00369     FIT_REAL8     = 13,
00370     FIT_REAL16    = 14,
00371     FIT_COMPLEX4  = 15,
00372     FIT_COMPLEX8  = 16,
00373     FIT_COMPLEX16 = 17,
00374     FIT_RECORD    = 18,
00375 
00376   FIOITEMTYPE_LAST = 18
00377 
00378 } FIOITEMTYPE;
00379 
00380 typedef enum {
00381 
00382   FIOFORMATTYPE_NONE = 0,
00383   FIOFORMATTYPE_FIRST = 1,
00384 
00385     FFT_FORMAT   = 1,
00386     FFT_UNFORMAT = 2,
00387     FFT_LIST     = 3,
00388 
00389   FIOFORMATTYPE_LAST = 3
00390 
00391 } FIOFORMATTYPE;
00392 
00393 typedef enum {
00394 
00395   FIOSTRUCTID_NONE = 0,
00396   FIOSTRUCTID_FIRST = 1,
00397 
00398     FID_CILIST = 1,
00399     FID_ICILIST = 2,
00400     FID_OLIST = 3,
00401     FID_FLIST = 4,
00402     FID_INLIST = 5,
00403     FID_ALIST = 6,
00404     FID_CLLIST = 7,
00405     FID_KEYSPEC = 8,
00406 
00407     FID_CRAY_CLIST = 9,
00408     FID_CRAY_FCD = 10,
00409     FID_CRAY_IOLIST = 11,
00410     FID_CRAY_OPENLIST = 12,
00411     FID_CRAY_CLOSELIST = 13,
00412     FID_CRAY_INQLIST = 14,
00413     FID_CRAY_DOPEVEC = 15,
00414     FID_IOSCALAR_ENTRY = 16,
00415     FID_IOARRAY_ENTRY = 17,
00416     FID_IOIMPLIEDDO_ENTRY = 18,
00417 
00418   FIOSTRUCTID_LAST = 18
00419 
00420 } FIOSTRUCTID;
00421 
00422 #define FIM_EXIST 0
00423 #define FIM_OPENED 2
00424 #define FIM_NUMBER 4
00425 #define FIM_NAMED 6
00426 #define FIM_RECL 8
00427 #define FIM_NEXTREC 10
00428 #define FIM_ASSOCIATEVARIABLE 12
00429 
00430 typedef enum {
00431 
00432   FIOSTRUCT_NONE = 0,
00433   FIOSTRUCT_FIRST = 1,
00434 
00435     /* F77 cilist structure fields. */
00436 
00437     FSC_CIERR = 1,
00438     FSC_CIUNIT = 2,
00439     FSC_CIEND = 3,
00440     FSC_CIFMT = 4,
00441     FSC_CIREC = 5,
00442     FSC_CIMATCH = 6,
00443     FSC_CIKEYTYPE = 7,
00444     FSC_CIKEYVAL = 8,
00445     FSC_CIKEYID = 9,
00446     FSC_CINML = 10,
00447     FSC_CIKEYVALLEN = 11,
00448     FSC_CIADVANCE = 12,
00449     FSC_CIADVANCELEN = 13,
00450     FSC_CIEOR = 14,
00451     FSC_CISIZE = 15,
00452     FSC_CIVFMT = 16,
00453     FSC_CIVFMTFP = 17,
00454 
00455     /* F77 icilist structure fields. */
00456 
00457     FSI_ICIERR = 18,
00458     FSI_ICIUNIT = 19,
00459     FSI_ICIEND = 20,
00460     FSI_ICIFMT = 21,
00461     FSI_ICIRLEN = 22,
00462     FSI_ICIRNUM = 23,
00463     FSI_ICIVFMT = 24,
00464     FSI_ICIVFMTFP = 25,
00465 
00466     /* F77 olist structure fields. */
00467 
00468     FSO_OERR = 26,
00469     FSO_OUNIT = 27,
00470     FSO_OFNM = 28,
00471     FSO_OFNMLEN = 29,
00472     FSO_OSTA = 30,
00473     FSO_OACC = 31,
00474     FSO_OFM = 32,
00475     FSO_ORL = 33,
00476     FSO_OBLNK = 34,
00477     FSO_OCC = 35,
00478     FSO_OORG = 36,
00479     FSO_OSHARED = 37,
00480     FSO_OREADONLY = 38,
00481     FSO_ONKEYS = 39,
00482     FSO_OKEYS = 40,
00483     FSO_OASSOCV = 41,
00484     FSO_OMAXREC = 42,
00485     FSO_ODFNM = 43,
00486     FSO_ODFNMLEN = 44,
00487     FSO_ODISP = 45,
00488     FSO_ORECTYPE = 46,
00489     FSO_OCONV = 47,
00490     FSO_OCONVLEN = 48,
00491     FSO_OBUFFSIZE = 49,
00492     FSO_ODIRECT = 50,
00493     FSO_OACTION = 51,
00494     FSO_OACTIONLEN = 52,
00495     FSO_ODELIM = 53,
00496     FSO_ODELIMLEN = 54,
00497     FSO_OPAD = 55,
00498     FSO_OPADLEN = 56,
00499     FSO_OPOSITION = 57,
00500     FSO_OPOSITIONLEN = 58,
00501 
00502     /* F77 flist structure fields. */
00503 
00504     FSF_FERR = 59,
00505     FSF_FUNIT = 60,
00506     FSF_FREC = 61,
00507 
00508     /* F77 inlist structure fields. */
00509 
00510     FSN_INERR = 62,
00511     FSN_INUNIT = 63,
00512     FSN_INFILE = 64,
00513     FSN_INFILEN = 65,
00514     FSN_INEX = 66,
00515     FSN_INOPEN = 67,
00516     FSN_INNUM = 68,
00517     FSN_INNAMED = 69,
00518     FSN_INNAME = 70,
00519     FSN_INNAMLEN = 71,
00520     FSN_INACC = 72,
00521     FSN_INACCLEN = 73,
00522     FSN_INSEQ = 74,
00523     FSN_INSEQLEN = 75,
00524     FSN_INDIR = 76,
00525     FSN_INDIRLEN = 77,
00526     FSN_INFMT = 78,
00527     FSN_INFMTLEN = 79,
00528     FSN_INFORM = 80,
00529     FSN_INFORMLEN = 81,
00530     FSN_INUNF = 82,
00531     FSN_INUNFLEN = 83,
00532     FSN_INRECL = 84,
00533     FSN_INNREC = 85,
00534     FSN_INBLANK = 86,
00535     FSN_INBLANKLEN = 87,
00536     FSN_INDEFAULTFILE = 88,
00537     FSN_INDEFAULTFILELEN = 89,
00538     FSN_INCC = 90,
00539     FSN_INCCLEN = 91,
00540     FSN_INKEYED = 92,
00541     FSN_INKEYEDLEN = 93,
00542     FSN_INORG = 94,
00543     FSN_INORGLEN = 95,
00544     FSN_INRECORDTYPE = 96,
00545     FSN_INRECORDTYPELEN = 97,
00546     FSN_INCONV = 98,
00547     FSN_INCONVLEN = 99,
00548     FSN_INBUFFSIZE = 100,
00549     FSN_INACTION = 101,
00550     FSN_INACTIONLEN = 102,
00551     FSN_INDELIM = 103,
00552     FSN_INDELIMLEN = 104,
00553     FSN_INPAD = 105,
00554     FSN_INPADLEN = 106,
00555     FSN_INPOSITION = 107,
00556     FSN_INPOSITIONLEN = 108,
00557     FSN_INREAD = 109,
00558     FSN_INREADLEN = 110,
00559     FSN_INREADWRITE = 111,
00560     FSN_INREADWRITELEN = 112,
00561     FSN_INWRITE = 113,
00562     FSN_INWRITELEN = 114,
00563 
00564     /* F77 alist structure fields. */
00565 
00566     FSA_AERR = 115,
00567     FSA_AUNIT = 116,
00568 
00569     /* F77 cllist structure fields. */
00570 
00571     FSL_CLERR = 117,
00572     FSL_CLUNIT = 118,
00573     FSL_CLSTA = 119,
00574 
00575     /* F77 Keyspec structure fields */
00576 
00577     FSK_START = 120,
00578     FSK_END = 121,
00579     FSK_KEYTYPE = 122,
00580 
00581     /* CRAY Control List Structure Fields */
00582 
00583     FCR_CI_WORD1 = 123,
00584     FCR_CI_UNIT = 124,
00585     FCR_CI_IOSTAT = 125,
00586     FCR_CI_REC = 126,
00587     FCR_CI_PARSFMT = 127,
00588     FCR_CI_FMTSRC = 128,
00589     FCR_CI_ADVANCE = 129,
00590     FCR_CI_SIZE = 130,
00591 
00592     /* CRAY FCD Structure Fields */
00593     FCR_FCD_ADDR = 131,
00594     FCR_FCD_LEN = 132,
00595 
00596     /* Cray IOLIST header */
00597     FCR_IOL_HEAD = 133,
00598 
00599     /* Cray open descriptor fields */
00600     FCR_OPEN_VERSION = 134,
00601     FCR_OPEN_UNIT = 135,
00602     FCR_OPEN_IOSTAT = 136,
00603     FCR_OPEN_ERR = 137,
00604     FCR_OPEN_FILE = 138,
00605     FCR_OPEN_STATUS = 139,
00606     FCR_OPEN_ACCESS = 140,
00607     FCR_OPEN_FORM = 141,
00608     FCR_OPEN_RECL = 142,
00609     FCR_OPEN_BLANK = 143,
00610     FCR_OPEN_POSITION = 144,
00611     FCR_OPEN_ACTION = 145,
00612     FCR_OPEN_DELIM = 146,
00613     FCR_OPEN_PAD = 147,
00614 
00615    /* Cray close descriptor fields */
00616     FCR_CLOSE_VERSION = 148,
00617     FCR_CLOSE_UNIT = 149,
00618     FCR_CLOSE_IOSTAT = 150,
00619     FCR_CLOSE_ERR = 151,
00620     FCR_CLOSE_STATUS = 152,
00621 
00622    /* Cray Inquire descriptor fields */
00623     FCR_INQ_VERSION = 153,
00624     FCR_INQ_UNIT = 154,
00625     FCR_INQ_FILE = 155,
00626     FCR_INQ_IOSTAT = 156,
00627     FCR_INQ_ERR = 157,
00628     FCR_INQ_EXIST = 158,
00629     FCR_INQ_OPENED = 159,
00630     FCR_INQ_NUMBER = 160,
00631     FCR_INQ_NAMED = 161,
00632     FCR_INQ_NAME = 162,
00633     FCR_INQ_ACCESS = 163,
00634     FCR_INQ_SEQUENTIAL = 164,
00635     FCR_INQ_DIRECT = 165,
00636     FCR_INQ_FORM = 166,
00637     FCR_INQ_FORMATTED = 167,
00638     FCR_INQ_UNFORMATTED = 168,
00639     FCR_INQ_RECL = 169,
00640     FCR_INQ_NEXTREC = 170,
00641     FCR_INQ_BLANK = 171,
00642     FCR_INQ_POSITION = 172,
00643     FCR_INQ_ACTION = 173,
00644     FCR_INQ_READ = 174,
00645     FCR_INQ_WRITE = 175,
00646     FCR_INQ_READWRITE = 176,
00647     FCR_INQ_DELIM = 177,
00648     FCR_INQ_PAD = 178,
00649 
00650     /* Cray Dope Vector descriptor fields */
00651     FCR_DV_BASE_PTR = 179,
00652     FCR_DV_BASE_LEN = 180,
00653     FCR_DV_FLAG_INFO = 181,
00654     FCR_DV_TYPE_LEN = 182,
00655     FCR_DV_ORIG_BASE = 183,
00656     FCR_DV_ORIG_SIZE = 184,
00657     FCR_DV_DIM1_LB = 185,
00658     FCR_DV_DIM1_EXTENT = 186,
00659     FCR_DV_DIM1_STRIDE = 187,
00660     FCR_DV_DIM2_LB = 188,
00661     FCR_DV_DIM2_EXTENT = 189,
00662     FCR_DV_DIM2_STRIDE = 190,
00663     FCR_DV_DIM3_LB = 191,
00664     FCR_DV_DIM3_EXTENT = 192,
00665     FCR_DV_DIM3_STRIDE = 193,
00666     FCR_DV_DIM4_LB = 194,
00667     FCR_DV_DIM4_EXTENT = 195,
00668     FCR_DV_DIM4_STRIDE = 196,
00669     FCR_DV_DIM5_LB = 197,
00670     FCR_DV_DIM5_EXTENT = 298,
00671     FCR_DV_DIM5_STRIDE = 299,
00672     FCR_DV_DIM6_LB = 200,
00673     FCR_DV_DIM6_EXTENT = 201,
00674     FCR_DV_DIM6_STRIDE = 202,
00675     FCR_DV_DIM7_LB = 203,
00676     FCR_DV_DIM7_EXTENT = 204,
00677     FCR_DV_DIM7_STRIDE = 205,
00678 
00679        /* FID_IOSCALAR_ENTRY */
00680     FCR_IOSCALAR_ENTRY = 206,
00681     FCR_IOSCALAR_TYPE_T = 207,
00682     FCR_IOSCALAR_ADDR = 208,
00683     FCR_IOSCALAR_CHAR_LEN = 209,
00684 
00685       /* FID_IOARRAY_ENTRY */
00686     FCR_IOARRAY_ENTRY = 210,
00687     FCR_IOARRAY_DV_ADDR = 211,
00688     FCR_IOARRAY_FLAG = 212,
00689     FCR_IOARRAY_IDX1 = 213,
00690     FCR_IOARRAY_IDX2 = 214,
00691     FCR_IOARRAY_IDX3 = 215,
00692     FCR_IOARRAY_IDX4 = 216,
00693     FCR_IOARRAY_IDX5 = 217,
00694     FCR_IOARRAY_IDX6= 218,
00695     FCR_IOARRAY_IDX7 = 219,
00696 
00697     /* FID_IOIMPLIEDDO_ENTRY */
00698     FCR_IOIMPLIEDDO_ENTRY = 220,
00699     FCR_IOIMPLIEDDO_VAR_ADDR = 221,
00700     FCR_IOIMPLIEDDO_BEGIN_CNT = 222,
00701     FCR_IOIMPLIEDDO_END_CNT = 223,
00702     FCR_IOIMPLIEDDO_INC_CNT = 224,
00703 
00704   FIOSTRUCT_LAST = 224
00705 
00706 } FIOSTRUCT;
00707 
00708 typedef enum {
00709 
00710   FIOCLASS_NONE = 0,
00711   FIOCLASS_FIRST = 1,
00712 
00713     FCL_EXT_FORMATTED = 1,
00714     FCL_EXT_UNFORMATTED = 2,
00715     FCL_EXT_LIST = 3,
00716     FCL_EXT_NAMELIST = 4,
00717 
00718     FCL_INT_FORMATTED = 5,
00719     FCL_INT_LIST = 6,
00720 
00721     FCL_DIR_FORMATTED = 7,
00722     FCL_DIR_UNFORMATTED = 8,
00723 
00724   FIOCLASS_LAST = 8
00725 
00726 } FIOCLASS;
00727 
00728 typedef struct {
00729     FIOSTRUCT  first;
00730     FIOSTRUCT  last;
00731     INT16      size32;
00732     INT16      size64;
00733     const char       *name;
00734     const char       *name_ptr;
00735     const char       *name_local;
00736 } FIOSTRUCTID_INFO;
00737 
00738 typedef struct {
00739     INT16        offset32;
00740     INT16        type32;
00741     INT16        offset64;
00742     INT16        type64;
00743     FIOSTRUCTID  iostruct;
00744     const char  *name;
00745 } FIOSTRUCT_INFO;
00746 
00747 static ST * Make_IoRuntime_ST ( FIOOPER );
00748 #define GET_RUNTIME_ST(x) (fio_sts[x] == NULL ? Make_IoRuntime_ST (x) : \
00749             fio_sts[x])
00750 
00751 static void Gen_Io_Calls ( WN *, FIOOPER, WN *, WN *, INT32, WN *, WN *, WN *,
00752          WN * );
00753 #define GEN_IO_CALL_0(bl, op, ios1, ios2) \
00754   Gen_Io_Calls (bl, op, ios1, ios2, 0, NULL, NULL, NULL, NULL);
00755 #define GEN_IO_CALL_1(bl, op, ios1, ios2, k1) \
00756   Gen_Io_Calls (bl, op, ios1, ios2, 1, k1, NULL, NULL, NULL);
00757 #define GEN_IO_CALL_2(bl, op, ios1, ios2, k1, k2) \
00758   Gen_Io_Calls (bl, op, ios1, ios2, 2, k1, k2, NULL, NULL);
00759 #define GEN_IO_CALL_3(bl, op, ios1, ios2, k1, k2, k3) \
00760   Gen_Io_Calls (bl, op, ios1, ios2, 3, k1, k2, k3, NULL);
00761 #define GEN_IO_CALL_4(bl, op, ios1, ios2, k1, k2, k3, k4) \
00762   Gen_Io_Calls (bl, op, ios1, ios2, 4, k1, k2, k3, k4);
00763 
00764 #define Action(x)   (actions & (x))
00765 
00766 #define WN_type_pointed(x)  TY_pointed(WN_type(x))
00767 
00768 inline WN *
00769 WN_CreateNewLabel (void)
00770 {
00771   LABEL_IDX label;
00772   (void) New_LABEL (CURRENT_SYMTAB, label);
00773   return WN_CreateLabel (label, 0, NULL);
00774 }
00775 
00776 
00777 INT32 mp_io;
00778 
00779 /*  This table contains the external names of all I/O runtime routines.  */
00780 
00781 static const char * fio_names [FIOOPER_LAST + 1] = {
00782     "",     /* FIOOPER_NONE */
00783     "s_rsfe64",   /* FIO_EXT_READ_FORMAT_start */
00784     "s_rsue64",   /* FIO_EXT_READ_UNFORMAT_start */
00785     "s_rsle64",   /* FIO_EXT_READ_LIST_start */
00786     "s_rsNe64",   /* FIO_EXT_READ_NAMELIST_start */
00787     "s_wsfe64",   /* FIO_EXT_WRITE_FORMAT_start */
00788     "s_wsue64",   /* FIO_EXT_WRITE_UNFORMAT_start */
00789     "s_wsle64",   /* FIO_EXT_WRITE_LIST_start */
00790     "s_wsNe64",   /* FIO_EXT_WRITE_NAMELIST_start */
00791     "s_xsfe64",   /* FIO_EXT_REWRITE_FORMAT_start */
00792     "s_xsue64",   /* FIO_EXT_REWRITE_UNFORMAT_start */
00793     "s_xsle64",   /* FIO_EXT_REWRITE_LIST_start */
00794     "e_rsfe64",   /* FIO_EXT_READ_FORMAT_end */
00795     "e_rsue64",   /* FIO_EXT_READ_UNFORMAT_end */
00796     "e_rsle64",   /* FIO_EXT_READ_LIST_end */
00797     "e_wsfe64",   /* FIO_EXT_WRITE_FORMAT_end */
00798     "e_wsue64",   /* FIO_EXT_WRITE_UNFORMAT_end */
00799     "e_wsle64",   /* FIO_EXT_WRITE_LIST_end */
00800     "e_xsfe64",   /* FIO_EXT_REWRITE_FORMAT_end */
00801     "e_xsue64",   /* FIO_EXT_REWRITE_UNFORMAT_end */
00802     "e_xsle64",   /* FIO_EXT_REWRITE_LIST_end */
00803     "s_rsfi64",   /* FIO_INT_READ_FORMAT_start */
00804     "s_rsli64",   /* FIO_INT_READ_LIST_start */
00805     "s_wsfi64",   /* FIO_INT_WRITE_FORMAT_start */
00806     "s_wsli64",   /* FIO_INT_WRITE_LIST_start */
00807     "e_rsfi64",   /* FIO_INT_READ_FORMAT_end */
00808     "e_rsli64",   /* FIO_INT_READ_LIST_end */
00809     "e_wsfi64",   /* FIO_INT_WRITE_FORMAT_end */
00810     "e_wsli64",   /* FIO_INT_WRITE_LIST_end */
00811     "s_rdfe64",   /* FIO_DIR_READ_FORMAT_start */
00812     "s_rdue64",   /* FIO_DIR_READ_UNFORMAT_start */
00813     "s_wdfe64",   /* FIO_DIR_WRITE_FORMAT_start */
00814     "s_wdue64",   /* FIO_DIR_WRITE_UNFORMAT_start */
00815     "e_rdfe64",   /* FIO_DIR_READ_FORMAT_end */
00816     "e_rdue64",   /* FIO_DIR_READ_UNFORMAT_end */
00817     "e_wdfe64",   /* FIO_DIR_WRITE_FORMAT_end */
00818     "e_wdue64",   /* FIO_DIR_WRITE_UNFORMAT_end */
00819     "do_fioxa4",  /* FIO_FORMAT_ADDR4_item */
00820     "do_fioxa8",  /* FIO_FORMAT_ADDR8_item */
00821     "do_fioxh1",  /* FIO_FORMAT_CHAR_item */
00822     "do_fioxi1",  /* FIO_FORMAT_I1_item */
00823     "do_fioxi2",  /* FIO_FORMAT_I2_item */
00824     "do_fioxi4",  /* FIO_FORMAT_I4_item */
00825     "do_fioxi8",  /* FIO_FORMAT_I8_item */
00826     "do_fioxl1",  /* FIO_FORMAT_L1_item */
00827     "do_fioxl2",  /* FIO_FORMAT_L2_item */
00828     "do_fioxl4",  /* FIO_FORMAT_L4_item */
00829     "do_fioxl8",  /* FIO_FORMAT_L8_item */
00830     "do_fioxr4",  /* FIO_FORMAT_R4_item */
00831     "do_fioxr8",  /* FIO_FORMAT_R8_item */
00832     "do_fioxr16", /* FIO_FORMAT_R16_item */
00833     "do_fioxc4",  /* FIO_FORMAT_C4_item */
00834     "do_fioxc8",  /* FIO_FORMAT_C8_item */
00835     "do_fioxc16", /* FIO_FORMAT_C16_item */
00836     "do_fioxa4v", /* FIO_FORMAT_ADDR4_value */
00837     "do_fioxa8v", /* FIO_FORMAT_ADDR8_value */
00838     "do_fioxh1v", /* FIO_FORMAT_CHAR_value */
00839     "do_fioxi1v", /* FIO_FORMAT_I1_value */
00840     "do_fioxi2v", /* FIO_FORMAT_I2_value */
00841     "do_fioxi4v", /* FIO_FORMAT_I4_value */
00842     "do_fioxi8v", /* FIO_FORMAT_I8_value */
00843     "do_fioxl1v", /* FIO_FORMAT_L1_value */
00844     "do_fioxl2v", /* FIO_FORMAT_L2_value */
00845     "do_fioxl4v", /* FIO_FORMAT_L4_value */
00846     "do_fioxl8v", /* FIO_FORMAT_L8_value */
00847     "do_fioxr4v", /* FIO_FORMAT_R4_value */
00848     "do_fioxr8v", /* FIO_FORMAT_R8_value */
00849     "do_fioxr16v",  /* FIO_FORMAT_R16_value */
00850     "do_fioxc4v", /* FIO_FORMAT_C4_value */
00851     "do_fioxc8v", /* FIO_FORMAT_C8_value */
00852     "do_fioxc16v",  /* FIO_FORMAT_C16_value */
00853     "do_uioxa4",  /* FIO_UNFORMAT_ADDR4_item */
00854     "do_uioxa8",  /* FIO_UNFORMAT_ADDR8_item */
00855     "do_uioxh1",  /* FIO_UNFORMAT_CHAR_item */
00856     "do_uioxi1",  /* FIO_UNFORMAT_I1_item */
00857     "do_uioxi2",  /* FIO_UNFORMAT_I2_item */
00858     "do_uioxi4",  /* FIO_UNFORMAT_I4_item */
00859     "do_uioxi8",  /* FIO_UNFORMAT_I8_item */
00860     "do_uioxl1",  /* FIO_UNFORMAT_L1_item */
00861     "do_uioxl2",  /* FIO_UNFORMAT_L2_item */
00862     "do_uioxl4",  /* FIO_UNFORMAT_L4_item */
00863     "do_uioxl8",  /* FIO_UNFORMAT_L8_item */
00864     "do_uioxr4",  /* FIO_UNFORMAT_R4_item */
00865     "do_uioxr8",  /* FIO_UNFORMAT_R8_item */
00866     "do_uioxr16", /* FIO_UNFORMAT_R16_item */
00867     "do_uioxc4",  /* FIO_UNFORMAT_C4_item */
00868     "do_uioxc8",  /* FIO_UNFORMAT_C8_item */
00869     "do_uioxc16", /* FIO_UNFORMAT_C16_item */
00870     "do_uioxa4v", /* FIO_UNFORMAT_ADDR4_value */
00871     "do_uioxa8v", /* FIO_UNFORMAT_ADDR8_value */
00872     "do_uioxh1v", /* FIO_UNFORMAT_CHAR_value */
00873     "do_uioxi1v", /* FIO_UNFORMAT_I1_value */
00874     "do_uioxi2v", /* FIO_UNFORMAT_I2_value */
00875     "do_uioxi4v", /* FIO_UNFORMAT_I4_value */
00876     "do_uioxi8v", /* FIO_UNFORMAT_I8_value */
00877     "do_uioxl1v", /* FIO_UNFORMAT_L1_value */
00878     "do_uioxl2v", /* FIO_UNFORMAT_L2_value */
00879     "do_uioxl4v", /* FIO_UNFORMAT_L4_value */
00880     "do_uioxl8v", /* FIO_UNFORMAT_L8_value */
00881     "do_uioxr4v", /* FIO_UNFORMAT_R4_value */
00882     "do_uioxr8v", /* FIO_UNFORMAT_R8_value */
00883     "do_uioxr16v",  /* FIO_UNFORMAT_R16_value */
00884     "do_uioxc4v", /* FIO_UNFORMAT_C4_value */
00885     "do_uioxc8v", /* FIO_UNFORMAT_C8_value */
00886     "do_uioxc16v",  /* FIO_UNFORMAT_C16_value */
00887     "do_lioxa4",  /* FIO_LIST_ADDR4_item */
00888     "do_lioxa8",  /* FIO_LIST_ADDR8_item */
00889     "do_lioxh1",  /* FIO_LIST_CHAR_item */
00890     "do_lioxi1",  /* FIO_LIST_I1_item */
00891     "do_lioxi2",  /* FIO_LIST_I2_item */
00892     "do_lioxi4",  /* FIO_LIST_I4_item */
00893     "do_lioxi8",  /* FIO_LIST_I8_item */
00894     "do_lioxl1",  /* FIO_LIST_L1_item */
00895     "do_lioxl2",  /* FIO_LIST_L2_item */
00896     "do_lioxl4",  /* FIO_LIST_L4_item */
00897     "do_lioxl8",  /* FIO_LIST_L8_item */
00898     "do_lioxr4",  /* FIO_LIST_R4_item */
00899     "do_lioxr8",  /* FIO_LIST_R8_item */
00900     "do_lioxr16", /* FIO_LIST_R16_item */
00901     "do_lioxc4",  /* FIO_LIST_C4_item */
00902     "do_lioxc8",  /* FIO_LIST_C8_item */
00903     "do_lioxc16", /* FIO_LIST_C16_item */
00904     "do_lioxa4v", /* FIO_LIST_ADDR4_value */
00905     "do_lioxa8v", /* FIO_LIST_ADDR8_value */
00906     "do_lioxh1v", /* FIO_LIST_CHAR_value */
00907     "do_lioxi1v", /* FIO_LIST_I1_value */
00908     "do_lioxi2v", /* FIO_LIST_I2_value */
00909     "do_lioxi4v", /* FIO_LIST_I4_value */
00910     "do_lioxi8v", /* FIO_LIST_I8_value */
00911     "do_lioxl1v", /* FIO_LIST_L1_value */
00912     "do_lioxl2v", /* FIO_LIST_L2_value */
00913     "do_lioxl4v", /* FIO_LIST_L4_value */
00914     "do_lioxl8v", /* FIO_LIST_L8_value */
00915     "do_lioxr4v", /* FIO_LIST_R4_value */
00916     "do_lioxr8v", /* FIO_LIST_R8_value */
00917     "do_lioxr16v",  /* FIO_LIST_R16_value */
00918     "do_lioxc4v", /* FIO_LIST_C4_value */
00919     "do_lioxc8v", /* FIO_LIST_C8_value */
00920     "do_lioxc16v",  /* FIO_LIST_C16_value */
00921     "f_back64",   /* FIO_BACKSPACE */
00922     "f_clos64",   /* FIO_CLOSE */
00923     "f_del64",    /* FIO_DELETE */
00924     "f_end64",    /* FIO_ENDFILE */
00925     "f_find64",   /* FIO_FIND */
00926     "f_inqu064x", /* FIO_INQUIRE */
00927     "f_open064x", /* FIO_OPEN */
00928     "f_rew64",    /* FIO_REWIND */
00929     "f_unl64",    /* FIO_UNLOCK */
00930     "f_df64x",    /* FIO_DEFINEFILE */
00931     "_FRU",   /* FIO_CR_READ_UNFORMATTED */
00932     "_FWU",   /* FIO_CR_WRITE_UNFORMATTED */
00933     "_FRF",   /* FIO_CR_READ_FORMATTED */
00934     "_FWF",   /* FIO_CR_WRITE_FORMATTED */
00935     "_FRN",   /* FIO_CR_READ_NAMELIST */
00936     "_FWN",   /* FIO_CR_WRITE_NAMELIST */
00937     "_INQIL",   /* FIO_INQLENGTH */
00938     "_OPEN",    /* FIO_CR_OPEN */
00939     "_CLOSE",   /* FIO_CR_CLOSE */
00940     "_EOFW",    /* FIO_CR_ENDFILE */
00941     "_REWF",    /* FIO_CR_REWIND */
00942     "_INQUIRE",   /* IOS_CR_INQUIRE */
00943     "_BACK",    /* IOS_CR_BACKSPACE */
00944     "_BUFFERIN",  /* IOS_CR_BUFFERIN */
00945     "_BUFFEROUT"  /* IOS_CR_BUFFEROUT */
00946 
00947 };
00948 
00949 /*  This table contains pointers to the global ST entries for each of the  */
00950 /*  I/O runtime routines.  These entries allow efficient sharing of all    */
00951 /*  calls to a particular runtime routine.                                 */
00952 
00953 static ST * fio_sts [FIOOPER_LAST + 1] = {
00954     NULL, /* FIOOPER_NONE */
00955     NULL, /* FIO_EXT_READ_FORMAT_start */
00956     NULL, /* FIO_EXT_READ_UNFORMAT_start */
00957     NULL, /* FIO_EXT_READ_LIST_start */
00958     NULL, /* FIO_EXT_READ_NAMELIST_start */
00959     NULL, /* FIO_EXT_WRITE_FORMAT_start */
00960     NULL, /* FIO_EXT_WRITE_UNFORMAT_start */
00961     NULL, /* FIO_EXT_WRITE_LIST_start */
00962     NULL, /* FIO_EXT_WRITE_NAMELIST_start */
00963     NULL, /* FIO_EXT_REWRITE_FORMAT_start */
00964     NULL, /* FIO_EXT_REWRITE_UNFORMAT_start */
00965     NULL, /* FIO_EXT_REWRITE_LIST_start */
00966     NULL, /* FIO_EXT_READ_FORMAT_end */
00967     NULL, /* FIO_EXT_READ_UNFORMAT_end */
00968     NULL, /* FIO_EXT_READ_LIST_end */
00969     NULL, /* FIO_EXT_WRITE_FORMAT_end */
00970     NULL, /* FIO_EXT_WRITE_UNFORMAT_end */
00971     NULL, /* FIO_EXT_WRITE_LIST_end */
00972     NULL, /* FIO_EXT_REWRITE_FORMAT_end */
00973     NULL, /* FIO_EXT_REWRITE_UNFORMAT_end */
00974     NULL, /* FIO_EXT_REWRITE_LIST_end */
00975     NULL, /* FIO_INT_READ_FORMAT_start */
00976     NULL, /* FIO_INT_READ_LIST_start */
00977     NULL, /* FIO_INT_WRITE_FORMAT_start */
00978     NULL, /* FIO_INT_WRITE_LIST_start */
00979     NULL, /* FIO_INT_READ_FORMAT_end */
00980     NULL, /* FIO_INT_READ_LIST_end */
00981     NULL, /* FIO_INT_WRITE_FORMAT_end */
00982     NULL, /* FIO_INT_WRITE_LIST_end */
00983     NULL, /* FIO_DIR_READ_FORMAT_start */
00984     NULL, /* FIO_DIR_READ_UNFORMAT_start */
00985     NULL, /* FIO_DIR_WRITE_FORMAT_start */
00986     NULL, /* FIO_DIR_WRITE_UNFORMAT_start */
00987     NULL, /* FIO_DIR_READ_FORMAT_end */
00988     NULL, /* FIO_DIR_READ_UNFORMAT_end */
00989     NULL, /* FIO_DIR_WRITE_FORMAT_end */
00990     NULL, /* FIO_DIR_WRITE_UNFORMAT_end */
00991     NULL, /* FIO_FORMAT_ADDR4_item */
00992     NULL, /* FIO_FORMAT_ADDR8_item */
00993     NULL, /* FIO_FORMAT_CHAR_item */
00994     NULL, /* FIO_FORMAT_I1_item */
00995     NULL, /* FIO_FORMAT_I2_item */
00996     NULL, /* FIO_FORMAT_I4_item */
00997     NULL, /* FIO_FORMAT_I8_item */
00998     NULL, /* FIO_FORMAT_L1_item */
00999     NULL, /* FIO_FORMAT_L2_item */
01000     NULL, /* FIO_FORMAT_L4_item */
01001     NULL, /* FIO_FORMAT_L8_item */
01002     NULL, /* FIO_FORMAT_R4_item */
01003     NULL, /* FIO_FORMAT_R8_item */
01004     NULL, /* FIO_FORMAT_R16_item */
01005     NULL, /* FIO_FORMAT_C4_item */
01006     NULL, /* FIO_FORMAT_C8_item */
01007     NULL, /* FIO_FORMAT_C16_item */
01008     NULL, /* FIO_FORMAT_ADDR4_value */
01009     NULL, /* FIO_FORMAT_ADDR8_value */
01010     NULL, /* FIO_FORMAT_CHAR_value */
01011     NULL, /* FIO_FORMAT_I1_value */
01012     NULL, /* FIO_FORMAT_I2_value */
01013     NULL, /* FIO_FORMAT_I4_value */
01014     NULL, /* FIO_FORMAT_I8_value */
01015     NULL, /* FIO_FORMAT_L1_value */
01016     NULL, /* FIO_FORMAT_L2_value */
01017     NULL, /* FIO_FORMAT_L4_value */
01018     NULL, /* FIO_FORMAT_L8_value */
01019     NULL, /* FIO_FORMAT_R4_value */
01020     NULL, /* FIO_FORMAT_R8_value */
01021     NULL, /* FIO_FORMAT_R16_value */
01022     NULL, /* FIO_FORMAT_C4_value */
01023     NULL, /* FIO_FORMAT_C8_value */
01024     NULL, /* FIO_FORMAT_C16_value */
01025     NULL, /* FIO_UNFORMAT_ADDR4_item */
01026     NULL, /* FIO_UNFORMAT_ADDR8_item */
01027     NULL, /* FIO_UNFORMAT_CHAR_item */
01028     NULL, /* FIO_UNFORMAT_I1_item */
01029     NULL, /* FIO_UNFORMAT_I2_item */
01030     NULL, /* FIO_UNFORMAT_I4_item */
01031     NULL, /* FIO_UNFORMAT_I8_item */
01032     NULL, /* FIO_UNFORMAT_L1_item */
01033     NULL, /* FIO_UNFORMAT_L2_item */
01034     NULL, /* FIO_UNFORMAT_L4_item */
01035     NULL, /* FIO_UNFORMAT_L8_item */
01036     NULL, /* FIO_UNFORMAT_R4_item */
01037     NULL, /* FIO_UNFORMAT_R8_item */
01038     NULL, /* FIO_UNFORMAT_R16_item */
01039     NULL, /* FIO_UNFORMAT_C4_item */
01040     NULL, /* FIO_UNFORMAT_C8_item */
01041     NULL, /* FIO_UNFORMAT_C16_item */
01042     NULL, /* FIO_UNFORMAT_ADDR4_value */
01043     NULL, /* FIO_UNFORMAT_ADDR8_value */
01044     NULL, /* FIO_UNFORMAT_CHAR_value */
01045     NULL, /* FIO_UNFORMAT_I1_value */
01046     NULL, /* FIO_UNFORMAT_I2_value */
01047     NULL, /* FIO_UNFORMAT_I4_value */
01048     NULL, /* FIO_UNFORMAT_I8_value */
01049     NULL, /* FIO_UNFORMAT_L1_value */
01050     NULL, /* FIO_UNFORMAT_L2_value */
01051     NULL, /* FIO_UNFORMAT_L4_value */
01052     NULL, /* FIO_UNFORMAT_L8_value */
01053     NULL, /* FIO_UNFORMAT_R4_value */
01054     NULL, /* FIO_UNFORMAT_R8_value */
01055     NULL, /* FIO_UNFORMAT_R16_value */
01056     NULL, /* FIO_UNFORMAT_C4_value */
01057     NULL, /* FIO_UNFORMAT_C8_value */
01058     NULL, /* FIO_UNFORMAT_C16_value */
01059     NULL, /* FIO_LIST_ADDR4_item */
01060     NULL, /* FIO_LIST_ADDR8_item */
01061     NULL, /* FIO_LIST_CHAR_item */
01062     NULL, /* FIO_LIST_I1_item */
01063     NULL, /* FIO_LIST_I2_item */
01064     NULL, /* FIO_LIST_I4_item */
01065     NULL, /* FIO_LIST_I8_item */
01066     NULL, /* FIO_LIST_L1_item */
01067     NULL, /* FIO_LIST_L2_item */
01068     NULL, /* FIO_LIST_L4_item */
01069     NULL, /* FIO_LIST_L8_item */
01070     NULL, /* FIO_LIST_R4_item */
01071     NULL, /* FIO_LIST_R8_item */
01072     NULL, /* FIO_LIST_R16_item */
01073     NULL, /* FIO_LIST_C4_item */
01074     NULL, /* FIO_LIST_C8_item */
01075     NULL, /* FIO_LIST_C16_item */
01076     NULL, /* FIO_LIST_ADDR4_value */
01077     NULL, /* FIO_LIST_ADDR8_value */
01078     NULL, /* FIO_LIST_CHAR_value */
01079     NULL, /* FIO_LIST_I1_value */
01080     NULL, /* FIO_LIST_I2_value */
01081     NULL, /* FIO_LIST_I4_value */
01082     NULL, /* FIO_LIST_I8_value */
01083     NULL, /* FIO_LIST_L1_value */
01084     NULL, /* FIO_LIST_L2_value */
01085     NULL, /* FIO_LIST_L4_value */
01086     NULL, /* FIO_LIST_L8_value */
01087     NULL, /* FIO_LIST_R4_value */
01088     NULL, /* FIO_LIST_R8_value */
01089     NULL, /* FIO_LIST_R16_value */
01090     NULL, /* FIO_LIST_C4_value */
01091     NULL, /* FIO_LIST_C8_value */
01092     NULL, /* FIO_LIST_C16_value */
01093     NULL, /* FIO_BACKSPACE */
01094     NULL, /* FIO_CLOSE */
01095     NULL, /* FIO_DELETE */
01096     NULL, /* FIO_ENDFILE */
01097     NULL, /* FIO_FIND */
01098     NULL, /* FIO_INQUIRE */
01099     NULL, /* FIO_OPEN */
01100     NULL, /* FIO_REWIND */
01101     NULL, /* FIO_UNLOCK */
01102     NULL, /* FIO_DEFINEFILE */
01103     NULL, /* FIO_CR_READ_UNFORMATTED */
01104     NULL, /* FIO_CR_WRITE_UNFORMATTED */
01105     NULL, /* FIO_CR_READ_FORMATTED */
01106     NULL, /* FIO_CR_WRITE_FORMATTED */
01107     NULL, /* FIO_CR_READ_NAMELIST */
01108     NULL, /* FIO_CR_WRITE_NAMELIST */
01109     NULL, /* FIO_INQLENGTH */
01110     NULL, /* IOS_CR_OPEN */
01111     NULL, /* IOS_CR_CLOSE */
01112     NULL, /* IOS_CR_ENDFILE */
01113     NULL, /* IOS_CR_REWIND */
01114     NULL, /* IOS_CR_INQUIRE */
01115     NULL, /* IOS_CR_BACKSPACE */
01116     NULL, /* IOS_CR_BUFFERIN */
01117     NULL  /* IOS_CR_BUFFEROUT */
01118 };
01119 
01120 
01121 /*  These tables contain the FIOOPER codes for each I/O item or value.     */
01122 /*  The tables are indexed by the type of I/O (formatted, unformatted,     */
01123 /*  list-directed) and the data type of the item/value.        */
01124 
01125 static FIOOPER fio_item_ops  [FIOFORMATTYPE_LAST +1] [FIOITEMTYPE_LAST + 1] = {
01126     FIOOPER_NONE,   /* unknown, FIOITEMTYPE_NONE */
01127     FIOOPER_NONE,   /* unknown, FIT_ADDRESS4 */
01128     FIOOPER_NONE,   /* unknown, FIT_ADDRESS8 */
01129     FIOOPER_NONE,   /* unknown, FIT_CHARACTER */
01130     FIOOPER_NONE,   /* unknown, FIT_INTEGER1 */
01131     FIOOPER_NONE,   /* unknown, FIT_INTEGER2 */
01132     FIOOPER_NONE,   /* unknown, FIT_INTEGER4 */
01133     FIOOPER_NONE,   /* unknown, FIT_INTEGER8 */
01134     FIOOPER_NONE,   /* unknown, FIT_LOGICAL1 */
01135     FIOOPER_NONE,   /* unknown, FIT_LOGICAL2 */
01136     FIOOPER_NONE,   /* unknown, FIT_LOGICAL4 */
01137     FIOOPER_NONE,   /* unknown, FIT_LOGICAL8 */
01138     FIOOPER_NONE,   /* unknown, FIT_REAL4 */
01139     FIOOPER_NONE,   /* unknown, FIT_REAL8 */
01140     FIOOPER_NONE,   /* unknown, FIT_REAL16 */
01141     FIOOPER_NONE,   /* unknown, FIT_COMPLEX4 */
01142     FIOOPER_NONE,   /* unknown, FIT_COMPLEX8 */
01143     FIOOPER_NONE,   /* unknown, FIT_COMPLEX16 */
01144     FIOOPER_NONE,   /* unknown, FIT_RECORD */
01145     FIOOPER_NONE,   /* formatted, FIOITEMTYPE_NONE */
01146     FIO_FORMAT_ADDR4_item,  /* formatted, FIT_ADDRESS4 */
01147     FIO_FORMAT_ADDR8_item,  /* formatted, FIT_ADDRESS8 */
01148     FIO_FORMAT_CHAR_item, /* formatted, FIT_CHARACTER */
01149     FIO_FORMAT_I1_item,   /* formatted, FIT_INTEGER1 */
01150     FIO_FORMAT_I2_item,   /* formatted, FIT_INTEGER2 */
01151     FIO_FORMAT_I4_item,   /* formatted, FIT_INTEGER4 */
01152     FIO_FORMAT_I8_item,   /* formatted, FIT_INTEGER8 */
01153     FIO_FORMAT_L1_item,   /* formatted, FIT_LOGICAL1 */
01154     FIO_FORMAT_L2_item,   /* formatted, FIT_LOGICAL2 */
01155     FIO_FORMAT_L4_item,   /* formatted, FIT_LOGICAL4 */
01156     FIO_FORMAT_L8_item,   /* formatted, FIT_LOGICAL8 */
01157     FIO_FORMAT_R4_item,   /* formatted, FIT_REAL4 */
01158     FIO_FORMAT_R8_item,   /* formatted, FIT_REAL8 */
01159     FIO_FORMAT_R16_item,  /* formatted, FIT_REAL16 */
01160     FIO_FORMAT_C4_item,   /* formatted, FIT_COMPLEX4 */
01161     FIO_FORMAT_C8_item,   /* formatted, FIT_COMPLEX8 */
01162     FIO_FORMAT_C16_item,  /* formatted, FIT_COMPLEX16 */
01163     FIOOPER_NONE,   /* formatted, FIT_RECORD */
01164     FIOOPER_NONE,   /* unformatted, FIOITEMTYPE_NONE */
01165     FIO_UNFORMAT_ADDR4_item,  /* unformatted, FIT_ADDRESS4 */
01166     FIO_UNFORMAT_ADDR8_item,  /* unformatted, FIT_ADDRESS8 */
01167     FIO_UNFORMAT_CHAR_item, /* unformatted, FIT_CHARACTER */
01168     FIO_UNFORMAT_I1_item, /* unformatted, FIT_INTEGER1 */
01169     FIO_UNFORMAT_I2_item, /* unformatted, FIT_INTEGER2 */
01170     FIO_UNFORMAT_I4_item, /* unformatted, FIT_INTEGER4 */
01171     FIO_UNFORMAT_I8_item, /* unformatted, FIT_INTEGER8 */
01172     FIO_UNFORMAT_L1_item, /* unformatted, FIT_LOGICAL1 */
01173     FIO_UNFORMAT_L2_item, /* unformatted, FIT_LOGICAL2 */
01174     FIO_UNFORMAT_L4_item, /* unformatted, FIT_LOGICAL4 */
01175     FIO_UNFORMAT_L8_item, /* unformatted, FIT_LOGICAL8 */
01176     FIO_UNFORMAT_R4_item, /* unformatted, FIT_REAL4 */
01177     FIO_UNFORMAT_R8_item, /* unformatted, FIT_REAL8 */
01178     FIO_UNFORMAT_R16_item,  /* unformatted, FIT_REAL16 */
01179     FIO_UNFORMAT_C4_item, /* unformatted, FIT_COMPLEX4 */
01180     FIO_UNFORMAT_C8_item, /* unformatted, FIT_COMPLEX8 */
01181     FIO_UNFORMAT_C16_item,  /* unformatted, FIT_COMPLEX16 */
01182     FIOOPER_NONE,   /* unformatted, FIT_RECORD */
01183     FIOOPER_NONE,   /* list-directed, FIOITEMTYPE_NONE */
01184     FIO_LIST_ADDR4_item,  /* list-directed, FIT_ADDRESS4 */
01185     FIO_LIST_ADDR8_item,  /* list-directed, FIT_ADDRESS8 */
01186     FIO_LIST_CHAR_item,   /* list-directed, FIT_CHARACTER */
01187     FIO_LIST_I1_item,   /* list-directed, FIT_INTEGER1 */
01188     FIO_LIST_I2_item,   /* list-directed, FIT_INTEGER2 */
01189     FIO_LIST_I4_item,   /* list-directed, FIT_INTEGER4 */
01190     FIO_LIST_I8_item,   /* list-directed, FIT_INTEGER8 */
01191     FIO_LIST_L1_item,   /* list-directed, FIT_LOGICAL1 */
01192     FIO_LIST_L2_item,   /* list-directed, FIT_LOGICAL2 */
01193     FIO_LIST_L4_item,   /* list-directed, FIT_LOGICAL4 */
01194     FIO_LIST_L8_item,   /* list-directed, FIT_LOGICAL8 */
01195     FIO_LIST_R4_item,   /* list-directed, FIT_REAL4 */
01196     FIO_LIST_R8_item,   /* list-directed, FIT_REAL8 */
01197     FIO_LIST_R16_item,    /* list-directed, FIT_REAL16 */
01198     FIO_LIST_C4_item,   /* list-directed, FIT_COMPLEX4 */
01199     FIO_LIST_C8_item,   /* list-directed, FIT_COMPLEX8 */
01200     FIO_LIST_C16_item,    /* list-directed, FIT_COMPLEX16 */
01201     FIOOPER_NONE    /* list-directed, FIT_RECORD */
01202 };
01203 
01204 static FIOOPER fio_value_ops [FIOFORMATTYPE_LAST +1] [FIOITEMTYPE_LAST + 1] = {
01205     FIOOPER_NONE,   /* unknown, FIOITEMTYPE_NONE */
01206     FIOOPER_NONE,   /* unknown, FIT_ADDRESS4 */
01207     FIOOPER_NONE,   /* unknown, FIT_ADDRESS8 */
01208     FIOOPER_NONE,   /* unknown, FIT_CHARACTER */
01209     FIOOPER_NONE,   /* unknown, FIT_INTEGER1 */
01210     FIOOPER_NONE,   /* unknown, FIT_INTEGER2 */
01211     FIOOPER_NONE,   /* unknown, FIT_INTEGER4 */
01212     FIOOPER_NONE,   /* unknown, FIT_INTEGER8 */
01213     FIOOPER_NONE,   /* unknown, FIT_LOGICAL1 */
01214     FIOOPER_NONE,   /* unknown, FIT_LOGICAL2 */
01215     FIOOPER_NONE,   /* unknown, FIT_LOGICAL4 */
01216     FIOOPER_NONE,   /* unknown, FIT_LOGICAL8 */
01217     FIOOPER_NONE,   /* unknown, FIT_REAL4 */
01218     FIOOPER_NONE,   /* unknown, FIT_REAL8 */
01219     FIOOPER_NONE,   /* unknown, FIT_REAL16 */
01220     FIOOPER_NONE,   /* unknown, FIT_COMPLEX4 */
01221     FIOOPER_NONE,   /* unknown, FIT_COMPLEX8 */
01222     FIOOPER_NONE,   /* unknown, FIT_COMPLEX16 */
01223     FIOOPER_NONE,   /* unknown, FIT_RECORD */
01224     FIOOPER_NONE,   /* formatted, FIOITEMTYPE_NONE */
01225     FIO_FORMAT_ADDR4_value, /* formatted, FIT_ADDRESS4 */
01226     FIO_FORMAT_ADDR8_value, /* formatted, FIT_ADDRESS8 */
01227     FIO_FORMAT_CHAR_value,  /* formatted, FIT_CHARACTER */
01228     FIO_FORMAT_I1_value,  /* formatted, FIT_INTEGER1 */
01229     FIO_FORMAT_I2_value,  /* formatted, FIT_INTEGER2 */
01230     FIO_FORMAT_I4_value,  /* formatted, FIT_INTEGER4 */
01231     FIO_FORMAT_I8_value,  /* formatted, FIT_INTEGER8 */
01232     FIO_FORMAT_L1_value,  /* formatted, FIT_LOGICAL1 */
01233     FIO_FORMAT_L2_value,  /* formatted, FIT_LOGICAL2 */
01234     FIO_FORMAT_L4_value,  /* formatted, FIT_LOGICAL4 */
01235     FIO_FORMAT_L8_value,  /* formatted, FIT_LOGICAL8 */
01236     FIO_FORMAT_R4_value,  /* formatted, FIT_REAL4 */
01237     FIO_FORMAT_R8_value,  /* formatted, FIT_REAL8 */
01238     FIO_FORMAT_R16_value, /* formatted, FIT_REAL16 */
01239     FIO_FORMAT_C4_value,  /* formatted, FIT_COMPLEX4 */
01240     FIO_FORMAT_C8_value,  /* formatted, FIT_COMPLEX8 */
01241     FIO_FORMAT_C16_value, /* formatted, FIT_COMPLEX16 */
01242     FIOOPER_NONE,   /* formatted, FIT_RECORD */
01243     FIOOPER_NONE,   /* unformatted, FIOITEMTYPE_NONE */
01244     FIO_UNFORMAT_ADDR4_value, /* unformatted, FIT_ADDRESS4 */
01245     FIO_UNFORMAT_ADDR8_value, /* unformatted, FIT_ADDRESS8 */
01246     FIO_UNFORMAT_CHAR_value,  /* unformatted, FIT_CHARACTER */
01247     FIO_UNFORMAT_I1_value,  /* unformatted, FIT_INTEGER1 */
01248     FIO_UNFORMAT_I2_value,  /* unformatted, FIT_INTEGER2 */
01249     FIO_UNFORMAT_I4_value,  /* unformatted, FIT_INTEGER4 */
01250     FIO_UNFORMAT_I8_value,  /* unformatted, FIT_INTEGER8 */
01251     FIO_UNFORMAT_L1_value,  /* unformatted, FIT_LOGICAL1 */
01252     FIO_UNFORMAT_L2_value,  /* unformatted, FIT_LOGICAL2 */
01253     FIO_UNFORMAT_L4_value,  /* unformatted, FIT_LOGICAL4 */
01254     FIO_UNFORMAT_L8_value,  /* unformatted, FIT_LOGICAL8 */
01255     FIO_UNFORMAT_R4_value,  /* unformatted, FIT_REAL4 */
01256     FIO_UNFORMAT_R8_value,  /* unformatted, FIT_REAL8 */
01257     FIO_UNFORMAT_R16_value, /* unformatted, FIT_REAL16 */
01258     FIO_UNFORMAT_C4_value,  /* unformatted, FIT_COMPLEX4 */
01259     FIO_UNFORMAT_C8_value,  /* unformatted, FIT_COMPLEX8 */
01260     FIO_UNFORMAT_C16_value, /* unformatted, FIT_COMPLEX16 */
01261     FIOOPER_NONE,   /* unformatted, FIT_RECORD */
01262     FIOOPER_NONE,   /* list-directed, FIOITEMTYPE_NONE */
01263     FIO_LIST_ADDR4_value, /* list-directed, FIT_ADDRESS4 */
01264     FIO_LIST_ADDR8_value, /* list-directed, FIT_ADDRESS8 */
01265     FIO_LIST_CHAR_value,  /* list-directed, FIT_CHARACTER */
01266     FIO_LIST_I1_value,    /* list-directed, FIT_INTEGER1 */
01267     FIO_LIST_I2_value,    /* list-directed, FIT_INTEGER2 */
01268     FIO_LIST_I4_value,    /* list-directed, FIT_INTEGER4 */
01269     FIO_LIST_I8_value,    /* list-directed, FIT_INTEGER8 */
01270     FIO_LIST_L1_value,    /* list-directed, FIT_LOGICAL1 */
01271     FIO_LIST_L2_value,    /* list-directed, FIT_LOGICAL2 */
01272     FIO_LIST_L4_value,    /* list-directed, FIT_LOGICAL4 */
01273     FIO_LIST_L8_value,    /* list-directed, FIT_LOGICAL8 */
01274     FIO_LIST_R4_value,    /* list-directed, FIT_REAL4 */
01275     FIO_LIST_R8_value,    /* list-directed, FIT_REAL8 */
01276     FIO_LIST_R16_value,   /* list-directed, FIT_REAL16 */
01277     FIO_LIST_C4_value,    /* list-directed, FIT_COMPLEX4 */
01278     FIO_LIST_C8_value,    /* list-directed, FIT_COMPLEX8 */
01279     FIO_LIST_C16_value,   /* list-directed, FIT_COMPLEX16 */
01280     FIOOPER_NONE    /* list-directed, FIT_RECORD */
01281 };
01282 
01283 
01284 /*  These variables contain a set of ST's (and their count) which   */
01285 /*  represent user variables whose address has been passed to an    */
01286 /*  I/O routine indirectly through a control structure.  Since the  */
01287 /*  reference is hidden, the optimizer may not properly allocate,   */
01288 /*  home or reload the user variable.  So, what we do is generate   */
01289 /*  a set of 'dummy' parameter nodes on the call which list all     */
01290 /*  such variables referenced.  Every call to Gen_Io_PutAddrWN      */
01291 /*  saves the referenced ST in the table.  The next (first) call    */
01292 /*  to an I/O routine has these dummy parameters appended to it.    */
01293 
01294 static INT32     fio_dummy_max = 0;
01295 static INT32     fio_dummy_count;
01296 static BOOL      *fio_dummy_ref;
01297 static ST      ** fio_dummy_st;
01298 static TY_IDX    *fio_dummy_tyidx;
01299 static WN_OFFSET *fio_dummy_ofst;
01300 
01301 /*  These variables and tables contain the TY & ST pointers to the I/O   */
01302 /*  global types and local symbols.  The variable fio_current_symtab is  */
01303 /*  to validate the entries in fiostruct_st.  When a new PU is first   */
01304 /*  entered, the ST pointers to old PU must be cleared.      */
01305 
01306 static TY_IDX  fioruntime_ty = (TY_IDX) 0;
01307 
01308 static TY_IDX  fiostruct_ty [FIOSTRUCTID_LAST + 1] = {
01309     (TY_IDX) 0, /* FIOSTRUCT_NONE */
01310     (TY_IDX) 0, /* FID_CILIST */
01311     (TY_IDX) 0, /* FID_ICILIST */
01312     (TY_IDX) 0, /* FID_OLIST */
01313     (TY_IDX) 0, /* FID_FLIST */
01314     (TY_IDX) 0, /* FID_INLIST */
01315     (TY_IDX) 0, /* FID_ALIST */
01316     (TY_IDX) 0, /* FID_CLLIST */
01317     (TY_IDX) 0, /* FID_KEYSPEC */
01318     (TY_IDX) 0, /* FID_CRAY_CLIST */
01319     (TY_IDX) 0,       /* FID_CRAY_FCD */
01320     (TY_IDX) 0, /* FID_CRAY_IOLIST */
01321     (TY_IDX) 0, /* FID_CRAY_OPENLIST */
01322     (TY_IDX) 0, /* FID_CRAY_CLOSELIST */
01323     (TY_IDX) 0, /* FID_CRAY_INQLIST */
01324     (TY_IDX) 0, /* FID_CRAY_DOPEVEC */
01325     (TY_IDX) 0, /* FID_IOSCALAR_ENTRY */
01326     (TY_IDX) 0, /* FID_IOARRAY_ENTRY */
01327     (TY_IDX) 0  /* FID_IOIMPLIEDDO_ENTRY */
01328 };
01329 
01330 static ST * fiostruct_st [FIOSTRUCTID_LAST + 1] = {
01331     NULL, /* FIOSTRUCT_NONE */
01332     NULL, /* FID_CILIST */
01333     NULL, /* FID_ICILIST */
01334     NULL, /* FID_OLIST */
01335     NULL, /* FID_FLIST */
01336     NULL, /* FID_INLIST */
01337     NULL, /* FID_ALIST */
01338     NULL, /* FID_CLLIST */
01339     NULL, /* FID_KEYSPEC */
01340     NULL, /* FID_CRAY_CLIST */
01341     NULL,       /* FID_CRAY_FCD */
01342     NULL, /* FID_CRAY_IOLIST */
01343     NULL, /* FID_CRAY_OPENLIST */
01344     NULL, /* FID_CRAY_CLOSELIST */
01345     NULL, /* FID_CRAY_INQLIST */
01346     NULL, /* FID_CRAY_DOPEVEC */
01347     NULL, /* FID_IOSCALAR_ENTRY */
01348     NULL, /* FID_IOARRAY_ENTRY */
01349     NULL  /* FID_IOIMPLIEDDO_ENTRY */
01350 };
01351 
01352 static PU * fio_current_pu = NULL;
01353 static PU * mp_fio_current_pu = NULL;
01354 
01355 static PU * namelist_current_pu = NULL;
01356 static PU * cray_iolist_current_pu = NULL;
01357 static WN     * namelist_node_list = NULL;
01358 static WN     * namelist_node = NULL;
01359 static ST     * container_block_for_iolists = NULL;
01360 static INT32  num_iolists = 0;
01361 
01362 /*  The following two tables describe all of the information about the       */
01363 /*  I/O runtime structures which are used to pass information between user   */
01364 /*  code and the runtime routines.               */
01365 /*                       */
01366 /*  WARNING:  It is absolutely critical that the following two structures    */
01367 /*        track any changes made to /usr/include/cmplrs/fioext.h.        */
01368 
01369 static FIOSTRUCTID_INFO fiostructid_info [FIOSTRUCTID_LAST + 1] = {
01370     FIOSTRUCT_NONE, FIOSTRUCT_NONE,   0,    0,  "",          "",
01371             "",        /* FIOSTRUCT_NONE */
01372     FSC_CIERR,   FSC_CISIZE,         72,  112,  ".cilist",   ".cilist_ptr",
01373             "_cilist",  /* FID_CILIST */
01374     FSI_ICIERR,  FSI_ICIRNUM,        32,   64,  ".icilist",  ".icilist_ptr",
01375             "_icilist",    /* FID_ICILIST */
01376     FSO_OERR,    FSO_OPOSITIONLEN,  136,  240,  ".olist",    ".olist_ptr",
01377             "_olist", /* FID_OLIST */
01378     FSF_FERR,    FSF_FREC,           16,   16,  ".flist",    ".flist_ptr",
01379             "_flist", /* FID_FLIST */
01380     FSN_INERR,   FSN_INWRITELEN,    216,  416,  ".inlist",   ".inlist_ptr",
01381             "_inlist",  /* FID_INLIST */
01382     FSA_AERR,    FSA_AUNIT,           8,    8,  ".alist",    ".alist_ptr",
01383             "_alist", /* FID_ALIST */
01384     FSL_CLERR,   FSL_CLSTA,          16,   16,  ".cllist",   ".cllist_ptr",
01385             "_cllist",  /* FID_CLLIST */
01386     FSK_START,   FSK_KEYTYPE,        6,   6,    ".keyspec",   ".keyspec_ptr",
01387             "_keyspec", /* FID_KEYSPEC*/
01388     FCR_CI_WORD1,  FCR_CI_SIZE,      48,  88, ".cray_clist",   ".cray_clist_ptr",
01389                 "_cray_clist", /*FID_CRAY_CLIST*/
01390    FCR_FCD_ADDR,  FCR_FCD_LEN,       8,   16,   ".cray_fcd",    ".cray_fcd_ptr",
01391             "cray_fcd",   /* FID_CRAY_FCD */
01392    FCR_IOL_HEAD,  FCR_IOL_HEAD,      8,   8,    ".cray_iolist",  ".cray_iolist_ptr",
01393             "_cray_iolist",  /*FID_CRAY_IOLIST */
01394    FCR_OPEN_VERSION, FCR_OPEN_PAD,  96, 184,    ".cray_open_desc", ".cray_open_desc_ptr",
01395             "_cray_open_desc", /* FID_CRAY_OPENLIST */
01396    FCR_CLOSE_VERSION, FCR_CLOSE_STATUS, 28, 48, ".cray_close_desc", ".cray_close_desc_ptr",
01397             "_cray_close_desc", /* FID_CRAY_CLOSELIST */
01398    FCR_INQ_VERSION, FCR_INQ_PAD,   172, 336,    ".cray_inq_desc",  ".cray_inq_desc_ptr",
01399             "_cray_inq_desc", /* FID_CRAY_INQLIST */
01400    FCR_DV_BASE_PTR, FCR_DV_DIM7_EXTENT, 116,    216,  ".cray_dv_desc", ".cray_dv_desc_ptr",
01401             "_cray_dv_desc",  /* CRAY_DOPEVEC */
01402   FCR_IOSCALAR_ENTRY, FCR_IOSCALAR_CHAR_LEN, 24, 32, ".ioscalar_entry", "_ioscalar_ptr",
01403             "_ioscalar_entry",
01404   FCR_IOARRAY_ENTRY, FCR_IOARRAY_FLAG, 20, 24, ".ioarray_entry", "_ioarray_ptr",
01405             "_ioarray_entry",
01406   FCR_IOIMPLIEDDO_ENTRY, FCR_IOIMPLIEDDO_INC_CNT, 24, 40, ".ioimplieddo_entry", "_ioimplieddo_ptr",
01407             "_ioimplieddo_entry"
01408 };
01409 
01410 static FIOSTRUCT_INFO fiostruct_info [FIOSTRUCT_LAST + 1] = {
01411       0,         0,      0,         0,    FIOSTRUCTID_NONE,  "",
01412               /* FIOSTRUCT_NONE */
01413 
01414       0,  MTYPE_I4,      0,  MTYPE_I4,    FID_CILIST, "cierr",
01415               /* FSC_CIERR */
01416       4,  MTYPE_I4,      4,  MTYPE_I4,    FID_CILIST, "ciunit",
01417               /* FSC_CIUNIT */
01418       8,  MTYPE_I4,      8,  MTYPE_I4,    FID_CILIST, "ciend",
01419               /* FSC_CIEND */
01420      12,  MTYPE_U4,     16,  MTYPE_U8,    FID_CILIST, "cifmt",
01421               /* FSC_CIFMT */
01422      16,  MTYPE_I8,     24,  MTYPE_I8,    FID_CILIST, "cirec",
01423               /* FSC_CIREC */
01424      24,  MTYPE_I4,     32,  MTYPE_I4,    FID_CILIST, "cimatch",
01425               /* FSC_CIMATCH */
01426      28,  MTYPE_I4,     36,  MTYPE_I4,    FID_CILIST, "cikeytype",
01427               /* FSC_CIKEYTYPE */
01428      32,  MTYPE_I4,     40,  MTYPE_I8,    FID_CILIST, "cikeyval",
01429               /* FSC_CIKEYVAL */
01430      36,  MTYPE_I4,     48,  MTYPE_I4,    FID_CILIST, "cikeyid",
01431               /* FSC_CIKEYID */
01432      40,  MTYPE_U4,     56,  MTYPE_U8,    FID_CILIST, "cinml",
01433               /* FSC_CINML */
01434      44,  MTYPE_I4,     64,  MTYPE_I4,    FID_CILIST, "cikeyvallen",
01435               /* FSC_CIKEYVALLEN */
01436      48,  MTYPE_U4,     72,  MTYPE_U8,    FID_CILIST, "ciadvance",
01437               /* FSC_CIADVANCE */
01438      52,  MTYPE_I4,     80,  MTYPE_I4,    FID_CILIST, "ciadvancelen",
01439               /* FSC_CIADVANCELEN */
01440      56,  MTYPE_I4,     84,  MTYPE_I4,    FID_CILIST, "cieor",
01441               /* FSC_CIEOR */
01442      60,  MTYPE_U4,     88,  MTYPE_U8,    FID_CILIST, "cisize",
01443               /* FSC_CISIZE */
01444      64,  MTYPE_U4,     96,  MTYPE_U8,    FID_CILIST, "civfmt",
01445               /* FSC_CIVFMT */
01446      68,  MTYPE_U4,    104,  MTYPE_U8,    FID_CILIST, "civfmtfp",
01447               /* FSC_CIVFMTFP */
01448 
01449       0,  MTYPE_I4,      0,  MTYPE_I4,    FID_ICILIST,  "icierr",
01450               /* FSI_ICIERR */
01451       4,  MTYPE_U4,      8,  MTYPE_U8,    FID_ICILIST,  "iciunit",
01452               /* FSI_ICIUNIT */
01453       8,  MTYPE_I4,     16,  MTYPE_I4,    FID_ICILIST,  "iciend",
01454               /* FSI_ICIEND */
01455      12,  MTYPE_U4,     24,  MTYPE_U8,    FID_ICILIST,  "icifmt",
01456               /* FSI_ICIFMT */
01457      16,  MTYPE_I4,     32,  MTYPE_I8,    FID_ICILIST,  "icirlen",
01458               /* FSI_ICIRLEN */
01459      20,  MTYPE_I4,     40,  MTYPE_I8,    FID_ICILIST,  "icirnum",
01460               /* FSI_ICIRNUM */
01461      24,  MTYPE_U4,     48,  MTYPE_U8,    FID_ICILIST,  "icivfmt",
01462               /* FSI_ICIVFMT */
01463      28,  MTYPE_U4,     56,  MTYPE_U8,    FID_ICILIST,  "icivfmtfp",
01464               /* FSI_ICIVFMTFP */
01465 
01466       0,  MTYPE_I4,      0,  MTYPE_I4,    FID_OLIST,  "oerr",
01467               /* FSO_OERR */
01468       4,  MTYPE_I4,      4,  MTYPE_I4,    FID_OLIST,  "ounit",
01469               /* FSO_OUNIT */
01470       8,  MTYPE_U4,      8,  MTYPE_U8,    FID_OLIST,  "ofnm",
01471               /* FSO_OFNM */
01472      12,  MTYPE_I4,     16,  MTYPE_I4,    FID_OLIST,  "ofnmlen",
01473               /* FSO_OFNMLEN */
01474      16,  MTYPE_U4,     24,  MTYPE_U8,    FID_OLIST,  "osta",
01475               /* FSO_OSTA */
01476      20,  MTYPE_U4,     32,  MTYPE_U8,    FID_OLIST,  "oacc",
01477               /* FSO_OACC */
01478      24,  MTYPE_U4,     40,  MTYPE_U8,    FID_OLIST,  "ofm",
01479               /* FSO_OFM */
01480      28,  MTYPE_I4,     48,  MTYPE_I8,    FID_OLIST,  "orl",
01481               /* FSO_ORL */
01482      32,  MTYPE_U4,     56,  MTYPE_U8,    FID_OLIST,  "oblnk",
01483               /* FSO_OBLNK */
01484      36,  MTYPE_U4,     64,  MTYPE_U8,    FID_OLIST,  "occ",
01485               /* FSO_OCC */
01486      40,  MTYPE_U4,     72,  MTYPE_U8,    FID_OLIST,  "oorg",
01487               /* FSO_OORG */
01488      44,  MTYPE_I4,     80,  MTYPE_I4,    FID_OLIST,  "oshared",
01489               /* FSO_OSHARED */
01490      48,  MTYPE_I4,     84,  MTYPE_I4,    FID_OLIST,  "oreadonly",
01491               /* FSO_OREADONLY */
01492      52,  MTYPE_I4,     88,  MTYPE_I4,    FID_OLIST,  "onkeys",
01493               /* FSO_ONKEYS */
01494      56,  MTYPE_U4,     96,  MTYPE_U8,    FID_OLIST,  "okeys",
01495               /* FSO_OKEYS */
01496      60,  MTYPE_U4,    104,  MTYPE_U8,    FID_OLIST,  "oassocv",
01497               /* FSO_OASSOCV */
01498      64,  MTYPE_I8,    112,  MTYPE_I8,    FID_OLIST,  "omaxrec",
01499               /* FSO_OMAXREC */
01500      72,  MTYPE_U4,    120,  MTYPE_U8,    FID_OLIST,  "odfnm",
01501               /* FSO_ODFNM */
01502      76,  MTYPE_I4,    128,  MTYPE_I4,    FID_OLIST,  "odfnmlen",
01503               /* FSO_ODFNMLEN */
01504      80,  MTYPE_U4,    136,  MTYPE_U8,    FID_OLIST,  "odisp",
01505               /* FSO_ODISP */
01506      84,  MTYPE_U4,    144,  MTYPE_U8,    FID_OLIST,  "orectype",
01507               /* FSO_ORECTYPE */
01508      88,  MTYPE_U4,    152,  MTYPE_U8,    FID_OLIST,  "oconv",
01509               /* FSO_OCONV */
01510      92,  MTYPE_I4,    160,  MTYPE_I4,    FID_OLIST,  "oconvlen",
01511               /* FSO_OCONVLEN */
01512      96,  MTYPE_I4,    164,  MTYPE_I4,    FID_OLIST,  "obuffsize",
01513               /* FSO_OBUFFSIZE */
01514     100,  MTYPE_I4,    168,  MTYPE_I4,    FID_OLIST,  "odirect",
01515               /* FSO_ODIRECT */
01516     104,  MTYPE_U4,    176,  MTYPE_U8,    FID_OLIST,  "oaction",
01517               /* FSO_OACTION */
01518     108,  MTYPE_I4,    184,  MTYPE_I4,    FID_OLIST,  "oactionlen",
01519               /* FSO_OACTIONLEN */
01520     112,  MTYPE_U4,    192,  MTYPE_U8,    FID_OLIST,  "odelim",
01521               /* FSO_ODELIM */
01522     116,  MTYPE_I4,    200,  MTYPE_I4,    FID_OLIST,  "odelimlen",
01523               /* FSO_ODELIMLEN */
01524     120,  MTYPE_U4,    208,  MTYPE_U8,    FID_OLIST,  "opad",
01525               /* FSO_OPAD */
01526     124,  MTYPE_I4,    216,  MTYPE_I4,    FID_OLIST,  "opadlen",
01527               /* FSO_OPADLEN */
01528     128,  MTYPE_U4,    224,  MTYPE_U8,    FID_OLIST,  "oposition",
01529               /* FSO_OPOSITION */
01530     132,  MTYPE_I4,    232,  MTYPE_I4,    FID_OLIST,  "opositionlen",
01531               /* FSO_OPOSITIONLEN */
01532 
01533       0,  MTYPE_I4,      0,  MTYPE_I4,    FID_FLIST,  "ferr",
01534               /* FSF_FERR */
01535       4,  MTYPE_I4,      4,  MTYPE_I4,    FID_FLIST,  "funit",
01536               /* FSF_FUNIT */
01537       8,  MTYPE_I8,      8,  MTYPE_I8,    FID_FLIST,  "frec",
01538               /* FSF_FREC */
01539 
01540       0,  MTYPE_I4,      0,  MTYPE_I4,    FID_INLIST, "inerr",
01541               /* FSN_INERR */
01542       4,  MTYPE_I4,      4,  MTYPE_I4,    FID_INLIST, "inunit",
01543               /* FSN_INUNIT */
01544       8,  MTYPE_U4,      8,  MTYPE_U8,    FID_INLIST, "infile",
01545               /* FSN_INFILE */
01546      12,  MTYPE_I4,     16,  MTYPE_I4,    FID_INLIST, "infilen",
01547               /* FSN_INFILEN */
01548      16,  MTYPE_U4,     24,  MTYPE_U8,    FID_INLIST, "inex",
01549               /* FSN_INEX */
01550      20,  MTYPE_U4,     32,  MTYPE_U8,    FID_INLIST, "inopen",
01551               /* FSN_INOPEN */
01552      24,  MTYPE_U4,     40,  MTYPE_U8,    FID_INLIST, "innum",
01553               /* FSN_INNUM */
01554      28,  MTYPE_U4,     48,  MTYPE_U8,    FID_INLIST, "innamed",
01555               /* FSN_INNAMED */
01556      32,  MTYPE_U4,     56,  MTYPE_U8,    FID_INLIST, "inname",
01557               /* FSN_INNAME */
01558      36,  MTYPE_I4,     64,  MTYPE_I4,    FID_INLIST, "innamlen",
01559               /* FSN_INNAMLEN */
01560      40,  MTYPE_U4,     72,  MTYPE_U8,    FID_INLIST, "inacc",
01561               /* FSN_INACC */
01562      44,  MTYPE_I4,     80,  MTYPE_I4,    FID_INLIST, "inacclen",
01563               /* FSN_INACCLEN */
01564      48,  MTYPE_U4,     88,  MTYPE_U8,    FID_INLIST, "inseq",
01565               /* FSN_INSEQ */
01566      52,  MTYPE_I4,     96,  MTYPE_I4,    FID_INLIST, "inseqlen",
01567               /* FSN_INSEQLEN */
01568      56,  MTYPE_U4,    104,  MTYPE_U8,    FID_INLIST, "indir",
01569               /* FSN_INDIR */
01570      60,  MTYPE_I4,    112,  MTYPE_I4,    FID_INLIST, "indirlen",
01571               /* FSN_INDIRLEN */
01572      64,  MTYPE_U4,    120,  MTYPE_U8,    FID_INLIST, "infmt",
01573               /* FSN_INFMT */
01574      68,  MTYPE_I4,    128,  MTYPE_I4,    FID_INLIST, "infmtlen",
01575               /* FSN_INFMTLEN */
01576      72,  MTYPE_U4,    136,  MTYPE_U8,    FID_INLIST, "inform",
01577               /* FSN_INFORM */
01578      76,  MTYPE_I4,    144,  MTYPE_I4,    FID_INLIST, "informlen",
01579               /* FSN_INFORMLEN */
01580      80,  MTYPE_U4,    152,  MTYPE_U8,    FID_INLIST, "inunf",
01581               /* FSN_INUNF */
01582      84,  MTYPE_I4,    160,  MTYPE_I4,    FID_INLIST, "inunflen",
01583               /* FSN_INUNFLEN */
01584      88,  MTYPE_U4,    168,  MTYPE_U8,    FID_INLIST, "inrecl",
01585               /* FSN_INRECL */
01586      92,  MTYPE_U4,    176,  MTYPE_U8,    FID_INLIST, "innrec",
01587               /* FSN_INNREC */
01588      96,  MTYPE_U4,    184,  MTYPE_U8,    FID_INLIST, "inblank",
01589               /* FSN_INBLANK */
01590     100,  MTYPE_I4,    192,  MTYPE_I4,    FID_INLIST, "inblanklen",
01591               /* FSN_INBLANKLEN */
01592     104,  MTYPE_U4,    200,  MTYPE_U8,    FID_INLIST, "indefaultfile",
01593               /* FSN_INDEFAULTFILE */
01594     108,  MTYPE_I4,    208,  MTYPE_I4,    FID_INLIST, "indefaultfilelen",
01595                   /* FSN_INDEFAULTFILELEN */
01596     112,  MTYPE_U4,    216,  MTYPE_U8,    FID_INLIST, "incc",
01597               /* FSN_INCC */
01598     116,  MTYPE_I4,    224,  MTYPE_I4,    FID_INLIST, "incclen",
01599               /* FSN_INCCLEN */
01600     120,  MTYPE_U4,    232,  MTYPE_U8,    FID_INLIST, "inkeyed",
01601               /* FSN_INKEYED */
01602     124,  MTYPE_I4,    240,  MTYPE_I4,    FID_INLIST, "inkeyedlen",
01603               /* FSN_INKEYEDLEN */
01604     128,  MTYPE_U4,    248,  MTYPE_U8,    FID_INLIST, "inorg",
01605               /* FSN_INORG */
01606     132,  MTYPE_I4,    256,  MTYPE_I4,    FID_INLIST, "inorglen",
01607               /* FSN_INORGLEN */
01608     136,  MTYPE_U4,    264,  MTYPE_U8,    FID_INLIST, "inrecordtype",
01609               /* FSN_INRECORDTYPE */
01610     140,  MTYPE_I4,    272,  MTYPE_I4,    FID_INLIST, "inrecordtypelen",
01611                    /* FSN_INRECORDTYPELEN */
01612     144,  MTYPE_U4,    280,  MTYPE_U8,    FID_INLIST, "inconv",
01613               /* FSN_INCONV */
01614     148,  MTYPE_I4,    288,  MTYPE_I4,    FID_INLIST, "inconvlen",
01615               /* FSN_INCONVLEN */
01616     152,  MTYPE_U4,    296,  MTYPE_U8,    FID_INLIST, "inbuffsize",
01617               /* FSN_INBUFFSIZE */
01618     156,  MTYPE_U4,    304,  MTYPE_U8,    FID_INLIST, "inaction",
01619               /* FSN_INACTION */
01620     160,  MTYPE_I4,    312,  MTYPE_I4,    FID_INLIST, "inactionlen",
01621               /* FSN_INACTIONLEN */
01622     164,  MTYPE_U4,    320,  MTYPE_U8,    FID_INLIST, "indelim",
01623               /* FSN_INDELIM */
01624     168,  MTYPE_I4,    328,  MTYPE_I4,    FID_INLIST, "indelimlen",
01625               /* FSN_INDELIMLEN */
01626     172,  MTYPE_U4,    336,  MTYPE_U8,    FID_INLIST, "inpad",
01627               /* FSN_INPAD */
01628     176,  MTYPE_I4,    344,  MTYPE_I4,    FID_INLIST, "inpadlen",
01629               /* FSN_INPADLEN */
01630     180,  MTYPE_U4,    352,  MTYPE_U8,    FID_INLIST, "inposition",
01631               /* FSN_INPOSITION */
01632     184,  MTYPE_I4,    360,  MTYPE_I4,    FID_INLIST, "inpositionlen",
01633               /* FSN_INPOSITIONLEN */
01634     188,  MTYPE_U4,    368,  MTYPE_U8,    FID_INLIST, "inread",
01635               /* FSN_INREAD */
01636     192,  MTYPE_I4,    376,  MTYPE_I4,    FID_INLIST, "inreadlen",
01637               /* FSN_INREADLEN */
01638     196,  MTYPE_U4,    384,  MTYPE_U8,    FID_INLIST, "inreadwrite",
01639               /* FSN_INREADWRITE */
01640     200,  MTYPE_I4,    392,  MTYPE_I4,    FID_INLIST, "inreadwritelen",
01641               /* FSN_INREADWRITELEN */
01642     204,  MTYPE_U4,    400,  MTYPE_U8,    FID_INLIST, "inwrite",
01643               /* FSN_INWRITE */
01644     208,  MTYPE_I4,    408,  MTYPE_I4,    FID_INLIST, "inwritelen",
01645               /* FSN_INWRITELEN */
01646 
01647       0,  MTYPE_I4,      0,  MTYPE_I4,    FID_ALIST,  "aerr",
01648               /* FSA_AERR */
01649       4,  MTYPE_I4,      4,  MTYPE_I4,    FID_ALIST,  "aunit",
01650               /* FSA_AUNIT */
01651 
01652       0,  MTYPE_I4,      0,  MTYPE_I4,    FID_CLLIST, "clerr",
01653               /* FSL_CLERR */
01654       4,  MTYPE_I4,      4,  MTYPE_I4,    FID_CLLIST, "clunit",
01655               /* FSL_CLUNIT */
01656       8,  MTYPE_U4,      8,  MTYPE_U8,    FID_CLLIST, "clsta",
01657               /* FSL_CLSTA */
01658   
01659       0, MTYPE_I2,   0,  MTYPE_I2,    FID_KEYSPEC, "keystart",
01660               /* FSK_KEYSTART */
01661       2, MTYPE_I2,       2,  MTYPE_I2,    FID_KEYSPEC, "keyend",
01662               /* FSK_KEYEND */
01663       4, MTYPE_I2,       4,  MTYPE_I2,    FID_KEYSPEC, "keytype",
01664               /* FSK_KEYTYPE */
01665 
01666       0, MTYPE_U8,       0,  MTYPE_U8,    FID_CRAY_CLIST, "cray_ci_word1",
01667               /* FCR_CI_WORD1 */
01668       8, MTYPE_M,        8,  MTYPE_M,     FID_CRAY_CLIST, "cray_ci_unit",
01669               /* FCR_CI_UNIT */
01670      16, MTYPE_U4,      24,  MTYPE_U8,    FID_CRAY_CLIST, "cray_ci_iostat",
01671               /* FCR_CI_IOSTAT */
01672      20, MTYPE_U4,      32,  MTYPE_U8,    FID_CRAY_CLIST, "cray_ci_rec",
01673               /* FCR_CI_REC */
01674      24, MTYPE_U4,      40,  MTYPE_U8,    FID_CRAY_CLIST, "cray_ci_parsfmt",
01675               /* FCR_CI_PARSFMT */
01676      28, MTYPE_M,       48,  MTYPE_M,     FID_CRAY_CLIST, "cray_ci_fmtsrc",
01677               /* FCR_CI_FMTSRC */
01678      36, MTYPE_M,       64,  MTYPE_M,     FID_CRAY_CLIST, "cray_ci_advance",
01679               /* FCR_CI_ADVANCE */
01680      44, MTYPE_U4,      80, MTYPE_U8,     FID_CRAY_CLIST, "cray_ci_size",
01681               /* FCR_CI_SIZE */
01682 
01683       0, MTYPE_U4,  0, MTYPE_U8,    FID_CRAY_FCD,   "cray_fcd_addr",
01684               /* FCR_FCD_ADDR */
01685       4, MTYPE_U4,      8, MTYPE_U8,      FID_CRAY_FCD,   "cray_fcd_len",
01686               /* FCR_FCD_LEN */
01687 
01688       0, MTYPE_U8,  0, MTYPE_U8,    FID_CRAY_IOLIST, "cray_iol_head",
01689               /* FCR_IOL_HEAD */
01690 
01691       0, MTYPE_U8,  0, MTYPE_U8,      FID_CRAY_OPENLIST, "cray_open_version",
01692               /* FCR_OPEN_VERSION */
01693       8, MTYPE_U4,  8, MTYPE_U8,      FID_CRAY_OPENLIST, "cray_open_unit",
01694               /* FCR_OPEN_UNIT */
01695      12, MTYPE_U4,     16, MTYPE_U8,      FID_CRAY_OPENLIST, "cray_open_iostat",
01696               /* FCR_OPEN_IOSTAT */
01697      16, MTYPE_U4,     24, MTYPE_U8,      FID_CRAY_OPENLIST, "cray_open_err",
01698               /* FCR_OPEN_ERR */
01699      20, MTYPE_M,      32, MTYPE_M,       FID_CRAY_OPENLIST, "cray_open_file",
01700               /* FCR_OPEN_FILE */
01701      28, MTYPE_M,      48, MTYPE_M,       FID_CRAY_OPENLIST, "cray_open_status",
01702               /* FCR_OPEN_STATUS */
01703      36, MTYPE_M,      64, MTYPE_M,       FID_CRAY_OPENLIST, "cray_open_access",
01704               /* FCR_OPEN_ACCESS */
01705      44, MTYPE_M,      80, MTYPE_M,       FID_CRAY_OPENLIST, "cray_open_form",
01706               /* FCR_OPEN_FORM */
01707      52, MTYPE_U4,     96, MTYPE_U8,      FID_CRAY_OPENLIST, "cray_open_recl",
01708               /* FCR_OPEN_RECL */
01709      56, MTYPE_M,     104, MTYPE_M,       FID_CRAY_OPENLIST, "cray_open_blank",
01710               /* FCR_OPEN_BLANK */
01711      64, MTYPE_M,     120, MTYPE_M,       FID_CRAY_OPENLIST, "cray_open_position",
01712               /* FCR_OPEN_POSITION */
01713      72, MTYPE_M,     136, MTYPE_M,       FID_CRAY_OPENLIST, "cray_open_action",
01714               /* FCR_OPEN_ACTION */
01715      80, MTYPE_M,     152, MTYPE_M,       FID_CRAY_OPENLIST, "cray_open_delim",
01716               /* FCR_OPEN_DELIM */
01717      88, MTYPE_M,     168, MTYPE_M,       FID_CRAY_OPENLIST, "cray_open_pad",
01718               /* FCR_OPEN_PAD */
01719 
01720      0, MTYPE_U8,      0, MTYPE_U8,       FID_CRAY_CLOSELIST, "cray_close_version",
01721               /* FCR_CLOSE_VERSION */
01722      8, MTYPE_U4,      8, MTYPE_U8,       FID_CRAY_CLOSELIST, "cray_close_unit",
01723               /* FCR_CLOSE_UNIT */
01724     12, MTYPE_U4,     16, MTYPE_U8,       FID_CRAY_CLOSELIST, "cray_close_iostat",
01725               /* FCR_CLOSE_IOSTAT */
01726     16, MTYPE_U4,     24, MTYPE_U8,       FID_CRAY_CLOSELIST, "cray_close_err",
01727               /* FCR_CLOSE_ERR */
01728     20, MTYPE_M,      32, MTYPE_M,        FID_CRAY_CLOSELIST, "cray_close_status",
01729               /* FCR_CLOSE_STATUS */
01730 
01731      0, MTYPE_U8,      0, MTYPE_U8,       FID_CRAY_INQLIST,   "cray_inq_version",
01732               /* FCR_INQ_VERSION */ 
01733      8, MTYPE_U4,      8, MTYPE_U8,       FID_CRAY_INQLIST,   "cray_inq_unit",
01734               /* FCR_INQ_UNIT */
01735     12, MTYPE_M,      16, MTYPE_M,        FID_CRAY_INQLIST,   "cray_inq_file",
01736               /* FCR_INQ_FILE */
01737     20, MTYPE_U4,     32, MTYPE_U8,       FID_CRAY_INQLIST,   "cray_inq_iostat",
01738               /* FCR_INQ_IOSTAT */
01739     24, MTYPE_U4,     40, MTYPE_U8,       FID_CRAY_INQLIST,   "cray_inq_err",
01740               /* FCR_INQ_ERR */
01741     28, MTYPE_U4,     48, MTYPE_U8,       FID_CRAY_INQLIST,   "cray_inq_exist",
01742               /* FCR_INQ_EXIST */
01743     32, MTYPE_U4,     56, MTYPE_U8,       FID_CRAY_INQLIST,   "cray_inq_opened",
01744               /* FCR_INQ_OPENED */
01745     36, MTYPE_U4,     64, MTYPE_U8,       FID_CRAY_INQLIST,   "cray_inq_number",
01746               /* FCR_INQ_NUMBER */
01747     40, MTYPE_U4,     72, MTYPE_U8,       FID_CRAY_INQLIST,   "cray_inq_named",
01748               /* FCR_INQ_NAMED */
01749     44, MTYPE_M,      80, MTYPE_M,        FID_CRAY_INQLIST,   "cray_inq_name",
01750               /* FCR_INQ_NAME */
01751     52, MTYPE_M,      96, MTYPE_M,        FID_CRAY_INQLIST,   "cray_inq_access",
01752               /* FCR_INQ_ACCESS */
01753     60, MTYPE_M,     112, MTYPE_M,        FID_CRAY_INQLIST,   "cray_inq_sequential",
01754               /* FCR_INQ_SEQUENTIAL */
01755     68, MTYPE_M,     128, MTYPE_M,        FID_CRAY_INQLIST,   "cray_inq_direct",
01756               /* FCR_INQ_DIRECT */
01757     76, MTYPE_M,     144, MTYPE_M,        FID_CRAY_INQLIST,   "cray_inq_form",
01758               /* FCR_INQ_FORM */
01759     84, MTYPE_M,     160, MTYPE_M,        FID_CRAY_INQLIST,   "cray_inq_formatted",
01760               /* FCR_INQ_FORMATTED */
01761     92, MTYPE_M,     176, MTYPE_M,        FID_CRAY_INQLIST,   "cray_inq_unformatted",
01762               /* FCR_INQ_UNFORMATTED */
01763    100, MTYPE_U4,    192, MTYPE_U8,       FID_CRAY_INQLIST,   "cray_inq_recl",
01764               /* FCR_INQ_RECL */
01765    104, MTYPE_U4,    200, MTYPE_U8,       FID_CRAY_INQLIST,   "cray_inq_nextrec",
01766               /* FCR_INQ_NEXTREC */
01767    108, MTYPE_M,     208, MTYPE_M,        FID_CRAY_INQLIST,   "cray_inq_blank",
01768               /* FCR_INQ_BLANK */
01769    116, MTYPE_M,     224, MTYPE_M,        FID_CRAY_INQLIST,   "cray_inq_position",
01770               /* FCR_INQ_POSITION */
01771    124, MTYPE_M,     240, MTYPE_M,        FID_CRAY_INQLIST,   "cray_inq_action",
01772               /* FCR_INQ_ACTION */
01773    132, MTYPE_M,     256, MTYPE_M,        FID_CRAY_INQLIST,   "cray_inq_read",
01774               /* FCR_INQ_READ */
01775    140, MTYPE_M,     272, MTYPE_M,        FID_CRAY_INQLIST,   "cray_inq_write",
01776               /* FCR_INQ_WRITE */
01777    148, MTYPE_M,     288, MTYPE_M,        FID_CRAY_INQLIST,   "cray_inq_readwrite",
01778               /* FCR_INQ_READWRITE */
01779    156, MTYPE_M,     304, MTYPE_M,        FID_CRAY_INQLIST,   "cray_inq_delim",
01780               /* FCR_INQ_DELIM */
01781    164, MTYPE_M,     320, MTYPE_M,        FID_CRAY_INQLIST,   "cray_inq_pad",
01782               /* FCR_INQ_PAD */
01783 
01784      0, MTYPE_U4,      0, MTYPE_U8, FID_CRAY_DOPEVEC, "cray_dv_base_addr",
01785               /* FCR_DV_BASE_PTR */
01786      4, MTYPE_I4,      8, MTYPE_I8, FID_CRAY_DOPEVEC, "cray_dv_base_len",
01787               /* FCR_DV_BASE_LEN */
01788      8, MTYPE_U8,      16, MTYPE_U8,  FID_CRAY_DOPEVEC, "cray_dv_flag_info",
01789               /* FCR_DV_FLAG_INFO */
01790      16, MTYPE_U8,     24, MTYPE_U8,  FID_CRAY_DOPEVEC, "cray_dv_type_len",
01791               /* FCR_DV_TYPE_LEN */
01792      24, MTYPE_U4,     32, MTYPE_U8,  FID_CRAY_DOPEVEC, "cray_dv_orig_base",
01793               /* FCR_DV_ORIG_BASE */
01794      28, MTYPE_I4,     40, MTYPE_I8,  FID_CRAY_DOPEVEC, "cray_dv_orig_size",
01795               /* FCR_DV_ORIG_SIZE */
01796      32, MTYPE_I4,     48, MTYPE_I8,  FID_CRAY_DOPEVEC, "cray_dv_dim1_lb",
01797               /* FCR_DV_DIM1_LB */
01798      36, MTYPE_I4,     56, MTYPE_I8,  FID_CRAY_DOPEVEC, "cray_dv_dim1_extent",
01799               /* FCR_DV_DIM1_EXTENT */
01800      40, MTYPE_I4,     64, MTYPE_I8,  FID_CRAY_DOPEVEC, "cray_dv_dim1_stride",
01801               /* FCR_DV_DIM1_STRIDE */
01802      44, MTYPE_I4,     72, MTYPE_I8,  FID_CRAY_DOPEVEC, "cray_dv_dim2_lb",
01803               /* FCR_DV_DIM2_LB */
01804      48, MTYPE_I4,     80, MTYPE_I8,  FID_CRAY_DOPEVEC, "cray_dv_dim2_extent",
01805               /* FCR_DV_DIM2_EXTENT */
01806      52, MTYPE_I4,     88, MTYPE_I8,  FID_CRAY_DOPEVEC, "cray_dv_dim2_stride",
01807               /* FCR_DV_DIM2_STRIDE */
01808      56, MTYPE_I4,     96, MTYPE_I8,  FID_CRAY_DOPEVEC, "cray_dv_dim3_lb",
01809               /* FCR_DV_DIM3_LB */
01810      60, MTYPE_I4,     104, MTYPE_I8, FID_CRAY_DOPEVEC, "cray_dv_dim3_extent",
01811               /* FCR_DV_DIM3_EXTENT */
01812      64, MTYPE_I4,     112, MTYPE_I8, FID_CRAY_DOPEVEC, "cray_dv_dim3_stride",
01813               /* FCR_DV_DIM3_STRIDE */
01814      68, MTYPE_I4,     120, MTYPE_I8, FID_CRAY_DOPEVEC, "cray_dv_dim4_lb",
01815               /* FCR_DV_DIM4_LB */
01816      72, MTYPE_I4,     128, MTYPE_I8, FID_CRAY_DOPEVEC, "cray_dv_dim4_extent",
01817               /* FCR_DV_DIM4_EXTENT */
01818      76, MTYPE_I4,     136, MTYPE_I8, FID_CRAY_DOPEVEC, "cray_dv_dim4_stride",
01819               /* FCR_DV_DIM4_STRIDE */
01820      80, MTYPE_I4,     144, MTYPE_I8, FID_CRAY_DOPEVEC, "cray_dv_dim5_lb",
01821               /* FCR_DV_DIM5_LB */
01822      84, MTYPE_I4,     152, MTYPE_I8, FID_CRAY_DOPEVEC, "cray_dv_dim5_extent",
01823               /* FCR_DV_DIM5_EXTENT */
01824      88, MTYPE_I4,     160, MTYPE_I8, FID_CRAY_DOPEVEC, "cray_dv_dim5_stride",
01825               /* FCR_DV_DIM5_STRIDE */
01826      92, MTYPE_I4,     168, MTYPE_I8, FID_CRAY_DOPEVEC, "cray_dv_dim6_lb",
01827               /* FCR_DV_DIM6_LB */
01828      96, MTYPE_I4,     176, MTYPE_I8, FID_CRAY_DOPEVEC, "cray_dv_dim6_extent",
01829               /* FCR_DV_DIM6_EXTENT */
01830      100, MTYPE_I4,    184, MTYPE_I8, FID_CRAY_DOPEVEC, "cray_dv_dim6_stride",
01831               /* FCR_DV_DIM6_STRIDE */
01832      104, MTYPE_I4,    192, MTYPE_I8, FID_CRAY_DOPEVEC, "cray_dv_dim7_lb",
01833               /* FCR_DV_DIM7_LB */
01834      108, MTYPE_I4,    200, MTYPE_I8, FID_CRAY_DOPEVEC, "cray_dv_dim7_extent",
01835               /* FCR_DV_DIM7_EXTENT */
01836      112, MTYPE_I4,    208, MTYPE_I8, FID_CRAY_DOPEVEC, "cray_dv_dim7_stride",
01837               /* FCR_DV_DIM7_STRIDE */
01838        /* FCR_IOSCALAR_ENTRY */
01839        0, MTYPE_I8, 0, MTYPE_I8,    FID_IOSCALAR_ENTRY, "scalar_header",
01840        8, MTYPE_I8, 8, MTYPE_I8,    FID_IOSCALAR_ENTRY, "scalar_type_t",
01841       16, MTYPE_U4,    16, MTYPE_U8,  FID_IOSCALAR_ENTRY, "iovar_address",
01842       20, MTYPE_I4,    24, MTYPE_I8,    FID_IOSCALAR_ENTRY, "scalar_char_len",
01843 
01844       /* FCR_IOARRAY_ENTRY */
01845        0, MTYPE_I8,     0, MTYPE_I8,    FID_IOARRAY_ENTRY, "array_header",
01846        8, MTYPE_U4,     8, MTYPE_U8,    FID_IOARRAY_ENTRY, "dope_vector_addr",
01847       12, MTYPE_I8,    16, MTYPE_I8,    FID_IOARRAY_ENTRY, "array_flag",
01848       20, MTYPE_U4,    24, MTYPE_U8,    FID_IOARRAY_ENTRY, "array_indx_1",
01849       24, MTYPE_U4,    32, MTYPE_U8,    FID_IOARRAY_ENTRY, "array_indx_2",
01850       28, MTYPE_U4,    40, MTYPE_U8,    FID_IOARRAY_ENTRY, "array_indx_3",
01851       32, MTYPE_U4,    48, MTYPE_U8,    FID_IOARRAY_ENTRY, "array_indx_4",
01852       36, MTYPE_U4,    56, MTYPE_U8,    FID_IOARRAY_ENTRY, "array_indx_5",
01853       40, MTYPE_U4,    64, MTYPE_U8,    FID_IOARRAY_ENTRY, "array_indx_6",
01854       44, MTYPE_U4,    72, MTYPE_U8,    FID_IOARRAY_ENTRY, "array_indx_7",
01855 
01856       /* FCR_IOIMPLIEDDO_ENTRY */
01857        0, MTYPE_I8,     0, MTYPE_I8,    FID_IOIMPLIEDDO_ENTRY, "implieddo_header",
01858        8, MTYPE_U4,     8, MTYPE_U8,    FID_IOIMPLIEDDO_ENTRY, "loop_var_addr",
01859       12, MTYPE_U4,    16, MTYPE_U8,    FID_IOIMPLIEDDO_ENTRY, "begin_cnt_addr",
01860       16, MTYPE_U4,    24, MTYPE_U8,    FID_IOIMPLIEDDO_ENTRY, "end_cnt__addr",
01861       20, MTYPE_U4,    32, MTYPE_U8,    FID_IOIMPLIEDDO_ENTRY, "inc_cnt_addr",
01862 };
01863 
01864 
01865 #define FIO_OFFSET(i) ((Pointer_Size == 4) ? fiostruct_info[i].offset32 \
01866             : fiostruct_info[i].offset64)
01867 #define FIO_TYPE(i) ((Pointer_Size == 4) ? fiostruct_info[i].type32 \
01868             : fiostruct_info[i].type64)
01869 #define FIO_SIZE(i) ((Pointer_Size == 4) ? fiostructid_info[i].size32 \
01870             : fiostructid_info[i].size64)
01871 #define Int_Type        ((Pointer_Size == 4) ? MTYPE_I4 : MTYPE_I8)
01872 #define OPC_IntWord ((Pointer_Size == 4) ? OPC_I4INTCONST : OPC_I8INTCONST)
01873 
01874 
01875 static WN *extract_calls ( WN *, WN * );
01876 static INT32
01877 lower_f77_io_items ( WN *, WN *, WN *, WN*, WN*, FIOOPER, BOOL, INT32 *,
01878       INT32, INT32 );
01879 static void
01880 lower_f77_record_items (WN *, WN *, WN *, WN *, WN *, WN *,
01881       FIOOPER, ST **, TY_IDX*, INT32 *, FLD_HANDLE&,
01882       INT32 *, INT32 *, INT32, TY_IDX , INT64);
01883 
01884 /*  The following table gives the I/O mask code for each of the basic types.  */
01885 
01886 static INT32 fio_maskcode [MTYPE_LAST + 1] = {
01887   0,  /* MTYPE_UNKNOWN */
01888   0,  /* MTYPE_B */
01889   1,  /* MTYPE_I1 */
01890   2,  /* MTYPE_I2 */
01891   0,  /* MTYPE_I4 */
01892   3,  /* MTYPE_I8 */
01893   1,  /* MTYPE_U1 */
01894   2,  /* MTYPE_U2 */
01895   0,  /* MTYPE_U4 */
01896   3,  /* MTYPE_U8 */
01897   0,  /* MTYPE_F4 */
01898   0,  /* MTYPE_F8 */
01899   0,  /* MTYPE_F10 */
01900   0,  /* MTYPE_F16 */
01901   0,  /* MTYPE_STRING */
01902   0,  /* MTYPE_FQ */
01903   0,  /* MTYPE_M */
01904   0,  /* MTYPE_C4 */
01905   0,  /* MTYPE_C8 */
01906   0,  /* MTYPE_CQ */
01907   0 /* MTYPE_V */
01908 };
01909 
01910 
01911 
01912 typedef enum {
01913    ARB_UBOUND,
01914    ARB_LBOUND,
01915    ARB_STRIDE
01916 } arb_enum;
01917 
01918 static WN *
01919 Get_ST_Ldid(ST_IDX st)
01920 {
01921    WN *r;
01922    TY_IDX ty;
01923    ty = ST_type(st);
01924    r = WN_Ldid(TY_mtype(ty),0,st,ty);
01925    return (r);
01926 }
01927 
01928 static void io_set_addr_passed_flag(ST *st) {
01929    if ( WHIRL_Addr_Passed_On ) 
01930       Set_ST_addr_passed(st);
01931    if (WHIRL_Addr_Saved_For_Passed_On)
01932       Set_ST_addr_saved(st);
01933 }
01934 
01935 static void io_set_addr_saved_flag(ST *st) {
01936    if (WHIRL_Addr_Saved_On)
01937       Set_ST_addr_saved(st);
01938 }
01939 
01940 // Utility to return as a WHIRL node the value of an ARB
01941 static WN *
01942 Get_ARB_WN(const ARB_HANDLE arb, arb_enum whattoget)
01943 {
01944    switch (whattoget) {
01945     case ARB_UBOUND:
01946        if (ARB_const_ubnd(arb)) {
01947     return (WN_Intconst(MTYPE_I8,ARB_ubnd_val(arb)));
01948        } else {
01949     return (Get_ST_Ldid(ARB_ubnd_var(arb)));
01950        }
01951     case ARB_LBOUND:
01952        if (ARB_const_lbnd(arb)) {
01953     return (WN_Intconst(MTYPE_I8,ARB_lbnd_val(arb)));
01954        } else {
01955     return (Get_ST_Ldid(ARB_lbnd_var(arb)));
01956        }
01957     case ARB_STRIDE:
01958        if (ARB_const_stride(arb)) {
01959     return (WN_Intconst(MTYPE_I8,ARB_stride_val(arb)));
01960        } else {
01961     return (Get_ST_Ldid(ARB_stride_var(arb)));
01962        }
01963    }
01964    Fail_FmtAssertion("bad arguments to Get_ARB_WN");
01965    return NULL;
01966 }
01967 
01968 
01969 static TY_IDX
01970 Make_Simple_Array_Type (const char *name, INT32 n_elems, TY_IDX elem_ty)
01971 {
01972     TY_IDX ty_idx;
01973     TY& ty = New_TY (ty_idx);
01974 
01975     UINT32 elem_size = TY_size (elem_ty);
01976 
01977     TY_Init (ty, elem_size * n_elems, KIND_ARRAY, MTYPE_UNKNOWN,
01978        Save_Str (name));
01979     Set_TY_etype (ty, elem_ty);
01980 
01981     ARB_HANDLE arb = New_ARB ();
01982     ARB_Init (arb, 0, n_elems - 1, elem_size);
01983     Set_ARB_first_dimen (arb);
01984     Set_ARB_last_dimen (arb);
01985 
01986     Set_TY_arb (ty, arb);
01987     Set_TY_align_exp (ty_idx, TY_align_exp (elem_ty));
01988     return ty_idx;
01989 }
01990 
01991 
01992 static void
01993 Alloc_More_For_Dummy_Array(void)
01994 {
01995    if (fio_dummy_max == 0) {
01996       fio_dummy_max = 32;
01997       fio_dummy_ref = (BOOL *)  malloc (sizeof(BOOL) * fio_dummy_max);
01998       fio_dummy_st = (ST **) malloc (sizeof(ST *) * fio_dummy_max);
01999       fio_dummy_tyidx = (TY_IDX *) malloc (sizeof(TY_IDX *) * fio_dummy_max);
02000       fio_dummy_ofst = (WN_OFFSET *) malloc (sizeof(WN_OFFSET) *
02001                                                     fio_dummy_max);
02002    } else {
02003       fio_dummy_max = fio_dummy_max + (fio_dummy_max >> 1);
02004       fio_dummy_ref = (BOOL *) realloc (fio_dummy_ref,
02005                                     sizeof(BOOL) * fio_dummy_max);
02006       fio_dummy_st = (ST **) realloc (fio_dummy_st,
02007                                       sizeof(ST *) * fio_dummy_max);
02008       fio_dummy_tyidx = (TY_IDX *) realloc (fio_dummy_tyidx,
02009                                       sizeof(TY_IDX *) * fio_dummy_max);
02010       fio_dummy_ofst = (WN_OFFSET *) realloc (fio_dummy_ofst,
02011                                      sizeof(WN_OFFSET) * fio_dummy_max);
02012    }
02013 }
02014 
02015 static void
02016 Add_To_Dummy_List(WN *dummy) 
02017 {
02018     while ((WN_operator(dummy) != OPR_LDA) && 
02019      (WN_operator(dummy) != OPR_LDID))
02020   if ((WN_operator(dummy) == OPR_ADD) &&
02021       (WN_operator(WN_kid0(dummy)) == OPR_MPY))
02022       dummy = WN_kid1(dummy);
02023   else
02024       dummy = WN_kid0(dummy);
02025 
02026     if (fio_dummy_count == fio_dummy_max)
02027   Alloc_More_For_Dummy_Array();
02028 
02029     ST* st = WN_st (dummy);
02030     fio_dummy_ref[fio_dummy_count]    = WN_operator(dummy) == OPR_LDA;
02031     fio_dummy_st[fio_dummy_count]     = st;
02032     fio_dummy_tyidx[fio_dummy_count]  = WN_ty(dummy);
02033     fio_dummy_ofst[fio_dummy_count++] = WN_offset(dummy);
02034     if (ST_class(st) == CLASS_VAR)
02035        io_set_addr_saved_flag(st);
02036 }
02037 
02038 static char *
02039 Remove_Trailing_Blanks(char *s)
02040 {
02041   char *c;
02042   c = s + strlen(s) - 1;
02043   while (*c == ' ')
02044     c--;
02045   c++;
02046   *c = '\0';
02047   return s;
02048 }
02049 /*===================================================
02050  *
02051  * Find_array_TY
02052  *
02053  * Given a TY, find its array ty, ie: the bottom
02054  * of any KIND_POINTERS to a KIND_ARRAY etc...
02055  * Given a scalar, just hand it back..
02056  *
02057  ====================================================
02058 */
02059 extern TY_IDX 
02060 Find_array_TY(TY_IDX  ty)
02061 {
02062   TY_IDX  rty ;
02063 
02064   switch(TY_kind(ty)) {
02065   case KIND_ARRAY:
02066   case KIND_SCALAR:
02067   case KIND_STRUCT:
02068   case KIND_FUNCTION:
02069   case KIND_VOID:
02070     rty = ty;
02071     break;
02072 
02073   case KIND_POINTER:
02074     rty = Find_array_TY(TY_pointed(Ty_Table[ty])) ;
02075     break;
02076 
02077   default:
02078     DevAssert((0),("Odd array ty"));
02079     break;
02080   }
02081 
02082   return(rty);
02083 }
02084 
02085 /*===================================================
02086  *
02087  * Find_scalar_TY
02088  *
02089  * Given a TY, find its scalar ty, ie: the bottom
02090  * of any KIND_ARRAYs
02091  *
02092  ====================================================
02093 */
02094 extern TY_IDX 
02095 Find_scalar_TY(TY_IDX  ty)
02096 {
02097   TY_IDX  rty ;
02098 
02099   switch(TY_kind(ty)) {
02100 
02101   case KIND_VOID:
02102   case KIND_SCALAR:
02103   case KIND_STRUCT:
02104   case KIND_POINTER:
02105   case KIND_FUNCTION:
02106     rty = ty;
02107     break;
02108 
02109   case KIND_ARRAY:
02110     rty = Find_scalar_TY(TY_AR_etype(ty)) ;
02111     break;
02112 
02113   default:
02114     DevAssert((0),("Odd ty"));
02115     break;
02116   }
02117 
02118   return(rty);
02119 }
02120 /* ====================================================================
02121  *
02122  * WN *create_lda_of_temp(WN *block, WN *tree, TY_IDX ty)
02123  *
02124  * Store tree into a temp and create lda of that temp
02125  *
02126  * ==================================================================== */
02127 static WN *create_lda_of_temp(WN *block, WN *tree, TY_IDX ty)
02128 {
02129       TYPE_ID   type;
02130       ST  *st;
02131       WN  *stid;
02132 
02133       Is_True((WN_operator_is(tree, OPR_PARM)==FALSE),("bad parm"));
02134       /*
02135        *  store value to an addressible temporary, and take the address of that
02136        */
02137       if (ty)
02138          type = TY_mtype(ty);
02139       else
02140          type = WN_rtype(tree);
02141 
02142       st = Gen_Temp_Symbol( MTYPE_To_TY(type), "complex-temp-expr");
02143       stid = WN_Stid (type, 0, st, ST_type(st), WN_COPY_Tree(tree));
02144       WN_INSERT_BlockLast(block, stid);
02145 
02146       return WN_Lda(Pointer_type, WN_store_offset(stid), st);
02147 }
02148 
02149 /* ====================================================================
02150  *
02151  * WN *create_pointer_to_node(WN *block, WN *tree, TY_IDX ty, BOOL deref)
02152  *
02153  * Return the address of tree.
02154  *  for ILOAD and LDID use address directly if desc type and rtype is same.
02155  *  if a ty is passed, rtype is determined from this ty rather than from the
02156  *  rtype of the whirl node we are dealing with
02157  *
02158  *      for ISTORE we can use the address directly
02159  *      for LDID/STID we can create an LDA
02160  *      otherwise we need to create an addressable temp, store to it
02161  *      and try again.
02162  *  
02163  *  When 'deref' is FALSE, then for an LDA and ARRAY node, we will still
02164  *  store into a temp and pass the address of the temp; this is needed for
02165  *  example in write(*,*) loc(x); we don't want the library to dereference
02166  *  x, we just want to print the address of x.
02167  * ==================================================================== */
02168 
02169 static WN *create_pointer_to_node(WN *block, WN *tree, TY_IDX ty, BOOL deref)
02170 {
02171 
02172   TYPE_ID rtype;
02173   TYPE_ID desc;
02174   WN  *add;
02175 
02176   /* Need to deal with the INTRINSIC_OP */
02177   tree = extract_calls( block, tree );
02178   switch (WN_operator(tree))
02179   {
02180   case OPR_ILOAD:
02181       if (ty)
02182   rtype = TY_mtype( ty );
02183      else
02184         rtype = WN_rtype(tree);
02185 
02186       desc = WN_desc(tree);
02187 
02188       if (rtype == desc) {
02189    add = WN_Add(Pointer_Mtype,WN_kid0(tree),
02190           WN_Intconst(Pointer_Mtype,WN_load_offset(tree)));
02191    return (add);
02192       } else {
02193          return create_lda_of_temp(block, tree, ty); 
02194       }
02195     
02196   case OPR_ISTORE:
02197     return WN_kid1(tree);
02198 
02199   case OPR_LDID:
02200       if ((Language == LANG_F77) && TY_is_character(Ty_Table [ty])) {
02201    /* When the incoming tree is an INTRIN_OP to handle concatenation
02202       of strings extract_calls could return with an LDID that is the 
02203       address of a string; PV 550165; in this situation we can just
02204       return what extract_calls gave us*/
02205    return tree;
02206       }
02207       if (ty)
02208   rtype = TY_mtype( ty );
02209       else
02210         rtype = WN_rtype(tree);
02211 
02212       desc = WN_desc(tree);
02213       if ((ST_class(WN_st(tree)) != CLASS_PREG) &&
02214     (rtype == desc)) {
02215          return WN_Lda(Pointer_type, WN_load_offset(tree), WN_st(tree));
02216       } else {
02217          return create_lda_of_temp(block, tree, ty);
02218       }
02219 
02220   case OPR_STID:
02221     return WN_Lda(Pointer_type, WN_store_offset(tree), WN_st(tree));
02222 
02223   case OPR_ARRAY:
02224   case OPR_LDA:
02225     if (deref) {
02226        return tree;
02227     } else {
02228       return create_lda_of_temp(block, tree, ty);
02229     }
02230 
02231   case OPR_ADD:
02232 
02233 #ifdef KEY
02234     // Under -IPA, different PUs may have different src_lang, but the driver
02235     // always passes -LANG:=ansi_c
02236     if (!PU_f90_lang(Get_Current_PU())) {
02237 #else
02238     if (Language != LANG_F90) {
02239 #endif // KEY
02240        /* If address expression, return the tree */
02241   
02242        if (WN_opcode(tree) == OPC_U4ADD || WN_opcode(tree) == OPC_U8ADD)
02243            return(tree);
02244        else 
02245            return create_lda_of_temp(block, tree, ty);
02246     } else {
02247        return create_lda_of_temp(block, tree, ty);
02248     }
02249 
02250   case OPR_INTRINSIC_OP:
02251     {
02252       /* If it is an INTRINSIC_OP to get a VALTMP then cannot load that
02253       ** value and store in a temp.  Need to get kid(0) instead.
02254       */
02255     }
02256   default:
02257        return create_lda_of_temp(block, tree, ty);  
02258   }
02259 }
02260 
02261 
02262 /*===================================================
02263  *
02264  * Type_is_logical
02265  *
02266  * return T if this is a logical TY
02267  *
02268  ====================================================
02269 */
02270 extern BOOL
02271 Type_is_logical(TY_IDX  ty)
02272 {
02273   TY_IDX  ts ;
02274 
02275 #ifdef KEY
02276   // Under -IPA, different PUs may have different src_lang, but the driver
02277   // always passes -LANG:=ansi_c
02278   if (!PU_f90_lang(Get_Current_PU())) {
02279 #else
02280   if (Language != LANG_F90) {
02281 #endif // KEY
02282     ts = Find_array_TY(ty);
02283     ts = Find_scalar_TY(ts);
02284     return (TY_is_logical(Ty_Table[ts]));
02285   } else {
02286     return (TY_is_logical(Ty_Table[ty]));
02287   }
02288 }
02289 
02290 /*  This routine creates a global type for the selected I/O structure.    */
02291 /*  These struct types are only created on demand when they are needed    */
02292 /*  to support the creation of a local struct.  Once created, they have   */
02293 /*  persistence throughout compiling the entire source file.  All of the  */
02294 /*  information needed to create the structs (size, name, fields, etc)    */
02295 /*  is contained in the fiostructid_info and fiostruct_info tables.       */ 
02296 /*  This routine also creates a global type which is a pointer to the     */
02297 /*  appropriate structure type.             */
02298 
02299 static void Make_IoStruct_TY ( FIOSTRUCTID id )
02300 {
02301     INT32 /* FIOSTRUCT */ i;
02302     FIOSTRUCT first = fiostructid_info[id].first;
02303     FIOSTRUCT last = fiostructid_info[id].last;
02304 
02305     /* Create the structure TY and fill in the appropriate fields. */
02306 
02307     /*
02308      ** If it is an iolist then make the type local so not to polute the
02309      ** global space with thousands of local types
02310      */
02311 
02312     TY_IDX ty_idx;
02313     TY& ty = New_TY (ty_idx);
02314 
02315     if (id == FID_CRAY_IOLIST) {
02316   sprintf( seq_buff, "_%d", local_sequence );
02317   TY_Init (ty, (Pointer_Size == 4 ? fiostructid_info[id].size32 :
02318           fiostructid_info[id].size64),
02319            KIND_STRUCT, MTYPE_M,
02320      Save_Str2 (fiostructid_info[id].name, seq_buff));
02321     } else {
02322   TY_Init (ty, (Pointer_Size == 4 ? fiostructid_info[id].size32 :
02323           fiostructid_info[id].size64),
02324      KIND_STRUCT, MTYPE_M,
02325      Save_Str (fiostructid_info[id].name));
02326     }
02327     
02328     if (current_io_library == IOLIB_MIPS) {
02329   if (id != FID_KEYSPEC)
02330       Set_TY_align (ty_idx, MTYPE_align_req(MTYPE_I8));
02331   else
02332       Set_TY_align (ty_idx, MTYPE_align_req(MTYPE_I2));
02333     } else {
02334   Set_TY_align (ty_idx, MTYPE_align_req(MTYPE_I8));
02335     }
02336 
02337     /* Create all of the subordinate field entries. */
02338     FLD_HANDLE fld;
02339 
02340     for (i = first; i <= last; ++i) {
02341   fld = New_FLD ();
02342   if (Pointer_Size == 4) {
02343       FLD_Init (fld, Save_Str (fiostruct_info[i].name),
02344           Be_Type_Tbl (fiostruct_info[i].type32),
02345           fiostruct_info[i].offset32);
02346   } else
02347       FLD_Init (fld, Save_Str (fiostruct_info[i].name),
02348           Be_Type_Tbl (fiostruct_info[i].type64),
02349           fiostruct_info[i].offset64);
02350     }
02351     Set_FLD_last_field (fld);
02352     Set_TY_fld (ty, FLD_HANDLE (fld.Idx () - (last - first)));
02353 
02354 
02355     /* Create the structure pointer TY and fill in the appropriate fields. */
02356 
02357     /*
02358      ** If it is an iolist then make the type local so not to polute the
02359      ** global space with thousands of local types
02360      */
02361     TY_IDX tyx_idx;
02362     TY& tyx = New_TY (tyx_idx);
02363     TY_Init (tyx, Pointer_Size, KIND_POINTER, Pointer_Mtype,
02364        Save_Str (fiostructid_info[id].name_ptr));
02365     Set_TY_align (tyx_idx, Pointer_Size);
02366     Set_TY_pointed (tyx, ty_idx);
02367     fiostruct_ty[id] = ty_idx;
02368 }
02369 
02370 
02371 /*  This routine returns the ST for a local structure of the requested type.  */
02372 /*  If this is the first time in this PU, all saved ST pointers are cleared.  */
02373 /*  If the ST already exists, just return it.  If the ST doesn't exist then   */
02374 /*  create it.  If the global type doesn't exist, create that.  Finally, if   */
02375 /*  requested, generate code to clear the structure.            */
02376 
02377 static ST * Get_IoStruct_ST ( WN * block, FIOSTRUCTID id, BOOL clear )
02378 {
02379   INT32 i;
02380   ST * st;
02381   WN * wn;
02382 
02383   /*  Clear ST pointers in fiostruct_st when first entering a new PU.  */
02384 
02385   if (Current_pu != fio_current_pu) {
02386     local_sequence = 1;
02387     fio_current_pu = Current_pu;
02388     for (i=FIOSTRUCTID_FIRST; i<=FIOSTRUCTID_LAST; i++)
02389       fiostruct_st[i] = NULL;
02390   }
02391 
02392   /*  If a (previously created) ST doesn't exist, create it.  */
02393 
02394   if ((st = fiostruct_st[id]) == NULL) {
02395 
02396     /*  Get the global struct TY if it exists, otherwise create it.  */
02397     /* For iolist, always needs a new type since the struture is 
02398     ** different each time */
02399     if ((id == FID_CRAY_IOLIST) || 
02400   (fiostruct_ty[id] == (TY_IDX) 0))
02401       Make_IoStruct_TY ( id );
02402 
02403     /*  Create the local ST and enter into the local symbol table and save  */
02404     /*  the pointer.  */
02405 
02406     st = New_ST ();
02407     ST_Init (st, 0, CLASS_VAR, SCLASS_AUTO, EXPORT_LOCAL, fiostruct_ty[id]);
02408     io_set_addr_passed_flag(st);
02409     /* 
02410     ** Never set fiostruct_st for the following cases which use a
02411     ** local ST each time
02412     */
02413     if ((id != FID_CRAY_FCD) && (id != FID_CRAY_IOLIST) 
02414   && (id != FID_CRAY_DOPEVEC)) {
02415   Set_ST_name_idx (st, Save_Str ( fiostructid_info[id].name_local ));
02416   fiostruct_st[id] = st;
02417     } else {
02418   sprintf( seq_buff, "_%d", local_sequence++ );
02419   Set_ST_name_idx (st, Save_Str2( fiostructid_info[id].name_local,
02420              seq_buff ));
02421     }
02422   }
02423 
02424   /*  Clear the structure if requested.  */
02425 
02426   if (clear) {
02427     if (Pointer_Size == 4)
02428       wn = WN_CreateMstore ( 0, TY_pointer(ST_type(st)),
02429      WN_CreateIntconst ( OPC_U8INTCONST, 0 ),
02430      WN_CreateLda ( OPC_U4LDA, 0, TY_pointer(ST_type(st)), st),
02431      WN_CreateIntconst ( OPC_U4INTCONST, TY_size(ST_type(st)) ));
02432     else
02433       wn = WN_CreateMstore ( 0, TY_pointer(ST_type(st)),
02434      WN_CreateIntconst ( OPC_U8INTCONST, 0 ),
02435      WN_CreateLda ( OPC_U8LDA, 0, TY_pointer(ST_type(st)), st),
02436      WN_CreateIntconst ( OPC_U8INTCONST, TY_size(ST_type(st)) ));
02437     WN_INSERT_BlockLast ( block, wn );
02438   }
02439 
02440   return (st);
02441 }
02442 
02443 /*  This routine returns an ST for a local array of key struct elements.      */
02444 /*  If the global key struct type doesn't exist, create it.  No attempt to    */
02445 /*  share local arrays is made, usually they will be of different sizes       */
02446 /*  anyway.                                                                   */
02447 
02448 static ST * Get_KeyStruct_ST ( INT32 nitems )
02449 {
02450   INT32 nelem = nitems/3;
02451   char  ty_name[30];
02452   char  ptr_name[30];
02453   char  st_name[30];
02454 
02455   /*  If the global key struct TY doesn't exist, create it.  */
02456 
02457   if (fiostruct_ty[FID_KEYSPEC] == (TY_IDX) 0)
02458     Make_IoStruct_TY ( FID_KEYSPEC );
02459 
02460   /*  Create a local TY which is an array of key structs.  */
02461 
02462   TY_IDX ty_idx;
02463   TY& ty = New_TY (ty_idx);
02464   sprintf( ty_name, ".key_type.%d", nelem );
02465   TY_Init (ty, nelem * TY_size(fiostruct_ty[FID_KEYSPEC]), KIND_ARRAY,
02466      MTYPE_UNKNOWN, Save_Str ( ty_name ));
02467   Set_TY_etype (ty, fiostruct_ty[FID_KEYSPEC]);
02468   Set_TY_align (ty_idx, MTYPE_align_req(MTYPE_I8));
02469 
02470   ARB_HANDLE arb = New_ARB ();
02471   ARB_Init (arb, 0, nelem - 1, TY_size(fiostruct_ty[FID_KEYSPEC]));
02472   Set_ARB_first_dimen (arb);
02473   Set_ARB_last_dimen (arb);
02474 
02475   Set_TY_arb (ty, arb);
02476 
02477 
02478   /*  Create the local array pointer TY. */
02479 
02480   TY_IDX tyx_idx;
02481   TY& tyx = New_TY (tyx_idx);
02482   sprintf( ptr_name, ".key_pointer.%d", nelem );
02483   TY_Init (tyx, Pointer_Size, KIND_POINTER, Pointer_Mtype,
02484      Save_Str (ptr_name));
02485   Set_TY_align (tyx_idx, Pointer_Size);
02486 
02487   /*  Complete the TY entries and enter them in the local symbol table.  */
02488 
02489   Set_TY_pointed (tyx, ty_idx);
02490 
02491   /*  Create the local ST.  */
02492 
02493   ST* st = New_ST ();
02494   sprintf( st_name, ".key_array.%d", nelem );
02495   ST_Init (st, Save_Str (st_name), CLASS_VAR, SCLASS_AUTO, EXPORT_LOCAL,
02496      ty_idx);
02497 
02498   io_set_addr_saved_flag(st);
02499   fiostruct_st[ FID_KEYSPEC ] = st;
02500 
02501   return (st);
02502 }
02503 
02504 
02505 /*  This routines creates a local ST for a variable of type pointer to       */
02506 /*  save the the UNIT structure pointer. between the different steps of a    */
02507 /*  multiple-step I/O operations such as READ/WRITE.   This is needed        */
02508 /*  in the case of MP I/O as we can no longer depend on a static variable    */
02509 /*  in the runtime library to preserve the setup of the initialization       */
02510 /*  step.                                                                    */
02511 
02512 static ST * Get_UnitPointer_ST ( void )
02513 {
02514   static ST    * mpunit_ptr_var;
02515 
02516   if (Current_pu  != mp_fio_current_pu) {
02517     mp_fio_current_pu = Current_pu;
02518     mpunit_ptr_var = NULL;
02519   }
02520 
02521   if (mpunit_ptr_var)
02522     return( mpunit_ptr_var );
02523 
02524   static TY_IDX mpunit_ptr_ty_idx;
02525 
02526   if (mpunit_ptr_ty_idx == 0) {
02527       TY& mpunit_ptr_ty = New_TY (mpunit_ptr_ty_idx);
02528       TY_Init (mpunit_ptr_ty, Pointer_Size, KIND_POINTER, Pointer_Mtype, 
02529          Save_Str( ".mpunit_pointer" ));
02530       Set_TY_pointed (mpunit_ptr_ty, Be_Type_Tbl(MTYPE_I4));
02531       Set_TY_align (mpunit_ptr_ty_idx, Pointer_Size);
02532   }
02533 
02534   mpunit_ptr_var = New_ST ();
02535   ST_Init (mpunit_ptr_var, Save_Str (".mpunit_var"), CLASS_VAR,
02536      SCLASS_AUTO, EXPORT_LOCAL, mpunit_ptr_ty_idx);
02537   io_set_addr_saved_flag(mpunit_ptr_var);
02538   return mpunit_ptr_var;
02539 }
02540 
02541 
02542 static void
02543 Init_fioruntime_ty ()
02544 {
02545     TY& ty = New_TY (fioruntime_ty);
02546     TY_Init (ty, 0, KIND_FUNCTION, MTYPE_UNKNOWN, Save_Str (".ioruntime"));
02547     Set_TY_align (fioruntime_ty, 1);
02548 #ifdef KEY
02549     ty.Set_pu_flag(TY_HAS_PROTOTYPE);
02550 #endif
02551 
02552     TYLIST_IDX tylist_idx;
02553     TYLIST& tylist = New_TYLIST (tylist_idx);
02554     Set_TY_tylist (ty, tylist_idx);
02555     Set_TYLIST_type (tylist, Be_Type_Tbl ( MTYPE_I4 ));
02556     Set_TYLIST_type (New_TYLIST (tylist_idx), 0);
02557 
02558     TY_IDX tyx_idx;
02559     TY& tyx = New_TY (tyx_idx);
02560     TY_Init (tyx, Pointer_Size, KIND_POINTER, Pointer_Mtype,
02561        Save_Str (".ioruntime_ptr"));
02562     Set_TY_pointed (tyx, fioruntime_ty);
02563 } // Init_fioruntime_ty
02564 
02565 
02566 /*  This routine creates a global ST for the requested I/O runtime routine.  */
02567 /*  If the global type of the runtime routines does not exist, it is       */
02568 /*  created.                     */
02569 
02570 static ST * Make_IoRuntime_ST ( FIOOPER op )
02571 {
02572   ST *st;
02573   char mpname[ 40 ];
02574   INT32 i;
02575 
02576   /*  Do a little validation of the requested routine.  */
02577 
02578   if (op == FIOOPER_NONE)
02579     Fail_FmtAssertion("Make_IoRuntime_ST:"
02580           " null runtime operation in I/O processing");
02581 
02582 
02583   /*  If the global type doesn't exist, create it and it's pointer type.  */
02584 
02585   if (fioruntime_ty == (TY_IDX) 0) {
02586       Init_fioruntime_ty ();
02587   }
02588   
02589   /*  Create the ST, fill in all appropriate fields */
02590 
02591   fio_sts[op] = st = New_ST (GLOBAL_SYMTAB);
02592   STR_IDX st_name;
02593   if (mp_io && (current_io_library == IOLIB_MIPS)) {
02594     strcpy (mpname, fio_names[op] );
02595     i = strlen( mpname );
02596     mpname[i] = '_'; mpname[i+1] = 'm'; mpname[i+2] = 'p'; mpname[i+3] = '\0';
02597     st_name = Save_Str ( mpname );
02598   } else {
02599     if (op == FIO_CR_OPEN && Language == LANG_F77 && current_io_library == IOLIB_CRAY)
02600        st_name = Save_Str ("_OPENF77");
02601     else
02602        st_name = Save_Str ( fio_names[op] );
02603   }
02604 
02605   PU_IDX pu_idx;
02606   PU&    pu = New_PU (pu_idx);
02607 
02608   PU_Init (pu, fioruntime_ty, CURRENT_SYMTAB);
02609 
02610   ST_Init (st, st_name, CLASS_FUNC, SCLASS_EXTERN, EXPORT_PREEMPTIBLE,
02611      TY_IDX (pu_idx));
02612 
02613   return st;
02614 
02615 }
02616 
02617 
02618 /*  This routine takes an ST and generates an OPC_U4LDA or OPC_U8LDA  */
02619 /*  node depending on pointer size.                                   */
02620 
02621 static WN * Make_IoAddr_WN ( ST * st )
02622 {
02623     WN * wn;
02624     TY_IDX ty = ST_type (st);
02625     TY_IDX ty_ptr = TY_pointer (ty);
02626 
02627     if (ty_ptr == (TY_IDX) 0) {
02628   ty_ptr = Make_Pointer_Type (ty);
02629     }
02630 
02631     if (Pointer_Size == 4)
02632   wn = WN_CreateLda ( OPC_U4LDA, 0, ty_ptr, st);
02633     else
02634   wn = WN_CreateLda ( OPC_U8LDA, 0, ty_ptr, st);
02635 
02636     io_set_addr_passed_flag(st);
02637 
02638     return (wn);
02639 }
02640 
02641 /*  This routine takes a WN and generates a PARM node over it.  */
02642 
02643 static WN * Gen_Parm_WN ( WN * wn )
02644 {
02645     OPCODE opc = WN_opcode(wn);
02646     TYPE_ID rtype = OPCODE_rtype(opc);
02647 
02648     if (rtype == MTYPE_U4 || rtype == MTYPE_U8) {
02649       wn = WN_CreateParm (rtype, wn,
02650                           (OPCODE_has_1ty(opc))?WN_ty(wn):Be_Type_Tbl(rtype),
02651                           WN_PARM_BY_REFERENCE );
02652     }
02653     else
02654       wn = WN_CreateParm ( rtype, wn, Be_Type_Tbl(rtype), WN_PARM_BY_VALUE );
02655 
02656     return (wn);
02657 }
02658 
02659 
02660 /*  This routine is the main work horse of the I/O lowerer.  Given       */
02661 /*  information about an I/O runtime routine to be called, it generates  */
02662 /*  the call and any required handling of the status return.  Note the   */
02663 /*  special handling of dummy parms.  Any user variable/constant whose   */
02664 /*  address is put in an I/O control structure could be referenced or    */
02665 /*  modified without the knowledge of the optimizer.  So a set of dummy  */
02666 /*  parms is created for each such variable and attached to each I/O     */
02667 /*  call. A similar problem exists for namelist I/O where the variables  */
02668 /*  being referenced are not "visible" in the I/O statement.  Here again */
02669 /*  dummy parms are created for these variables.       */
02670 
02671 static void Gen_Io_Calls ( WN * block, FIOOPER op, WN * iostat1, WN * iostat2,
02672          INT32 kids, WN * kid0, WN * kid1, WN * kid2,
02673          WN * kid3 )
02674 {
02675   WN * wn;
02676   INT32 i;
02677   INT32 fio_namelist_count = (namelist_node) ? WN_kid_count(namelist_node) - 2
02678                : 0;
02679 
02680   /*  Create the appropriate call node.  */
02681 
02682   if (iostat1 != NULL || iostat2 != NULL || 
02683       op == FIO_INQLENGTH)
02684     wn = WN_Create ( OPC_I4CALL, kids + fio_dummy_count + fio_namelist_count);
02685   else
02686     wn = WN_Create ( OPC_VCALL, kids + fio_dummy_count + fio_namelist_count);
02687   WN_st_idx(wn) = ST_st_idx (GET_RUNTIME_ST ( op ));
02688   WN_Set_Call_Non_Data_Mod ( wn );
02689   WN_Set_Call_Non_Data_Ref ( wn );
02690   WN_Set_Call_Parm_Mod ( wn );
02691   WN_Set_Call_Parm_Ref ( wn );
02692   if (op == FIO_CR_READ_NAMELIST || op == FIO_CR_WRITE_NAMELIST) 
02693      WN_Set_Call_Non_Parm_Ref( wn );
02694 
02695   /*  Fill in any or all function arguments to the call.  */
02696 
02697   switch (kids) {
02698     case 4:
02699       WN_kid3(wn) = Gen_Parm_WN ( kid3 );
02700     case 3:
02701       WN_kid2(wn) = Gen_Parm_WN ( kid2 );
02702     case 2:
02703       WN_kid1(wn) = Gen_Parm_WN ( kid1 );
02704     case 1:
02705       WN_kid0(wn) = Gen_Parm_WN ( kid0 );
02706     case 0:
02707       break;
02708     default:
02709       Fail_FmtAssertion("Gen_Io_Calls: unexpected number of kids (%d)"
02710       " in I/O processing", kids);
02711   }
02712 
02713   /*  Generate any dummy parms needed and attach to the call.  */
02714 
02715   for (i = 0; i < fio_dummy_count; i++) {
02716     if (ST_class(fio_dummy_st[i]) == CLASS_VAR) {
02717       io_set_addr_passed_flag(fio_dummy_st[i]);
02718     }
02719     if (fio_dummy_ref[i])
02720       WN_kid(wn, kids++) = WN_CreateParm ( Pointer_type,
02721              WN_Lda ( Pointer_type,
02722                 fio_dummy_ofst[i],
02723                 fio_dummy_st[i] ),
02724              Be_Type_Tbl(Pointer_type),
02725              WN_PARM_BY_REFERENCE |
02726              WN_PARM_DUMMY );
02727     else
02728       WN_kid(wn, kids++) = WN_CreateParm ( Pointer_type,
02729              WN_Ldid ( Pointer_type,
02730                  fio_dummy_ofst[i],
02731                  fio_dummy_st[i],
02732                  fio_dummy_tyidx[i]),
02733              Be_Type_Tbl(Pointer_type),
02734              WN_PARM_BY_REFERENCE |
02735              WN_PARM_DUMMY );
02736   }
02737 
02738   for (i = 0; i < fio_namelist_count; i++) {
02739     WN_kid(wn, kids++) = WN_CreateParm ( Pointer_type,
02740            WN_COPY_Tree (WN_kid0(WN_kid(namelist_node, i+2))),
02741            Be_Type_Tbl(Pointer_type),
02742            WN_PARM_BY_REFERENCE |
02743            WN_PARM_DUMMY );
02744   }
02745 
02746   /*  Insert the call into the statement block being created for the I/O  */
02747   /*  statement.                */
02748 
02749   WN_INSERT_BlockLast ( block, wn );
02750 
02751   /*  Add any statements needed to handle the status result.  */
02752 
02753  if (iostat1 != NULL || iostat2 != NULL)
02754     if (iostat2 == NULL)
02755       WN_INSERT_BlockLast ( block, WN_COPY_Tree ( iostat1 ) );
02756     else {
02757       WN_INSERT_BlockLast ( block, iostat2 );
02758       if (iostat1 != NULL) {
02759   WN_DELETE_Tree ( iostat1 );
02760       }
02761     }
02762 }
02763 
02764 
02765 /* This is copied from file libI77/fmt.h */
02766 #define TYUNKNOWN 0
02767 #define TYADDR 1
02768 #define TYBYTE 2
02769 #define TYSHORT 3
02770 #define TYINT 4
02771 #define TYLONGLONG 5
02772 #define TYREAL 6
02773 #define TYDREAL 7
02774 #define TYCOMPLEX 8
02775 #define TYDCOMPLEX 9
02776 #define TYLOGICAL1 10
02777 #define TYLOGICAL2 11
02778 #define TYLOGICAL4 12
02779 #define TYLOGICAL8 13
02780 #define TYCHAR 14
02781 #define TYSUBR 15
02782 #define TYSTRUCTURE 16
02783 #define TYNML 17
02784 #define TYQUAD 18
02785 #define TYQUADCOMPLEX 19
02786 #define TYQUADLONG 20
02787 
02788 
02789 static void Gen_Impld_Io_Calls ( WN * block, FIOFORMATTYPE form, 
02790          FIOITEMTYPE type, WN * iostat1, WN * impld_item, 
02791          WN *arr_item, WN * mp_unit_ptr)
02792 /* 
02793   This function generates a single call to the runtime routine do_xxxx_1dim()
02794   for implied-do loop instead of having a loop generated to do I/O on one 
02795   element at a time.  The implied-DO loop must satisfy the following
02796   conditions to be converted:
02797         - must have one and only one I/O item in the implied-do list
02798         - the item must be an array
02799         - every subscript of the array must be a simple variable
02800         - the leftmost index must be the same as the implied-do variable
02801         and all other indices must be different from the leftmost index.
02802         E.g:  (ARR(I,J), I=1,10) will be converted whereas
02803         (ARR(I,J), J=1,10) and (ARR(I,I), I=1,10) will not.
02804   - the array is not character type
02805   - there can be no nested calls in the subscript expression
02806 
02807   These cases are not converted into a single call (could be done later but
02808   not very important):
02809   - the index is not a simple variable but an expression,
02810   For example: (ARR(I+1), I = 1,10)
02811   
02812   The following arguments will be passed to the do_xxxx_1dim() runtime 
02813   routine.  Thay are all passed by reference unless otherwise indicated:
02814         1) the item type (for formatted I/O only)
02815         2) address of the array with the leftmost index replaced by
02816         constant 1.  Note that this could cause a problem once the
02817         -check_bounds option is implemented for implied-do I/O if it
02818   is done after the I/O lowering phase for this reference without
02819   considering the implied-do bounds.
02820         3) The implied-do loop variable:  Its value will be modified
02821         appropriately when the I/O is completed.   This is the main
02822   reason why we need to implement the implied-do optimization
02823   this way as the implied-do loop variable has to be defined
02824   once execution goes into the implied-do I/O.  This is especially
02825   important for READ statement where people deliberately read a
02826   very large array with implied-do loop and expect the
02827   do loop variable to hold the number of elements sucessfully read
02828   into the array before the end-of-record.   We can't set this
02829   implied-do variable if we treat the implied-do loop as an array
02830   as in fcom.
02831         4) the lower-bound of the do-loop
02832         5) the upper bound of the do-loop
02833         6) the step size
02834         7) the length of one element in the implied-do (passed by value)
02835         8) the size of the implied-do variable (passed by value)
02836 
02837   CAVEAT:
02838   -------
02839   - As noted in argument 2) above.  In the case of an array declared
02840   as ARR(20:30) for example and used in an implied-do loop 
02841   (ARR(I), I = 20,30) then this function will make a reference to
02842   ARR(1) and passes to the I/O library to be used as the base to
02843   calculate the offset.  If the check_bounds implementation generates
02844   code to check on this reference then it will cause an error where there
02845   should be none.
02846   - An array fio_types is created to map the FE types to the types
02847   defined in the Fortran I/O library.   Changes to the type table either
02848   from the FE or from the I/O library could cause serious regression if
02849   this table is not updated.
02850 */
02851 {
02852   WN * wn, *dovar;
02853   INT32 i, size;
02854   char impld_name[48];
02855   ST *tmp_st;
02856   static ST * impld_fio_sts [FIOFORMATTYPE_LAST + 1];
02857   static const char *impld_fio_names [ FIOFORMATTYPE_LAST + 1] =
02858   { "", "do_fio64", "do_uio64", "do_Lio64" };
02859   INT32 nkids;
02860   TY_IDX aty;
02861   ST *st;
02862   static INT32 fio_types[FIOITEMTYPE_LAST + 1];
02863 
02864   /* Update this static table at runtime to lessen the chance of regression
02865   ** in case the type tables are changed either in the FE or in the I/O
02866   ** library
02867   */
02868   if (fio_types[ FIT_COMPLEX16 ] == 0) {
02869     fio_types[FIOITEMTYPE_NONE] = TYUNKNOWN;  
02870     fio_types[FIT_ADDRESS4] = TYADDR;   
02871     fio_types[FIT_ADDRESS8] = TYADDR; 
02872     fio_types[FIT_CHARACTER] = TYCHAR;
02873     fio_types[FIT_INTEGER1] = TYBYTE;
02874     fio_types[FIT_INTEGER2] = TYSHORT;  
02875     fio_types[FIT_INTEGER4] = TYINT;
02876     fio_types[FIT_INTEGER8] = TYLONGLONG; 
02877     fio_types[FIT_LOGICAL1] = TYLOGICAL1;
02878     fio_types[FIT_LOGICAL2] = TYLOGICAL2;
02879     fio_types[FIT_LOGICAL4] = TYLOGICAL4;
02880     fio_types[FIT_LOGICAL8] = TYLOGICAL8;
02881     fio_types[FIT_REAL4] = TYREAL;  
02882     fio_types[FIT_REAL8] = TYDREAL;
02883     fio_types[FIT_REAL16] = TYQUAD;
02884     fio_types[FIT_COMPLEX4] = TYCOMPLEX;
02885     fio_types[FIT_COMPLEX8] = TYDCOMPLEX; 
02886     fio_types[FIT_COMPLEX16] = TYQUADCOMPLEX;
02887     fio_types[FIT_RECORD] = TYSTRUCTURE;
02888   }
02889 
02890   /*  Create the appropriate call node.  */
02891   wn = WN_Create ( OPC_I4CALL, 7 + (mp_unit_ptr ? 1 : 0)
02892       + (form == FFT_UNFORMAT ? 0 : 1) );
02893   if (impld_fio_sts[form] == NULL) {
02894   
02895     /*  Do a little validation of the requested routine.  */
02896   
02897     /*  If the global type doesn't exist, create it and it's pointer type.  */
02898 
02899     if (fioruntime_ty == (TY_IDX) 0) {
02900 
02901       Init_fioruntime_ty ();
02902 
02903     }
02904 
02905     /*  Create the ST, fill in all appropriate fields and enter into the  */
02906     /*  global symbol table. */
02907 
02908     strcpy( impld_name, impld_fio_names[form] );
02909     i = strlen( impld_name );
02910     if (mp_unit_ptr) {
02911       impld_name[i] = '_'; impld_name[i+1] = 'm'; impld_name[i+2] = 'p'; 
02912       strcpy( &impld_name[i+3], "_1dim" );
02913     } else {
02914       strcpy( &impld_name[i], "_1dim" );
02915     }
02916     impld_fio_sts[form] = st = New_ST ( GLOBAL_SYMTAB );
02917 
02918     PU_IDX pu_idx;
02919     PU&    pu = New_PU (pu_idx);
02920 
02921     PU_Init (pu, fioruntime_ty, CURRENT_SYMTAB);
02922 
02923     ST_Init ( st, Save_Str ( impld_name ), CLASS_FUNC, SCLASS_EXTERN,
02924               EXPORT_PREEMPTIBLE, (TY_IDX) pu_idx);
02925     WN_st_idx (wn) =  ST_st_idx (st);
02926     impld_fio_sts[form] = st;
02927   } else
02928     WN_st_idx (wn) = ST_st_idx (impld_fio_sts[form]);
02929 
02930   WN_Set_Call_Non_Data_Mod ( wn );
02931   WN_Set_Call_Non_Data_Ref ( wn );
02932   WN_Set_Call_Parm_Mod ( wn );
02933   WN_Set_Call_Parm_Ref ( wn );
02934 
02935   /*  Fill in any or all function arguments to the call.  */
02936 
02937   nkids = 0;
02938   switch (form) {
02939     case FFT_FORMAT   :
02940     case FFT_LIST     :
02941       /* For Formatted & List-directed, first argument is the element type */
02942       tmp_st = Gen_Temp_Symbol( Be_Type_Tbl(MTYPE_I4), "io_item_type" );
02943       WN_INSERT_BlockLast ( block, WN_CreateStid( OPC_I4STID, 0, tmp_st,
02944       Be_Type_Tbl(MTYPE_I4), 
02945       WN_CreateIntconst( OPC_I4INTCONST, fio_types[type] )));
02946       WN_kid(wn, nkids++) = Gen_Parm_WN ( Make_IoAddr_WN( tmp_st ) );
02947     case FFT_UNFORMAT :
02948 
02949       /* Second/First argument is the array element */
02950       WN_kid(wn, nkids++) = Gen_Parm_WN ( arr_item );
02951 
02952       /* Third/Second argument is the Implied-do variables */
02953       dovar = WN_COPY_Tree(WN_index (impld_item));
02954       WN_kid(wn, nkids++) = Gen_Parm_WN( Make_IoAddr_WN( WN_st( dovar ) ) );
02955 
02956       /* Fourth/third argument is the lower bound */
02957       tmp_st = Gen_Temp_Symbol( Be_Type_Tbl(
02958     (Pointer_Size == 4) ? MTYPE_I4 : MTYPE_I8), "lower_bound" );
02959       WN_INSERT_BlockLast ( block, WN_CreateStid( 
02960     (Pointer_Size == 4) ? OPC_I4STID : OPC_I8STID, 0, tmp_st,
02961         Be_Type_Tbl(
02962     (Pointer_Size == 4) ? MTYPE_I4 : MTYPE_I8), 
02963         WN_COPY_Tree(WN_start(impld_item))));
02964       WN_kid(wn, nkids++) = Gen_Parm_WN( Make_IoAddr_WN( tmp_st ) );
02965 
02966       /* Fifth/Fourth argument is the upper bound */
02967       tmp_st = Gen_Temp_Symbol( Be_Type_Tbl(
02968     (Pointer_Size == 4) ? MTYPE_I4 : MTYPE_I8), "upper_bound" );
02969       WN_INSERT_BlockLast ( block, WN_CreateStid( 
02970     (Pointer_Size == 4) ? OPC_I4STID : OPC_I8STID, 0, tmp_st,
02971         Be_Type_Tbl(
02972     (Pointer_Size == 4) ? MTYPE_I4 : MTYPE_I8), 
02973         WN_COPY_Tree(WN_end(impld_item))));
02974       WN_kid(wn, nkids++) = Gen_Parm_WN( Make_IoAddr_WN( tmp_st ) );
02975 
02976       /* Sixth/Fifth argument is the step */
02977       tmp_st = Gen_Temp_Symbol( Be_Type_Tbl(
02978     (Pointer_Size == 4) ? MTYPE_I4 : MTYPE_I8), "do_step" );
02979       WN_INSERT_BlockLast ( block, WN_CreateStid( 
02980     (Pointer_Size == 4) ? OPC_I4STID : OPC_I8STID, 0, tmp_st,
02981         Be_Type_Tbl(
02982     (Pointer_Size == 4) ? MTYPE_I4 : MTYPE_I8), 
02983         WN_COPY_Tree(WN_step(impld_item))));
02984       WN_kid(wn, nkids++) = Gen_Parm_WN( Make_IoAddr_WN( tmp_st ) );
02985 
02986       /* Seventh/Sixth argument is the mp_unit_ptr if needed */
02987       if (mp_unit_ptr) {
02988   WN_kid(wn, nkids++) = Gen_Parm_WN( mp_unit_ptr );
02989       }
02990 
02991       /* Eighth/Seventh argument is the size of the array element, 
02992    passed by value */
02993       aty = TY_pointed( WN_ty( WN_kid0(arr_item) ) );
02994       size = TY_size( TY_AR_etype(aty) );
02995       WN_kid(wn, nkids++) = Gen_Parm_WN( 
02996       WN_CreateIntconst ( OPC_I4INTCONST, size ) );
02997 
02998       /* Ninth/Eighth argument is the size of the implied-do variable, 
02999   passed by value */
03000       size = TY_size( Ty_Table[ ST_type( WN_st( dovar) ) ]);
03001       WN_kid(wn, nkids++) = Gen_Parm_WN( 
03002       WN_CreateIntconst ( OPC_I4INTCONST, size ) );
03003       break;
03004     default:
03005       Fail_FmtAssertion("Gen_Impld_Io_Calls: illegal format type (%d)"
03006       " in I/O processing", form);
03007   }
03008 
03009   /*  Insert the call into the statement block being created for the I/O  */
03010   /*  statement.                */
03011 
03012   WN_INSERT_BlockLast ( block, wn );
03013 
03014   /*  Add any statements needed to handle the status result.  */
03015 
03016  if (iostat1 != NULL)
03017    WN_INSERT_BlockLast ( block, WN_COPY_Tree ( iostat1 ) );
03018 }
03019 
03020 /*  This routine is one of a set to manage the structures passed between    */
03021 /*  user code and the I/O runtime routines.  This routine will take an      */
03022 /*  integer constant value and put it at the specified offset within the
03023     structure */
03024 
03025 static void Gen_Iolist_PutFieldConst ( WN * block, ST * st, INT32 foffset, 
03026                                        INT32 ftype, INT64 value )
03027 {
03028   WN * wn = NULL;
03029 
03030   /*  Generate an appropriate INTCONST node and store it into the structure  */
03031   /*  field.                                                                 */
03032 
03033   if (ftype == MTYPE_I4)
03034     wn = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03035          WN_CreateIntconst ( OPC_I4INTCONST, value ));
03036   else if (ftype == MTYPE_U4)
03037     wn = WN_CreateStid ( OPC_U4STID, foffset, st, Be_Type_Tbl(MTYPE_U4),
03038          WN_CreateIntconst ( OPC_U4INTCONST, value ));
03039   else if (ftype == MTYPE_I8)
03040     wn = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03041          WN_CreateIntconst ( OPC_I8INTCONST, value ));
03042   else if (ftype == MTYPE_U8)
03043     wn = WN_CreateStid ( OPC_U8STID, foffset, st, Be_Type_Tbl(MTYPE_U8),
03044          WN_CreateIntconst ( OPC_U8INTCONST, value ));
03045   else
03046     Fail_FmtAssertion("Gen_Iolist_PutFieldConst: unexpected field type (%s) "
03047           "in I/O processing", MTYPE_name(ftype));
03048 
03049   /*  Add the generated load/store into the statement block being created  */
03050   /*  for the I/O statement.                                               */
03051 
03052   WN_INSERT_BlockLast ( block, wn );
03053 
03054 }
03055 
03056 /*  The mload/mstore generates WHIRL based on the TY_align, which must     */
03057 /*  be correct. Create a new TY based on the alignment and offset    */
03058 
03059 static TY_IDX Create_Maligned_TY(INT32 offset, TY_IDX ty) 
03060 {
03061   INT32 align=  compute_offset_alignment(offset, TY_align(ty));
03062 
03063   if (align) {
03064     TY_IDX newTY;
03065     newTY = Make_Align_Type(MTYPE_To_TY(MTYPE_M), align);
03066 
03067     return Make_Pointer_Type(newTY, FALSE);
03068   }
03069   ty = Make_Align_Type (MTYPE_To_TY (MTYPE_M), TY_align(ty));
03070   return TY_pointer(ty);
03071 }
03072 
03073 /*  This routine is one of a set to manage the structures passed between    */
03074 /*  user code and the I/O runtime routines.  This routine will take the     */
03075 /*  value of a user expression specified by a WN and put it at the          */
03076 /*  specified offset within the I/O structures.                             */
03077 
03078 static void Gen_Iolist_PutFieldWN ( WN * block, ST * st, INT32 foffset, 
03079                                                          INT32 ftype, WN * wn ) 
03080 {
03081   WN * wnx = NULL;
03082   INT32 etype;
03083   INT32 vtype;
03084 
03085   /*  Determine kind and type of expression node.  Then convert the node as  */
03086   /*  appropriate to match the structure field type.  Finally, generate the  */
03087   /*  store into the field.                */
03088   /*                       */
03089   /*  The three cases handled are:               */
03090   /*  1) OPC_I4INTCONST or OPC_I8INTCONST - this will be used directly     */
03091   /*                or have it's size adjusted.    */
03092   /*  2) any expression tree - this will be used directly with the       */
03093   /*         addition of a CVT node if needed.       */
03094 
03095   if (WN_opcode(wn) == OPC_I4INTCONST)
03096 
03097     if (ftype == MTYPE_I4)
03098       wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03099           wn );
03100     else if (ftype == MTYPE_U4) {
03101       wnx = WN_CreateStid ( OPC_U4STID, foffset, st, Be_Type_Tbl(MTYPE_U4), 
03102       WN_CreateIntconst ( OPC_U4INTCONST, WN_const_val(wn) ));
03103       WN_Delete ( wn );
03104     } else if (ftype == MTYPE_I8) {
03105       wnx = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03106       WN_CreateIntconst ( OPC_I8INTCONST, WN_const_val(wn) ));
03107       WN_Delete ( wn );
03108     } else if (ftype == MTYPE_U8) {
03109       wnx = WN_CreateStid ( OPC_U8STID, foffset, st, Be_Type_Tbl(MTYPE_U8),
03110       WN_CreateIntconst ( OPC_U8INTCONST, WN_const_val(wn) ));
03111       WN_Delete ( wn );
03112     } else
03113       Fail_FmtAssertion("Gen_Iolist_PutFieldWN, I4INTCONST: unexpected field"
03114       " type (%s) in I/O processing", MTYPE_name(ftype));
03115 
03116   else if (WN_opcode(wn) == OPC_I8INTCONST)
03117 
03118     if (ftype == MTYPE_I4) {
03119       wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03120       WN_CreateIntconst ( OPC_I4INTCONST, WN_const_val(wn) ));
03121       WN_Delete ( wn );
03122     } else if (ftype == MTYPE_U4) {
03123       wnx = WN_CreateStid ( OPC_U4STID, foffset, st, Be_Type_Tbl(MTYPE_U4),
03124       WN_CreateIntconst ( OPC_U4INTCONST, WN_const_val(wn) ));
03125       WN_Delete ( wn );
03126     } else if (ftype == MTYPE_U8) {
03127       wnx = WN_CreateStid ( OPC_U8STID, foffset, st, Be_Type_Tbl(MTYPE_U8),
03128       WN_CreateIntconst ( OPC_U8INTCONST, WN_const_val(wn) ));
03129       WN_Delete ( wn );
03130     } else if (ftype == MTYPE_I8)
03131       wnx = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03132           wn );
03133     else
03134       Fail_FmtAssertion("Gen_Iolist_PutFieldWN, I8INTCONST: unexpected field"
03135       " type (%s) in I/O processing", MTYPE_name(ftype));
03136 
03137   else if (WN_opcode(wn) == OPC_U4INTCONST)
03138 
03139     if (ftype == MTYPE_U4)
03140       wnx = WN_CreateStid ( OPC_U4STID, foffset, st, Be_Type_Tbl(MTYPE_U4),
03141           wn );
03142     else if (ftype == MTYPE_U8) {
03143       wnx = WN_CreateStid ( OPC_U8STID, foffset, st, Be_Type_Tbl(MTYPE_U8),
03144       WN_CreateIntconst ( OPC_U8INTCONST, WN_const_val(wn) ));
03145       WN_Delete ( wn );
03146     } else
03147       Fail_FmtAssertion("Gen_Iolist_PutFieldWN, U4INTCONST: unexpected field"
03148       " type (%s) in I/O processing", MTYPE_name(ftype));
03149 
03150   else if (WN_opcode(wn) == OPC_U8INTCONST)
03151 
03152     if (ftype == MTYPE_U4) {
03153       wnx = WN_CreateStid ( OPC_U4STID, foffset, st, Be_Type_Tbl(MTYPE_U4),
03154       WN_CreateIntconst ( OPC_U4INTCONST, WN_const_val(wn) ));
03155       WN_Delete ( wn );
03156     } else if (ftype == MTYPE_U8)
03157       wnx = WN_CreateStid ( OPC_U8STID, foffset, st, Be_Type_Tbl(MTYPE_U8),
03158           wn );
03159     else
03160       Fail_FmtAssertion("Gen_Iolist_PutFieldWN, U8INTCONST: unexpected field"
03161       " type (%s) in I/O processing", MTYPE_name(ftype));
03162 
03163   else if (WN_opcode(wn) == OPC_U4LDA || WN_opcode(wn) == OPC_U8LDA) {
03164 
03165     vtype = ST_btype(WN_st(wn));
03166     if (ftype == MTYPE_I4)
03167       if (vtype == MTYPE_I4)
03168   wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03169         WN_CreateLdid ( OPC_I4I4LDID, WN_offset(wn), WN_st(wn),
03170             Be_Type_Tbl(MTYPE_I4) ));
03171       else if (vtype == MTYPE_I8)
03172   wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03173         WN_CreateExp1 ( OPC_I4I8CVT,
03174         WN_CreateLdid ( OPC_I8I8LDID, WN_offset(wn), WN_st(wn),
03175             Be_Type_Tbl(MTYPE_I8) )));
03176       else if (vtype == MTYPE_F4)
03177   wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03178         WN_CreateExp1 ( OPC_I4F4CVT,
03179         WN_CreateLdid ( OPC_F4F4LDID, WN_offset(wn), WN_st(wn),
03180             Be_Type_Tbl(MTYPE_F4) )));
03181       else if (vtype == MTYPE_F8)
03182   wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03183         WN_CreateExp1 ( OPC_I4F8CVT,
03184         WN_CreateLdid ( OPC_F8F8LDID, WN_offset(wn), WN_st(wn),
03185             Be_Type_Tbl(MTYPE_F8) )));
03186 #if defined(TARG_IA64)
03187       else if (vtype == MTYPE_F10)
03188         wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03189               WN_CreateExp1 ( OPC_I4F10CVT,
03190               WN_CreateLdid ( OPC_F10F10LDID, WN_offset(wn), WN_st(wn),
03191                               Be_Type_Tbl(MTYPE_F10) )));
03192 #endif
03193       else if (vtype == MTYPE_FQ)
03194   wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03195         WN_CreateExp1 ( OPC_I4FQCVT,
03196         WN_CreateLdid ( OPC_FQFQLDID, WN_offset(wn), WN_st(wn),
03197             Be_Type_Tbl(MTYPE_FQ) )));
03198       else
03199   Fail_FmtAssertion("Gen_Iolist_PutFieldWN, LDA,I4: unexpected item"
03200         " type (%s) in I/O processing", MTYPE_name(vtype));
03201     else if (ftype == MTYPE_I8)
03202       if (vtype == MTYPE_I4)
03203   wnx = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03204         WN_CreateLdid ( OPC_I8I4LDID, WN_offset(wn), WN_st(wn),
03205             Be_Type_Tbl(MTYPE_I8) ));
03206       else if (vtype == MTYPE_I8)
03207   wnx = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03208         WN_CreateLdid ( OPC_I8I8LDID, WN_offset(wn), WN_st(wn),
03209             Be_Type_Tbl(MTYPE_I8) ));
03210       else if (vtype == MTYPE_F4)
03211   wnx = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03212         WN_CreateExp1 ( OPC_I8F4CVT,
03213         WN_CreateLdid ( OPC_F4F4LDID, WN_offset(wn), WN_st(wn),
03214             Be_Type_Tbl(MTYPE_F4) )));
03215       else if (vtype == MTYPE_F8)
03216   wnx = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03217         WN_CreateExp1 ( OPC_I8F8CVT,
03218         WN_CreateLdid ( OPC_F8F8LDID, WN_offset(wn), WN_st(wn),
03219             Be_Type_Tbl(MTYPE_F8) )));
03220 #if defined(TARG_IA64)
03221       else if (vtype == MTYPE_F10)
03222         wnx = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03223               WN_CreateExp1 ( OPC_I8F10CVT,
03224               WN_CreateLdid ( OPC_F10F10LDID, WN_offset(wn), WN_st(wn),
03225                               Be_Type_Tbl(MTYPE_F10) )));
03226 #endif
03227       else if (vtype == MTYPE_FQ)
03228   wnx = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03229         WN_CreateExp1 ( OPC_I8FQCVT,
03230         WN_CreateLdid ( OPC_FQFQLDID, WN_offset(wn), WN_st(wn),
03231             Be_Type_Tbl(MTYPE_FQ) )));
03232       else
03233   Fail_FmtAssertion("Gen_Iolist_PutFieldWN, LDA,I8: unexpected item"
03234         " type (%s) in I/O processing", MTYPE_name(vtype));
03235     else
03236       Fail_FmtAssertion("Gen_Iolist_PutFieldWN, U4LDA/U8LDA: unexpected field"
03237       " type (%s) in I/O processing", MTYPE_name(ftype));
03238     WN_Delete ( wn );
03239 
03240   } else if (OPCODE_is_expression(WN_opcode(wn))) {
03241 
03242     etype = WN_rtype(wn);
03243     if (ftype == MTYPE_I4)
03244       if (etype == MTYPE_I4)
03245   wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03246             wn );
03247       else if (etype == MTYPE_U4)
03248   wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03249                   wn );
03250       else if (etype == MTYPE_I8)
03251   wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03252         WN_CreateExp1 ( OPC_I4I8CVT, wn ));
03253       else if (etype == MTYPE_U8)
03254         wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03255               WN_CreateExp1 ( OPC_I4U8CVT, wn ));
03256       else if (etype == MTYPE_F4)
03257   wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03258         WN_CreateExp1 ( OPC_I4F4CVT, wn ));
03259       else if (etype == MTYPE_F8)
03260   wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03261         WN_CreateExp1 ( OPC_I4F8CVT, wn ));
03262       else if (etype == MTYPE_F10)
03263         wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03264               WN_CreateExp1 ( OPC_I4F10CVT, wn ));
03265       else if (etype == MTYPE_FQ)
03266   wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03267         WN_CreateExp1 ( OPC_I4FQCVT, wn ));
03268       else
03269   Fail_FmtAssertion("Gen_Iolist_PutFieldWN, exp,I4: unexpected expression"
03270         " type (%s) in I/O processing", MTYPE_name(etype));
03271     else if (ftype == MTYPE_U4)
03272       if (etype == MTYPE_U4 || etype == MTYPE_I4)
03273   wnx = WN_CreateStid ( OPC_U4STID, foffset, st, Be_Type_Tbl(MTYPE_U4),
03274                   wn );
03275       else if (etype == MTYPE_U8)
03276         wnx = WN_CreateStid ( OPC_U4STID, foffset, st, Be_Type_Tbl(MTYPE_U4),
03277               WN_CreateExp1 ( OPC_U4U8CVT, wn ));
03278       else if (etype == MTYPE_I8)
03279         wnx = WN_CreateStid ( OPC_U4STID, foffset, st, Be_Type_Tbl(MTYPE_U4),
03280               WN_CreateExp1 ( OPC_U4I8CVT, wn ));
03281       else
03282   Fail_FmtAssertion("Gen_Iolist_PutFieldWN, exp,U4: unexpected expression"
03283         " type (%s) in I/O processing", MTYPE_name(etype));
03284     else if (ftype == MTYPE_I8)
03285       if (etype == MTYPE_I4)
03286   wnx = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03287         WN_CreateExp1 ( OPC_I8I4CVT, wn ));
03288       else if (etype == MTYPE_U4)
03289         wnx = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03290               WN_CreateExp1 ( OPC_I8U4CVT, wn ));
03291       else if (etype == MTYPE_I8)
03292   wnx = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03293             wn );
03294       else if (etype == MTYPE_U8)
03295   wnx = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03296             wn );
03297       else if (etype == MTYPE_F4)
03298   wnx = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03299         WN_CreateExp1 ( OPC_I8F4CVT, wn ));
03300       else if (etype == MTYPE_F8)
03301   wnx = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03302         WN_CreateExp1 ( OPC_I8F8CVT, wn ));
03303       else if (etype == MTYPE_F10)
03304         wnx = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03305               WN_CreateExp1 ( OPC_I8F10CVT, wn ));
03306       else if (etype == MTYPE_FQ)
03307   wnx = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03308         WN_CreateExp1 ( OPC_I8FQCVT, wn ));
03309       else
03310   Fail_FmtAssertion("Gen_Iolist_PutFieldWN, exp,I8: unexpected expression"
03311         " type (%s) in I/O processing", MTYPE_name(etype));
03312     else if (ftype == MTYPE_U8)
03313       if (etype == MTYPE_U8 || etype == MTYPE_I8)
03314   wnx = WN_CreateStid ( OPC_U8STID, foffset, st, Be_Type_Tbl(MTYPE_U8),
03315             wn );
03316       else if (etype == MTYPE_U4)
03317         wnx = WN_CreateStid ( OPC_U8STID, foffset, st, Be_Type_Tbl(MTYPE_U8),
03318               WN_CreateExp1 ( OPC_U8U4CVT, wn ));
03319       else if (etype == MTYPE_I4)
03320         wnx = WN_CreateStid ( OPC_U8STID, foffset, st, Be_Type_Tbl(MTYPE_U8),
03321               WN_CreateExp1 ( OPC_U8I4CVT, wn ));
03322       else
03323   Fail_FmtAssertion("Gen_Iolist_PutFieldWN, exp,U8: unexpected expression"
03324         " type (%s) in I/O processing", MTYPE_name(etype));
03325     else
03326       Fail_FmtAssertion("Gen_Iolist_PutFieldWN, expression: unexpected field"
03327       " type (%s) in I/O processing", MTYPE_name(ftype));
03328 
03329   } else
03330 
03331     Fail_FmtAssertion("Gen_Iolist_PutFieldWN: unexpected WN_opcode (%s) in"
03332           " I/O processing", OPCODE_name(WN_opcode(wn)));
03333 
03334   /*  Add the generated load/store into the statement block being created  */
03335   /*  for the I/O statement.               */
03336 
03337   WN_INSERT_BlockLast ( block, wnx );
03338 
03339 }
03340 
03341 /*  This routine is one of a set to manage the structures passed between    */
03342 /*  user code and the I/O runtime routines.  This routine will take an      */
03343 /*  address (given by an LDA node, ARRAY node or an LDID node) and put it   */
03344 /*  at the specified offset within the structure */
03345 
03346 static void Gen_Iolist_PutAddrWN ( WN * block, ST * st, INT32 foffset,
03347            INT32 ftype, WN * wn )
03348 {
03349   WN * wnx;
03350 
03351   /*  Save the ST info for building dummy parm lists.  */
03352 
03353 #ifdef KEY
03354   // Bug 10413: IPA may have constant propagated a non-existing optional
03355   // argument to an IO_ITEM, skip it.
03356   if (WN_operator(wn) == OPR_INTCONST)
03357   {
03358     // The constant must be zero.
03359     FmtAssert (WN_const_val(wn) == 0,
03360                ("Get_Iolist_PutAddrWN: INTCONST can only be zero"));
03361     return;
03362   }
03363 #endif
03364 
03365   wnx = wn;
03366   Add_To_Dummy_List(wnx);
03367 
03368   /*  Generate the appropriate STID depending on the field type and  */
03369   /*  child node.                */
03370 
03371   if ((WN_opcode(wn) == OPC_U4LDA   || WN_opcode(wn) == OPC_U4U4LDID  ||
03372        WN_opcode(wn) == OPC_U4ARRAY || WN_opcode(wn) == OPC_U4U4ILOAD ||
03373        WN_opcode(wn) == OPC_U4ADD || WN_opcode(wn) == OPC_I4I4LDID)  &&
03374       (ftype == MTYPE_U4 || ftype == MTYPE_I4 || ftype == MTYPE_M ))
03375     wnx = WN_CreateStid ( OPC_U4STID, foffset, st, Be_Type_Tbl(MTYPE_U4), wn );
03376 
03377   else if ((WN_opcode(wn) == OPC_U4LDA   || WN_opcode(wn) == OPC_U4U4LDID  ||
03378        WN_opcode(wn) == OPC_U4ARRAY || WN_opcode(wn) == OPC_U4U4ILOAD ||
03379        WN_opcode(wn) == OPC_U4ADD)  &&
03380       (ftype == MTYPE_U8 || ftype == MTYPE_I8 ))
03381     wnx = WN_CreateStid ( OPC_U8STID, foffset, st, Be_Type_Tbl(MTYPE_U8), 
03382           WN_CreateExp1 ( OPC_U8U4CVT, wn));
03383 
03384   else if ((WN_opcode(wn) == OPC_U8LDA   || WN_opcode(wn) == OPC_U8U8LDID  ||
03385       WN_opcode(wn) == OPC_U8ARRAY || WN_opcode(wn) == OPC_U8U8ILOAD ||
03386       WN_opcode(wn) == OPC_U8ADD || WN_opcode(wn) == OPC_I8I8LDID)  &&
03387      (ftype == MTYPE_U8 || ftype == MTYPE_I8 || ftype == MTYPE_M))
03388     wnx = WN_CreateStid ( OPC_U8STID, foffset, st, Be_Type_Tbl(MTYPE_U8), wn );
03389 
03390   else if ((WN_opcode(wn) == OPC_U8LDA   || WN_opcode(wn) == OPC_U8U8LDID  ||
03391       WN_opcode(wn) == OPC_U8ARRAY || WN_opcode(wn) == OPC_U8U8ILOAD ||
03392       WN_opcode(wn) == OPC_U8ADD)  &&
03393      (ftype == MTYPE_U4 || ftype == MTYPE_I4 ))
03394     wnx = WN_CreateStid ( OPC_U8STID, foffset, st, Be_Type_Tbl(MTYPE_U8), 
03395           WN_CreateExp1 ( OPC_U4U8CVT, wn ));
03396 
03397   else if (WN_opcode(wn) == OPC_MLOAD) 
03398     wnx = WN_CreateMstore(foffset, Create_Maligned_TY(foffset, ST_type(st)), wn,
03399     WN_CreateLda(opc_lda, 0, TY_pointer(ST_type(st)), st),
03400     WN_CreateIntconst ( OPC_U4INTCONST, fcd_size));
03401   else 
03402     Fail_FmtAssertion("Gen_Iolist_PutAddrWN: unexpected WN_opcode (%s) and"
03403           " field type (%s) in I/O processing",
03404           OPCODE_name(WN_opcode(wn)), MTYPE_name(ftype));
03405 
03406   /*  Add the generated load/store into the statement block being created  */
03407   /*  for the I/O statement.               */
03408 
03409   WN_INSERT_BlockLast ( block, wnx );
03410 
03411 }
03412 
03413 /*  This routine is one of a set to manage the structures passed between     */
03414 /*  user code and the I/O runtime routines.  This routine will get any       */
03415 /*  field within any of the I/O structures and store the value into a        */
03416 /*  user variable specified by an ST entry.  All necessary data conversions  */
03417 /*  are generated.                   */
03418 
03419 static void Gen_Io_GetFieldST ( WN * block, ST * var, ST * st, FIOSTRUCT field )
03420 {
03421   WN * wn;
03422   INT32 foffset;
03423   INT32 ftype;
03424   INT32 vtype = ST_btype(var);
03425 
03426   /*  Lookup the offset and type of the requested field.  */
03427 
03428   if (Pointer_Size == 4) {
03429     foffset = fiostruct_info[field].offset32;
03430     ftype = fiostruct_info[field].type32;
03431   } else {
03432     foffset = fiostruct_info[field].offset64;
03433     ftype = fiostruct_info[field].type64;
03434   }
03435 
03436   /*  Based on the field type and the user variable type, generate the  */
03437   /*  ldid/stid pair plus any additional conversion needed.   */
03438 
03439   if (vtype == MTYPE_I4)
03440 
03441     if (ftype == MTYPE_I4)
03442       wn = WN_CreateStid ( OPC_I4STID, 0, var, ST_type(var),
03443      WN_CreateLdid ( OPC_I4I4LDID, foffset, st, Be_Type_Tbl(MTYPE_I4) ));
03444     else if (ftype == MTYPE_I8)
03445       wn = WN_CreateStid ( OPC_I4STID, 0, var, ST_type(var),
03446      WN_CreateExp1 ( OPC_I4I8CVT,
03447      WN_CreateLdid ( OPC_I8I8LDID, foffset, st, Be_Type_Tbl(MTYPE_I8) )));
03448     else
03449       Fail_FmtAssertion("Gen_Io_GetFieldST, I4: unexpected field type (%s)"
03450       " in I/O processing", MTYPE_name(ftype));
03451 
03452   else if (vtype == MTYPE_I8)
03453 
03454     if (ftype == MTYPE_I4)
03455       wn = WN_CreateStid ( OPC_I8STID, 0, var, ST_type(var),
03456      WN_CreateLdid ( OPC_I8I4LDID, foffset, st, Be_Type_Tbl(MTYPE_I8) ));
03457     else if (ftype == MTYPE_I8)
03458       wn = WN_CreateStid ( OPC_I8STID, 0, var, ST_type(var),
03459      WN_CreateLdid ( OPC_I8I8LDID, foffset, st, Be_Type_Tbl(MTYPE_I8) ));
03460     else
03461       Fail_FmtAssertion("Gen_Io_GetFieldST, I8: unexpected field type (%s)"
03462       " in I/O processing", MTYPE_name(ftype));
03463 
03464   else
03465 
03466     Fail_FmtAssertion("Gen_Io_GetFieldST: unexpected item type (%s) in"
03467           " I/O processing", MTYPE_name(vtype));
03468 
03469   /*  Add the generated load/store into the statement block being created  */
03470   /*  for the I/O statement.               */
03471 
03472   WN_INSERT_BlockLast ( block, wn );
03473 
03474 }
03475 
03476 
03477 /*  This routine is one of a set to manage the structures passed between     */
03478 /*  user code and the I/O runtime routines.  This routine will get any       */
03479 /*  field within any of the I/O structures and store the value into a        */
03480 /*  user variable specified by an WN node.  All necessary data conversions   */
03481 /*  are generated.                   */
03482 
03483 static void Gen_Io_GetFieldWN ( WN * block, WN * wn, ST * st, FIOSTRUCT field )
03484 {
03485   WN * wnx;
03486   INT32 foffset;
03487   INT32 ftype;
03488   ST * var = WN_st(wn);
03489   INT32 vtype = ST_btype(var);
03490 
03491   /*  Lookup the offset and type of the requested field.  */
03492 
03493   if (Pointer_Size == 4) {
03494     foffset = fiostruct_info[field].offset32;
03495     ftype = fiostruct_info[field].type32;
03496   } else {
03497     foffset = fiostruct_info[field].offset64;
03498     ftype = fiostruct_info[field].type64;
03499   }
03500 
03501   /*  Based on the field type and the user variable type, generate the  */
03502   /*  ldid/stid pair plus any additional conversion needed.   */
03503 
03504   if (vtype == MTYPE_I4)
03505 
03506     if (ftype == MTYPE_I4)
03507       wnx = WN_CreateStid ( OPC_I4STID, 0, var, ST_type(var),
03508       WN_CreateLdid ( OPC_I4I4LDID, foffset, st, Be_Type_Tbl(MTYPE_I4) ));
03509     else if (ftype == MTYPE_I8)
03510       wnx = WN_CreateStid ( OPC_I4STID, 0, var, ST_type(var),
03511       WN_CreateExp1 ( OPC_I4I8CVT,
03512       WN_CreateLdid ( OPC_I8I8LDID, foffset, st,
03513           Be_Type_Tbl(MTYPE_I8) )));
03514     else
03515       Fail_FmtAssertion("Gen_Io_GetFieldWN, I4: unexpected field type (%s)"
03516       " in I/O processing", MTYPE_name(ftype));
03517 
03518   else if (vtype == MTYPE_I8)
03519 
03520     if (ftype == MTYPE_I4)
03521       wnx = WN_CreateStid ( OPC_I8STID, 0, var, ST_type(var),
03522       WN_CreateLdid ( OPC_I8I4LDID, foffset, st, Be_Type_Tbl(MTYPE_I8) ));
03523     else if (ftype == MTYPE_I8)
03524       wnx = WN_CreateStid ( OPC_I8STID, 0, var, ST_type(var),
03525       WN_CreateLdid ( OPC_I8I8LDID, foffset, st, Be_Type_Tbl(MTYPE_I8) ));
03526     else
03527       Fail_FmtAssertion("Gen_Io_GetFieldWN, I8: unexpected field type (%s)"
03528       " in I/O processing", MTYPE_name(ftype));
03529 
03530   else
03531 
03532     Fail_FmtAssertion("Gen_Io_GetFieldWN: unexpected item type (%s)"
03533           " in I/O processing", MTYPE_name(vtype));
03534 
03535   /*  Add the generated load/store into the statement block being created  */
03536   /*  for the I/O statement.               */
03537 
03538   WN_INSERT_BlockLast ( block, wnx );
03539 
03540   /*  Delete the old load node.  */
03541 
03542   WN_Delete ( wn );
03543 
03544 }
03545 
03546 
03547 /*  This routine is one of a set to manage the structures passed between    */
03548 /*  user code and the I/O runtime routines.  This routine will take the     */
03549 /*  value of a user variable specified by an ST and put it into any field   */
03550 /*  within any of the I/O structures.  All necessary data conversions are   */
03551 /*  generated.                    */
03552 
03553 static void Gen_Io_PutFieldST ( WN * block, ST * st, FIOSTRUCT field, ST * var )
03554 {
03555   WN * wn;
03556   INT32 foffset;
03557   INT32 ftype;
03558   INT32 vtype = ST_btype(var);
03559 
03560   /*  Lookup the offset and type of the requested field.  */
03561 
03562   if (Pointer_Size == 4) {
03563     foffset = fiostruct_info[field].offset32;
03564     ftype = fiostruct_info[field].type32;
03565   } else {
03566     foffset = fiostruct_info[field].offset64;
03567     ftype = fiostruct_info[field].type64;
03568   }
03569 
03570   /*  Based on the field type and the user variable type, generate the  */
03571   /*  ldid/stid pair plus any additional conversion needed.   */
03572 
03573   if (ftype == MTYPE_I4)
03574 
03575     if (vtype == MTYPE_I4)
03576       wn = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03577      WN_CreateLdid ( OPC_I4I4LDID, 0, var, Be_Type_Tbl(MTYPE_I4) ));
03578     else if (vtype == MTYPE_I8)
03579       wn = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03580      WN_CreateExp1 ( OPC_I4I8CVT,
03581      WN_CreateLdid ( OPC_I8I8LDID, 0, var, Be_Type_Tbl(MTYPE_I8) )));
03582     else if (vtype == MTYPE_F4)
03583       wn = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03584      WN_CreateExp1 ( OPC_I4F4CVT,
03585      WN_CreateLdid ( OPC_F4F4LDID, 0, var, Be_Type_Tbl(MTYPE_F4) )));
03586     else if (vtype == MTYPE_F8)
03587       wn = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03588      WN_CreateExp1 ( OPC_I4F8CVT,
03589      WN_CreateLdid ( OPC_F8F8LDID, 0, var, Be_Type_Tbl(MTYPE_F8) )));
03590     else if (vtype == MTYPE_F10)
03591       wn = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03592            WN_CreateExp1 ( OPC_I4F10CVT,
03593            WN_CreateLdid ( OPC_F10F10LDID, 0, var, Be_Type_Tbl(MTYPE_F10) )));
03594     else if (vtype == MTYPE_FQ)
03595       wn = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03596      WN_CreateExp1 ( OPC_I4FQCVT,
03597      WN_CreateLdid ( OPC_FQFQLDID, 0, var, Be_Type_Tbl(MTYPE_FQ) )));
03598     else
03599       Fail_FmtAssertion("Gen_Io_PutFieldST, I4: unexpected item type (%s)"
03600       " in I/O processing", MTYPE_name(vtype));
03601 
03602   else if (ftype == MTYPE_I8)
03603 
03604     if (vtype == MTYPE_I4)
03605       wn = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03606      WN_CreateLdid ( OPC_I8I4LDID, 0, var, Be_Type_Tbl(MTYPE_I8) ));
03607     else if (vtype == MTYPE_I8)
03608       wn = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03609      WN_CreateLdid ( OPC_I8I8LDID, 0, var, Be_Type_Tbl(MTYPE_I8) ));
03610     else if (vtype == MTYPE_F4)
03611       wn = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03612      WN_CreateExp1 ( OPC_I8F4CVT,
03613      WN_CreateLdid ( OPC_F4F4LDID, 0, var, Be_Type_Tbl(MTYPE_F4) )));
03614     else if (vtype == MTYPE_F8)
03615       wn = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03616      WN_CreateExp1 ( OPC_I8F8CVT,
03617      WN_CreateLdid ( OPC_F8F8LDID, 0, var, Be_Type_Tbl(MTYPE_F8) )));
03618     else if (vtype == MTYPE_F10)
03619       wn = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03620            WN_CreateExp1 ( OPC_I8F10CVT,
03621            WN_CreateLdid ( OPC_F10F10LDID, 0, var, Be_Type_Tbl(MTYPE_F10) )));
03622     else if (vtype == MTYPE_FQ)
03623       wn = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03624      WN_CreateExp1 ( OPC_I8FQCVT,
03625      WN_CreateLdid ( OPC_FQFQLDID, 0, var, Be_Type_Tbl(MTYPE_FQ) )));
03626     else
03627       Fail_FmtAssertion("Gen_Io_PutFieldST, I8: unexpected item type (%s)"
03628       " in I/O processing", MTYPE_name(vtype));
03629 
03630   else
03631 
03632     Fail_FmtAssertion("Gen_Io_PutFieldST: unexpected field type (%s)"
03633           " in I/O processing", MTYPE_name(ftype));
03634 
03635   /*  Add the generated load/store into the statement block being created  */
03636   /*  for the I/O statement.               */
03637 
03638   WN_INSERT_BlockLast ( block, wn );
03639 
03640 }
03641 
03642 
03643 /*  This routine is one of a set to manage the structures passed between    */
03644 /*  user code and the I/O runtime routines.  This routine will take the     */
03645 /*  value of a user expression specified by a WN and put it into any field  */
03646 /*  within any of the I/O structures.  All necessary data conversions are   */
03647 /*  generated.                    */
03648 
03649 static void Gen_Io_PutFieldWN ( WN * block, ST * st, FIOSTRUCT field, WN * wn )
03650 {
03651   WN * wnx = NULL;
03652   INT32 foffset;
03653   INT32 ftype;
03654   INT32 etype;
03655   INT32 vtype;
03656 
03657   /*  Lookup the offset and type of the requested field.  */
03658 
03659   if (Pointer_Size == 4) {
03660     foffset = fiostruct_info[field].offset32;
03661     ftype = fiostruct_info[field].type32;
03662   } else {
03663     foffset = fiostruct_info[field].offset64;
03664     ftype = fiostruct_info[field].type64;
03665   }
03666 
03667   /*  Determine kind and type of expression node.  Then convert the node as  */
03668   /*  appropriate to match the structure field type.  Finally, generate the  */
03669   /*  store into the field.                */
03670   /*                       */
03671   /*  The three cases handled are:               */
03672   /*  1) OPC_I4INTCONST or OPC_I8INTCONST - this will be used directly     */
03673   /*                or have it's size adjusted.    */
03674   /*  2) OPC_U4LDA or OPC_U8LDA - this will be replaced with an LDID node  */
03675   /*            with the same ST entry and possibly a    */
03676   /*            CVT node.            */
03677   /*  3) any expression tree - this will be used directly with the       */
03678   /*         addition of a CVT node if needed.       */
03679 
03680   if (WN_opcode(wn) == OPC_I4INTCONST)
03681 
03682     if (ftype == MTYPE_I4)
03683       wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03684           wn );
03685     else if (ftype == MTYPE_U4) {
03686       wnx = WN_CreateStid ( OPC_U4STID, foffset, st, Be_Type_Tbl(MTYPE_U4),
03687             WN_CreateIntconst ( OPC_U4INTCONST, WN_const_val(wn) ));
03688       WN_Delete ( wn );
03689     } else if (ftype == MTYPE_I8) {
03690       wnx = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03691             WN_CreateIntconst ( OPC_I8INTCONST, WN_const_val(wn) ));
03692       WN_Delete ( wn );
03693     } else if (ftype == MTYPE_U8) {
03694       wnx = WN_CreateStid ( OPC_U8STID, foffset, st, Be_Type_Tbl(MTYPE_U8),
03695             WN_CreateIntconst ( OPC_U8INTCONST, WN_const_val(wn) ));
03696       WN_Delete ( wn );
03697     } else
03698       Fail_FmtAssertion("Gen_Io_PutFieldWN, I4INTCONST: unexpected field"
03699       " type (%s) in I/O processing", MTYPE_name(ftype));
03700 
03701   else if (WN_opcode(wn) == OPC_I8INTCONST)
03702 
03703     if (ftype == MTYPE_I4) {
03704       wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03705             WN_CreateIntconst ( OPC_I4INTCONST, WN_const_val(wn) ));
03706       WN_Delete ( wn );
03707     } else if (ftype == MTYPE_U4) {
03708       wnx = WN_CreateStid ( OPC_U4STID, foffset, st, Be_Type_Tbl(MTYPE_U4),
03709             WN_CreateIntconst ( OPC_U4INTCONST, WN_const_val(wn) ));
03710       WN_Delete ( wn );
03711     } else if (ftype == MTYPE_U8) {
03712       wnx = WN_CreateStid ( OPC_U8STID, foffset, st, Be_Type_Tbl(MTYPE_U8),
03713             WN_CreateIntconst ( OPC_U8INTCONST, WN_const_val(wn) ));
03714       WN_Delete ( wn );
03715     } else if (ftype == MTYPE_I8)
03716       wnx = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03717           wn );
03718     else
03719       Fail_FmtAssertion("Gen_Io_PutFieldWN, I8INTCONST: unexpected field"
03720       " type (%s) in I/O processing", MTYPE_name(ftype));
03721 
03722   else if (WN_opcode(wn) == OPC_U4INTCONST)
03723 
03724     if (ftype == MTYPE_U4)
03725       wnx = WN_CreateStid ( OPC_U4STID, foffset, st, Be_Type_Tbl(MTYPE_U4),
03726           wn );
03727     else if (ftype == MTYPE_U8) {
03728       wnx = WN_CreateStid ( OPC_U8STID, foffset, st, Be_Type_Tbl(MTYPE_U8),
03729       WN_CreateIntconst ( OPC_U8INTCONST, WN_const_val(wn) ));
03730       WN_Delete ( wn );
03731     } else
03732       Fail_FmtAssertion("Gen_Io_PutFieldWN, U4INTCONST: unexpected field"
03733       " type (%s) in I/O processing", MTYPE_name(ftype));
03734 
03735   else if (WN_opcode(wn) == OPC_U8INTCONST)
03736 
03737     if (ftype == MTYPE_U4) {
03738       wnx = WN_CreateStid ( OPC_U4STID, foffset, st, Be_Type_Tbl(MTYPE_U4),
03739       WN_CreateIntconst ( OPC_U4INTCONST, WN_const_val(wn) ));
03740       WN_Delete ( wn );
03741     } else if (ftype == MTYPE_U8)
03742       wnx = WN_CreateStid ( OPC_U8STID, foffset, st, Be_Type_Tbl(MTYPE_U8),
03743           wn );
03744     else
03745       Fail_FmtAssertion("Gen_Io_PutFieldWN, U8INTCONST: unexpected field"
03746       " type (%s) in I/O processing", MTYPE_name(ftype));
03747 
03748   else if (WN_opcode(wn) == OPC_U4LDA || WN_opcode(wn) == OPC_U8LDA) {
03749 
03750     vtype = ST_btype(WN_st(wn));
03751     if (ftype == MTYPE_I4)
03752       if (vtype == MTYPE_I4)
03753   wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03754         WN_CreateLdid ( OPC_I4I4LDID, WN_offset(wn), WN_st(wn),
03755             Be_Type_Tbl(MTYPE_I4) ));
03756       else if (vtype == MTYPE_I8)
03757   wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03758         WN_CreateExp1 ( OPC_I4I8CVT,
03759         WN_CreateLdid ( OPC_I8I8LDID, WN_offset(wn), WN_st(wn),
03760             Be_Type_Tbl(MTYPE_I8) )));
03761       else if (vtype == MTYPE_F4)
03762   wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03763         WN_CreateExp1 ( OPC_I4F4CVT,
03764         WN_CreateLdid ( OPC_F4F4LDID, WN_offset(wn), WN_st(wn),
03765             Be_Type_Tbl(MTYPE_F4) )));
03766       else if (vtype == MTYPE_F8)
03767   wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03768         WN_CreateExp1 ( OPC_I4F8CVT,
03769         WN_CreateLdid ( OPC_F8F8LDID, WN_offset(wn), WN_st(wn),
03770             Be_Type_Tbl(MTYPE_F8) )));
03771       else if (vtype == MTYPE_F10)
03772         wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03773               WN_CreateExp1 ( OPC_I4F10CVT,
03774               WN_CreateLdid ( OPC_F10F10LDID, WN_offset(wn), WN_st(wn),
03775                               Be_Type_Tbl(MTYPE_F10) )));
03776       else if (vtype == MTYPE_FQ)
03777   wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03778         WN_CreateExp1 ( OPC_I4FQCVT,
03779         WN_CreateLdid ( OPC_FQFQLDID, WN_offset(wn), WN_st(wn),
03780             Be_Type_Tbl(MTYPE_FQ) )));
03781       else
03782   Fail_FmtAssertion("Gen_Io_PutFieldWN, LDA,I4: unexpected item type"
03783         " (%s) in I/O processing", MTYPE_name(vtype));
03784     else if (ftype == MTYPE_I8)
03785       if (vtype == MTYPE_I4)
03786   wnx = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03787         WN_CreateLdid ( OPC_I8I4LDID, WN_offset(wn), WN_st(wn),
03788             Be_Type_Tbl(MTYPE_I8) ));
03789       else if (vtype == MTYPE_I8)
03790   wnx = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03791         WN_CreateLdid ( OPC_I8I8LDID, WN_offset(wn), WN_st(wn),
03792             Be_Type_Tbl(MTYPE_I8) ));
03793       else if (vtype == MTYPE_F4)
03794   wnx = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03795         WN_CreateExp1 ( OPC_I8F4CVT,
03796         WN_CreateLdid ( OPC_F4F4LDID, WN_offset(wn), WN_st(wn),
03797             Be_Type_Tbl(MTYPE_F4) )));
03798       else if (vtype == MTYPE_F8)
03799   wnx = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03800         WN_CreateExp1 ( OPC_I8F8CVT,
03801         WN_CreateLdid ( OPC_F8F8LDID, WN_offset(wn), WN_st(wn),
03802             Be_Type_Tbl(MTYPE_F8) )));
03803       else if (vtype == MTYPE_F10)
03804         wnx = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03805               WN_CreateExp1 ( OPC_I8F10CVT,
03806               WN_CreateLdid ( OPC_F10F10LDID, WN_offset(wn), WN_st(wn),
03807                               Be_Type_Tbl(MTYPE_F10) )));
03808       else if (vtype == MTYPE_FQ)
03809   wnx = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03810         WN_CreateExp1 ( OPC_I8FQCVT,
03811         WN_CreateLdid ( OPC_FQFQLDID, WN_offset(wn), WN_st(wn),
03812             Be_Type_Tbl(MTYPE_FQ) )));
03813       else
03814   Fail_FmtAssertion("Gen_Io_PutFieldWN, LDA,I8: unexpected item type"
03815         " (%s) in I/O processing", MTYPE_name(vtype));
03816     else
03817       Fail_FmtAssertion("Gen_Io_PutFieldWN, U4LDA/U8LDA: unexpected field"
03818       " type (%s) in I/O processing", MTYPE_name(ftype));
03819     WN_Delete ( wn );
03820 
03821   } else if (OPCODE_is_expression(WN_opcode(wn))) {
03822 
03823     etype = WN_rtype(wn);
03824     if (ftype == MTYPE_I4)
03825       if (etype == MTYPE_I4)
03826   wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03827             wn );
03828       else if (etype == MTYPE_U4)
03829   wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03830                   wn );
03831       else if (etype == MTYPE_I8)
03832   wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03833         WN_CreateExp1 ( OPC_I4I8CVT, wn ));
03834       else if (etype == MTYPE_U8)
03835         wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03836               WN_CreateExp1 ( OPC_I4U8CVT, wn ));
03837       else if (etype == MTYPE_F4)
03838   wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03839         WN_CreateExp1 ( OPC_I4F4CVT, wn ));
03840       else if (etype == MTYPE_F8)
03841   wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03842         WN_CreateExp1 ( OPC_I4F8CVT, wn ));
03843       else if (etype == MTYPE_F10)
03844         wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03845               WN_CreateExp1 ( OPC_I4F10CVT, wn ));
03846       else if (etype == MTYPE_FQ)
03847   wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
03848         WN_CreateExp1 ( OPC_I4FQCVT, wn ));
03849       else
03850   Fail_FmtAssertion("Gen_Io_PutFieldWN, exp,I4: unexpected expression"
03851         " type (%s) in I/O processing", MTYPE_name(etype));
03852     else if (ftype == MTYPE_U4)
03853       if (etype == MTYPE_U4 || etype == MTYPE_I4)
03854   wnx = WN_CreateStid ( OPC_U4STID, foffset, st, Be_Type_Tbl(MTYPE_U4),
03855                   wn );
03856       else if (etype == MTYPE_U8)
03857         wnx = WN_CreateStid ( OPC_U4STID, foffset, st, Be_Type_Tbl(MTYPE_U4),
03858               WN_CreateExp1 ( OPC_U4U8CVT, wn ));
03859       else if (etype == MTYPE_I8)
03860         wnx = WN_CreateStid ( OPC_U4STID, foffset, st, Be_Type_Tbl(MTYPE_U4),
03861               WN_CreateExp1 ( OPC_U4I8CVT, wn ));
03862       else
03863   Fail_FmtAssertion("Gen_Io_PutFieldWN, exp,U4: unexpected expression"
03864         " type (%s) in I/O processing", MTYPE_name(etype));
03865     else if (ftype == MTYPE_I8)
03866       if (etype == MTYPE_I4)
03867   wnx = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03868         WN_CreateExp1 ( OPC_I8I4CVT, wn ));
03869       else if (etype == MTYPE_U4)
03870         wnx = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03871               WN_CreateExp1 ( OPC_I8U4CVT, wn ));
03872       else if (etype == MTYPE_I8)
03873   wnx = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03874             wn );
03875       else if (etype == MTYPE_U8)
03876   wnx = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03877             wn );
03878       else if (etype == MTYPE_F4)
03879   wnx = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03880         WN_CreateExp1 ( OPC_I8F4CVT, wn ));
03881       else if (etype == MTYPE_F8)
03882   wnx = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03883         WN_CreateExp1 ( OPC_I8F8CVT, wn ));
03884       else if (etype == MTYPE_F10)
03885         wnx = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03886               WN_CreateExp1 ( OPC_I8F10CVT, wn ));
03887       else if (etype == MTYPE_FQ)
03888   wnx = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
03889         WN_CreateExp1 ( OPC_I8FQCVT, wn ));
03890       else
03891   Fail_FmtAssertion("Gen_Io_PutFieldWN, exp,I8: unexpected expression"
03892         " type (%s) in I/O processing", MTYPE_name(etype));
03893     else if (ftype == MTYPE_U8)
03894       if (etype == MTYPE_U8 || etype == MTYPE_I8)
03895   wnx = WN_CreateStid ( OPC_U8STID, foffset, st, Be_Type_Tbl(MTYPE_U8),
03896             wn );
03897       else if (etype == MTYPE_U4)
03898         wnx = WN_CreateStid ( OPC_U8STID, foffset, st, Be_Type_Tbl(MTYPE_U8),
03899               WN_CreateExp1 ( OPC_U8U4CVT, wn ));
03900       else if (etype == MTYPE_I4)
03901         wnx = WN_CreateStid ( OPC_U8STID, foffset, st, Be_Type_Tbl(MTYPE_U8),
03902               WN_CreateExp1 ( OPC_U8I4CVT, wn ));
03903       else
03904   Fail_FmtAssertion("Gen_Io_PutFieldWN, exp,U8: unexpected expression"
03905         " type (%s) in I/O processing", MTYPE_name(etype));
03906     else
03907       Fail_FmtAssertion("Gen_Io_PutFieldWN, expression: unexpected field"
03908       " type (%s) in I/O processing", MTYPE_name(ftype));
03909 
03910   } else
03911 
03912     Fail_FmtAssertion("Gen_Io_PutFieldWN: unexpected node (%s)"
03913           " in I/O processing", OPCODE_name(WN_opcode(wn)));
03914 
03915   /*  Add the generated load/store into the statement block being created  */
03916   /*  for the I/O statement.               */
03917 
03918   WN_INSERT_BlockLast ( block, wnx );
03919 
03920 }
03921 
03922 
03923 /*  This routine is used to set the Keyspec structure.  This routine will   */
03924 /*  take an array of values specified by a WN and put it into an array of   */
03925 /*  structures specified by the ST. All necessary data conversions are      */
03926 /*  generated.                    */
03927 
03928 static void Gen_Io_PutKeyFieldWN ( WN * block, ST * st, WN ** wn, INT32 nkeys )
03929 {
03930   WN * wnx = NULL;
03931   INT32 foffset;
03932   INT32 etype;
03933   INT32 vtype;
03934   INT32 i;
03935 
03936   /*  Lookup the offset and type of the requested field.  */
03937 
03938   foffset = 0;
03939 
03940   /*  Go through the list of all nkeys and assign the WN values into the     */
03941   /*  array of Keyspec structure                                             */
03942 
03943   for (i = 0; i < nkeys; i++, wn++, foffset += 2) {
03944   /*  Determine kind and type of expression node.  Then convert the node to  */
03945   /*  INT16 as needed.  Finally, store into the field.                       */
03946 
03947     if (WN_opcode(*wn) == OPC_I4INTCONST) {
03948 
03949       wnx = WN_CreateStid ( OPC_I2STID, foffset, st, Be_Type_Tbl(MTYPE_I2),
03950       WN_CreateIntconst ( OPC_I4INTCONST, WN_const_val(*wn) ));
03951       WN_Delete ( *wn );
03952 
03953     } else if (WN_opcode(*wn) == OPC_I8INTCONST) {
03954 
03955       wnx = WN_CreateStid ( OPC_I2STID, foffset, st, Be_Type_Tbl(MTYPE_I2),
03956         WN_CreateIntconst ( OPC_I4INTCONST, WN_const_val(*wn) ));
03957       WN_Delete ( *wn );
03958 
03959     } else if (WN_opcode(*wn) == OPC_U4LDA || WN_opcode(*wn) == OPC_U8LDA) {
03960 
03961       vtype = ST_btype(WN_st(*wn));
03962       if (vtype == MTYPE_I4)
03963   wnx = WN_CreateStid ( OPC_I2STID, foffset, st, Be_Type_Tbl(MTYPE_I2),
03964         WN_CreateLdid ( OPC_I4I4LDID, WN_offset(*wn), WN_st(*wn),
03965             Be_Type_Tbl(MTYPE_I4) ));
03966       else if (vtype == MTYPE_I8)
03967   wnx = WN_CreateStid ( OPC_I2STID, foffset, st, Be_Type_Tbl(MTYPE_I2),
03968         WN_CreateExp1 ( OPC_I4I8CVT,
03969         WN_CreateLdid ( OPC_I8I8LDID, WN_offset(*wn), WN_st(*wn),
03970             Be_Type_Tbl(MTYPE_I8) )));
03971       else if (vtype == MTYPE_F4)
03972   wnx = WN_CreateStid ( OPC_I2STID, foffset, st, Be_Type_Tbl(MTYPE_I2),
03973         WN_CreateExp1 ( OPC_I4F4CVT,
03974         WN_CreateLdid ( OPC_F4F4LDID, WN_offset(*wn), WN_st(*wn),
03975             Be_Type_Tbl(MTYPE_F4) )));
03976       else if (vtype == MTYPE_F8)
03977   wnx = WN_CreateStid ( OPC_I2STID, foffset, st, Be_Type_Tbl(MTYPE_I2),
03978         WN_CreateExp1 ( OPC_I4F8CVT,
03979         WN_CreateLdid ( OPC_F8F8LDID, WN_offset(*wn), WN_st(*wn),
03980             Be_Type_Tbl(MTYPE_F8) )));
03981       else if (vtype == MTYPE_F10)
03982         wnx = WN_CreateStid ( OPC_I2STID, foffset, st, Be_Type_Tbl(MTYPE_I2),
03983               WN_CreateExp1 ( OPC_I4F10CVT,
03984               WN_CreateLdid ( OPC_F10F10LDID, WN_offset(*wn), WN_st(*wn),
03985                               Be_Type_Tbl(MTYPE_F10) )));
03986       else if (vtype == MTYPE_FQ)
03987   wnx = WN_CreateStid ( OPC_I2STID, foffset, st, Be_Type_Tbl(MTYPE_I2),
03988         WN_CreateExp1 ( OPC_I4FQCVT,
03989         WN_CreateLdid ( OPC_FQFQLDID, WN_offset(*wn), WN_st(*wn),
03990             Be_Type_Tbl(MTYPE_FQ) )));
03991       else
03992   Fail_FmtAssertion("Gen_Io_PutKeyFieldWN: unexpected item type (%s)"
03993         " in I/O processing", MTYPE_name(vtype));
03994       WN_Delete ( *wn );
03995 
03996     } else if (OPCODE_is_expression(WN_opcode(*wn))) {
03997 
03998       etype = WN_rtype(*wn);
03999       if (etype == MTYPE_I4)
04000   wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I2),
04001         *wn );
04002       else if (etype == MTYPE_I8)
04003   wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I2),
04004         WN_CreateExp1 ( OPC_I4I8CVT, *wn ));
04005       else if (etype == MTYPE_F4)
04006   wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I2),
04007         WN_CreateExp1 ( OPC_I4F4CVT, *wn ));
04008       else if (etype == MTYPE_F8)
04009   wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I2),
04010         WN_CreateExp1 ( OPC_I4F8CVT, *wn ));
04011       else if (etype == MTYPE_F10)
04012         wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I2),
04013               WN_CreateExp1 ( OPC_I4F10CVT, *wn ));
04014       else if (etype == MTYPE_FQ)
04015   wnx = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I2),
04016         WN_CreateExp1 ( OPC_I4FQCVT, *wn ));
04017       else
04018   Fail_FmtAssertion("Gen_Io_PutKeyFieldWN: unexpected expression type"
04019         " (%s) in I/O processing", MTYPE_name(etype));
04020     } else
04021       Fail_FmtAssertion("Gen_Io_PutKeyFieldWN: unexpected node (%s)"
04022       " in I/O processing", OPCODE_name(WN_opcode(*wn)));
04023 
04024     /*  Add the generated load/store into the statement block being created  */
04025     /*  for the I/O statement.               */
04026 
04027     WN_INSERT_BlockLast ( block, wnx );
04028   }
04029 }
04030 
04031 
04032 /*  This routine is one of a set to manage the structures passed between    */
04033 /*  user code and the I/O runtime routines.  This routine will take an      */
04034 /*  integer constant value and put it into any field within any of the      */
04035 /*  seven structures.  The appropriate INTCONST node is generated based on  */
04036 /*  the field type.                 */
04037 
04038 static void Gen_Io_PutFieldConst ( WN * block, ST * st, FIOSTRUCT field,
04039            INT64 value )
04040 {
04041   WN * wn = NULL;
04042   INT32 foffset;
04043   INT32 ftype;
04044 
04045   /*  Lookup the offset and type of the requested field.  */
04046 
04047   if (Pointer_Size == 4) {
04048     foffset = fiostruct_info[field].offset32;
04049     ftype = fiostruct_info[field].type32;
04050   } else {
04051     foffset = fiostruct_info[field].offset64;
04052     ftype = fiostruct_info[field].type64;
04053   }
04054 
04055   /*  Generate an appropriate INTCONST node and store it into the structure  */
04056   /*  field.                     */
04057 
04058   if (ftype == MTYPE_I4)
04059     wn = WN_CreateStid ( OPC_I4STID, foffset, st, Be_Type_Tbl(MTYPE_I4),
04060    WN_CreateIntconst ( OPC_I4INTCONST, value ));
04061   else if (ftype == MTYPE_U4)
04062     wn = WN_CreateStid ( OPC_U4STID, foffset, st, Be_Type_Tbl(MTYPE_U4),
04063    WN_CreateIntconst ( OPC_U4INTCONST, value ));
04064   else if (ftype == MTYPE_I8)
04065     wn = WN_CreateStid ( OPC_I8STID, foffset, st, Be_Type_Tbl(MTYPE_I8),
04066    WN_CreateIntconst ( OPC_I8INTCONST, value ));
04067   else if (ftype == MTYPE_U8)
04068     wn = WN_CreateStid ( OPC_U8STID, foffset, st, Be_Type_Tbl(MTYPE_U8),
04069    WN_CreateIntconst ( OPC_U8INTCONST, value ));
04070   else
04071     Fail_FmtAssertion("Gen_Io_PutFieldConst: unexpected field type (%s)"
04072           " in I/O processing", MTYPE_name(ftype));
04073 
04074   /*  Add the generated load/store into the statement block being created  */
04075   /*  for the I/O statement.               */
04076 
04077   WN_INSERT_BlockLast ( block, wn );
04078 
04079 }
04080 
04081 
04082 /*  This routine is one of a set to manage the structures passed between    */
04083 /*  user code and the I/O runtime routines.  This routine will take an      */
04084 /*  address (given by an LDA node, ARRAY node or an LDID node) and put it   */
04085 /*  into any field within any of the I/O structures.  It will also save the */
04086 /*  ST info for use by Gen_Io_Calls to build a dummy argument list of       */
04087 /*  referenced variables.               */
04088 
04089 static void Gen_Io_PutAddrWN ( WN * block, ST * st, FIOSTRUCT field, WN * wn )
04090 {
04091   INT32 foffset;
04092   INT32 ftype;
04093   WN * wnx;
04094 
04095 #ifdef KEY
04096   // Bug 10413: IPA may have constant propagated a non-existing optional
04097   // argument to an IO_ITEM, skip it.
04098   if (WN_operator(wn) == OPR_INTCONST)
04099   {
04100     FmtAssert (WN_const_val(wn) == 0,
04101                ("Gen_Io_PutAddrWN: INTCONST can only be zero"));
04102     return;
04103   }
04104 #endif
04105 
04106   /*  Save the ST info for building dummy parm lists.  */
04107 
04108   wnx = wn;
04109   Add_To_Dummy_List(wnx);
04110 
04111   /*  Lookup the offset and type of the requested field.  */
04112 
04113   if (Pointer_Size == 4) {
04114     foffset = fiostruct_info[field].offset32;
04115     ftype = fiostruct_info[field].type32;
04116   } else {
04117     foffset = fiostruct_info[field].offset64;
04118     ftype = fiostruct_info[field].type64;
04119   }
04120 
04121   /*  Generate the appropriate STID depending on the field type and  */
04122   /*  child node.                */
04123 
04124   if ((WN_opcode(wn) == OPC_U4LDA   || WN_opcode(wn) == OPC_U4U4LDID  ||
04125        WN_opcode(wn) == OPC_U4ARRAY || WN_opcode(wn) == OPC_U4U4ILOAD ||
04126        WN_opcode(wn) == OPC_U4ADD || WN_opcode(wn) == OPC_I4I4LDID)  &&
04127       (ftype == MTYPE_U4 || ftype == MTYPE_I4 || ftype == MTYPE_M))
04128     wnx = WN_CreateStid ( OPC_U4STID, foffset, st, Be_Type_Tbl(MTYPE_U4), wn );
04129 
04130   else if ((WN_opcode(wn) == OPC_U4LDA   || WN_opcode(wn) == OPC_U4U4LDID  ||
04131        WN_opcode(wn) == OPC_U4ARRAY || WN_opcode(wn) == OPC_U4U4ILOAD ||
04132        WN_opcode(wn) == OPC_U4ADD)  &&
04133       (ftype == MTYPE_U8 || ftype == MTYPE_I8 ))
04134     wnx = WN_CreateStid ( OPC_U8STID, foffset, st, Be_Type_Tbl(MTYPE_U8), 
04135           WN_CreateExp1 ( OPC_U8U4CVT, wn));
04136 
04137   else if ((WN_opcode(wn) == OPC_U8LDA   || WN_opcode(wn) == OPC_U8U8LDID  ||
04138       WN_opcode(wn) == OPC_U8ARRAY || WN_opcode(wn) == OPC_U8U8ILOAD ||
04139       WN_opcode(wn) == OPC_U8ADD || WN_opcode(wn) == OPC_I8I8LDID)  &&
04140      (ftype == MTYPE_U8 || ftype == MTYPE_I8 || ftype == MTYPE_M))
04141     wnx = WN_CreateStid ( OPC_U8STID, foffset, st, Be_Type_Tbl(MTYPE_U8), wn );
04142 
04143   else if ((WN_opcode(wn) == OPC_U8LDA   || WN_opcode(wn) == OPC_U8U8LDID  ||
04144       WN_opcode(wn) == OPC_U8ARRAY || WN_opcode(wn) == OPC_U8U8ILOAD ||
04145       WN_opcode(wn) == OPC_U8ADD)   &&
04146      (ftype == MTYPE_U4 || ftype == MTYPE_I4 ))
04147     wnx = WN_CreateStid ( OPC_U8STID, foffset, st, Be_Type_Tbl(MTYPE_U8), 
04148           WN_CreateExp1 ( OPC_U4U8CVT, wn ));
04149 
04150   else if (WN_opcode(wn) == OPC_MLOAD) 
04151     wnx = WN_CreateMstore(foffset, Create_Maligned_TY(foffset, ST_type(st)), wn,
04152     WN_CreateLda(opc_lda, 0, TY_pointer(ST_type(st)), st),
04153     WN_CreateIntconst ( OPC_U4INTCONST, fcd_size));
04154   else 
04155     Fail_FmtAssertion("Gen_Io_PutAddrWN: unexpected field type (%s)"
04156           " in I/O processing", MTYPE_name(ftype));
04157 
04158   /*  Add the generated load/store into the statement block being created  */
04159   /*  for the I/O statement.               */
04160 
04161   WN_INSERT_BlockLast ( block, wnx );
04162 
04163 }
04164 
04165 
04166 static void
04167 Set_Cilist_Fields( WN * block, ST *st,
04168        WN *unit_wn, WN **items, WN *rec_wn, 
04169        WN *parsfmt_wn, WN *fmtsrc_wn, 
04170        WN *advance_wn, WN *size_wn, WN *varfmt )
04171 {
04172   INT32 keytype;
04173 
04174   if (unit_wn != NULL)
04175     Gen_Io_PutAddrWN ( block, st, FCR_CI_UNIT, unit_wn );
04176   if (items[IOC_IOSTAT] != NULL)
04177     Gen_Io_PutAddrWN ( block, st, FCR_CI_IOSTAT, items[IOC_IOSTAT]);
04178   if (rec_wn != NULL)
04179     Gen_Io_PutAddrWN ( block, st, FCR_CI_REC, rec_wn );
04180   if (parsfmt_wn != NULL)
04181     Gen_Io_PutAddrWN ( block, st, FCR_CI_PARSFMT, parsfmt_wn );
04182   if (fmtsrc_wn != NULL) {
04183     Gen_Io_PutAddrWN ( block, st, FCR_CI_FMTSRC, fmtsrc_wn );
04184   }
04185   if (advance_wn != NULL)
04186     Gen_Io_PutAddrWN ( block, st, FCR_CI_ADVANCE, advance_wn );
04187   if (size_wn != NULL)
04188     Gen_Io_PutAddrWN ( block, st, FCR_CI_SIZE, size_wn );
04189   if (varfmt != NULL) {
04190     /* Calvin TODO */
04191       fprintf( stderr, "Variable format not yet implemented\n" );
04192       abort();
04193   }
04194   if (items[IOC_KEY] != NULL) {
04195     keytype = IOC_KEY;
04196   } else if (items[IOC_KEYEQ] != NULL) {
04197     keytype = IOC_KEYEQ;
04198   } else if (items[IOC_KEYGE] != NULL) {
04199     keytype = IOC_KEYGE;
04200   } else if (items[IOC_KEYGT] != NULL) {
04201     keytype = IOC_KEYGT;
04202   } else
04203     keytype = 0;
04204   if (keytype) {
04205     fprintf( stderr, "Keyed I/O is not done\n" );
04206   } else {
04207     /* Calvin TODO: Need to clear the fields for non-indexed I/O */
04208   }
04209   if (items[IOC_KEYID] != NULL) {
04210   } else {
04211     /* Calvin TODO: Need to set the field to -1 for non-indexed I/O */
04212   }
04213 }
04214 
04215 
04216 /*  This routine is used to build up an I/O mask used as the second argument  */
04217 /*  to the OPEN and INQUIRE runtimes.  Every user scalar variable (logical or */
04218 /*  integer) which can be stored into by the runtime is represented by two    */
04219 /*  bits in the iomask.  These two bits encode the size of the user variable. */
04220 
04221 static void Build_Io_Mask ( INT32 * iomask, INT32 ioshift, WN * wn )
04222 {
04223   TY_IDX  ty;
04224   INT32 mtype = 0;
04225 
04226   /*  Determine the basic type of the user variable.  */
04227 
04228   if (WN_operator(wn) == OPR_LDA  ||
04229       WN_operator(wn) == OPR_LDID ||
04230       WN_operator(wn) == OPR_ILOAD) {
04231     ty = WN_ty(wn);
04232     while (TY_kind(ty) == KIND_POINTER || TY_kind(ty) == KIND_ARRAY)
04233       if (TY_kind(ty) == KIND_POINTER)
04234   ty = TY_pointed(ty);
04235       else
04236         ty = TY_etype (ty);
04237     mtype = TY_mtype(ty);
04238   }
04239 
04240   /*  Based on the type, get the size code, shift it into position and add  */
04241   /*  it to the iomask being built.             */
04242 
04243   *iomask |= (fio_maskcode[mtype] << ioshift);
04244 
04245 }
04246 
04247 
04248 /* ====================================================================
04249  *
04250  * WN *extract_calls (WN * block, WN * tree)
04251  *
04252  * Called by I/O lowerer to extract any nested calls or expressions which
04253  * require a store to a temporary.  Due to the semantics of F77 I/O such
04254  * expressions can not (in the general case) be extracted from within
04255  * the I/O statement when the tree is built.  On the other side, WHIRL
04256  * semantics does not allow a statement (or expression with side effects)
04257  * to be nested within an normal expression.  So the WHIRL rules were
04258  * slightly relaxed to allow CALL's within an I/O expression.  The case
04259  * of stores to temps is handled by a set of special, internal only,
04260  * INTRINSIC_OP's which indicate where a store to a temp is needed and
04261  * this routine does the extraction, temp generation, store and reload.
04262  *
04263  * ==================================================================== */
04264 
04265 static WN *extract_calls ( WN * block, WN * tree )
04266 {
04267   INT32 i;
04268   INT32 dtype;
04269   BOOL loadaddr;
04270   TY_IDX ttype;
04271   ST *temp;
04272   WN *kid0;
04273   PREG_NUM reg1, reg2;
04274 
04275   /* First process all kids in case there are multiple (nested) calls so
04276      that they will be done in the correct sequence.  */
04277 
04278   for (i = 0; i < WN_kid_count(tree); i++)
04279     WN_kid(tree,i) = extract_calls ( block, WN_kid(tree,i) );
04280 
04281   /*  If the current tree node is one of the special INTRINSIC_OP's, then
04282       extract the subtree, generate a temp and a store to that temp.  Place
04283       all of that at the block level and replace the subtree with an
04284       appropriate (re-)load operation.  Character functions are handled a
04285       little differently.  */
04286 
04287   if (WN_operator(tree) == OPR_INTRINSIC_OP) {
04288 
04289     kid0 = WN_kid0(tree);
04290 
04291     switch (WN_intrinsic(tree)) {
04292 
04293       case INTRN_U4I1ADRTMP:
04294       case INTRN_U8I1ADRTMP:  dtype    = MTYPE_I1;
04295         loadaddr = TRUE;
04296         break;
04297 
04298       case INTRN_U4I2ADRTMP:
04299       case INTRN_U8I2ADRTMP:  dtype    = MTYPE_I2;
04300         loadaddr = TRUE;
04301         break;
04302 
04303       case INTRN_U4I4ADRTMP:
04304       case INTRN_U8I4ADRTMP:  dtype    = MTYPE_I4;
04305         loadaddr = TRUE;
04306         break;
04307 
04308       case INTRN_U4I8ADRTMP:
04309       case INTRN_U8I8ADRTMP:  dtype    = MTYPE_I8;
04310         loadaddr = TRUE;
04311         break;
04312 
04313       case INTRN_U4F4ADRTMP:
04314       case INTRN_U8F4ADRTMP:  dtype    = MTYPE_F4;
04315         loadaddr = TRUE;
04316         break;
04317 
04318       case INTRN_U4F8ADRTMP:
04319       case INTRN_U8F8ADRTMP:  dtype    = MTYPE_F8;
04320         loadaddr = TRUE;
04321         break;
04322 
04323       case INTRN_U4FQADRTMP:
04324       case INTRN_U8FQADRTMP:  dtype    = MTYPE_FQ;
04325         loadaddr = TRUE;
04326         break;
04327 
04328       case INTRN_U4C4ADRTMP:
04329       case INTRN_U8C4ADRTMP:  dtype    = MTYPE_C4;
04330         loadaddr = TRUE;
04331         break;
04332 
04333       case INTRN_U4C8ADRTMP:
04334       case INTRN_U8C8ADRTMP:  dtype    = MTYPE_C8;
04335         loadaddr = TRUE;
04336         break;
04337 
04338       case INTRN_U4CQADRTMP:
04339       case INTRN_U8CQADRTMP:  dtype    = MTYPE_CQ;
04340         loadaddr = TRUE;
04341         break;
04342 
04343       case INTRN_U4VADRTMP:
04344       case INTRN_U8VADRTMP: WN_Delete ( tree );
04345         WN_INSERT_BlockLast ( block, kid0 );
04346         if (WN_operator(WN_kid0(kid0)) != OPR_PARM)
04347           return (WN_COPY_Tree (WN_kid0(kid0)));
04348         else
04349          return (WN_COPY_Tree (WN_kid0(WN_kid0(kid0))));
04350 
04351       case INTRN_I4VALTMP:  dtype    = MTYPE_I4;
04352         loadaddr = FALSE;
04353         break;
04354 
04355       case INTRN_I8VALTMP:  dtype    = MTYPE_I8;
04356         loadaddr = FALSE;
04357         break;
04358 
04359       case INTRN_U4VALTMP:  dtype    = MTYPE_U4;
04360         loadaddr = FALSE;
04361         break;
04362 
04363       case INTRN_U8VALTMP:  dtype    = MTYPE_U8;
04364         loadaddr = FALSE;
04365         break;
04366 
04367       case INTRN_F4VALTMP:  dtype    = MTYPE_F4;
04368         loadaddr = FALSE;
04369         break;
04370 
04371       case INTRN_F8VALTMP:  dtype    = MTYPE_F8;
04372         loadaddr = FALSE;
04373         break;
04374 
04375       case INTRN_FQVALTMP:  dtype    = MTYPE_FQ;
04376         loadaddr = FALSE;
04377         break;
04378 
04379       case INTRN_C4VALTMP:  dtype    = MTYPE_C4;
04380         loadaddr = FALSE;
04381         break;
04382 
04383       case INTRN_C8VALTMP:  dtype    = MTYPE_C8;
04384         loadaddr = FALSE;
04385         break;
04386 
04387       case INTRN_CQVALTMP:  dtype    = MTYPE_CQ;
04388         loadaddr = FALSE;
04389         break;
04390 
04391       default:      return (tree);
04392 
04393     }
04394 
04395     WN_Delete ( tree );
04396     ttype = MTYPE_To_TY ( dtype );
04397     temp = Gen_Temp_Symbol ( ttype, "iotemp" );
04398     io_set_addr_saved_flag(temp);
04399 
04400     if (OPCODE_is_call(WN_opcode(kid0))) {
04401 
04402       WN_INSERT_BlockLast ( block, kid0 );
04403 
04404       if (WHIRL_Return_Info_On) {
04405 
04406   RETURN_INFO return_info = Get_Return_Info (Be_Type_Tbl(dtype),
04407                Use_Simulated);
04408 
04409   if (RETURN_INFO_count(return_info) <= 2) {
04410 
04411     reg1 = RETURN_INFO_preg (return_info, 0);
04412     reg2 = RETURN_INFO_preg (return_info, 1);
04413   }
04414 
04415   else
04416     Fail_FmtAssertion ("extract_calls: more than 2 return registers");
04417       }
04418       else
04419   Get_Return_Pregs ( dtype, MTYPE_UNKNOWN, &reg1, &reg2 );
04420 
04421       WN_INSERT_BlockLast ( block, WN_Stid ( dtype, 0, temp, ttype,
04422            WN_LdidPreg ( dtype, reg1 )));
04423 
04424     } else {
04425 
04426       WN_INSERT_BlockLast ( block, WN_Stid ( dtype, 0, temp, ttype, kid0 ));
04427 
04428     }
04429 
04430     if (loadaddr)
04431       return (WN_Lda ( Pointer_type, 0, temp ));
04432     else
04433       return (WN_Ldid ( dtype, 0, temp, ttype ));
04434 
04435   }
04436 
04437   /*  Just return the passed tree node because it's nothing special.  */
04438 
04439   return (tree);
04440 
04441 }
04442 
04443 static WN *
04444 Create_fcd (WN *block, WN *kid1, WN *kid2)
04445 {
04446    ST *st;
04447    WN *fcd;
04448 
04449    st = Get_IoStruct_ST ( block, FID_CRAY_FCD, FALSE );
04450    Gen_Io_PutAddrWN ( block, st, FCR_FCD_ADDR, WN_COPY_Tree(kid1));
04451    Gen_Io_PutFieldWN ( block, st, FCR_FCD_LEN, WN_COPY_Tree(kid2));
04452    fcd = WN_CreateMload( 0, TY_pointer(ST_type(st)),
04453              WN_CreateLda(opc_lda, 0, TY_pointer(ST_type(st)), st),
04454              WN_CreateIntconst ( OPC_U4INTCONST, fcd_size));
04455    return (fcd);
04456 }
04457 
04458 /* ====================================================================
04459  *
04460  * void copyout_temp_to_var ( WN * addr, ST *st, TY_IDX ty)
04461  *
04462  * For F90, for certain control list items, eg. iostat, exist, size, etc.,
04463  * the library expects the item to be an 32bit item. A temp is generated 
04464  * in get_32bit_cilist_item and then in this routine we generate a block
04465  * to copy all such temps back to the user variable.  
04466  *
04467  * ==================================================================== 
04468  */
04469 
04470 static void copyout_temp_to_var ( WN * addr, ST *st, TY_IDX ty)
04471 {
04472   WN * wn;
04473 
04474   if (TY_mtype(ty) == MTYPE_I1)
04475         wn = WN_CreateIstore ( OPC_I1ISTORE, 0,
04476                        Make_Pointer_Type(Be_Type_Tbl(MTYPE_I1), FALSE),
04477                        WN_CreateLdid ( OPC_I4I4LDID, 0, st,
04478                                        Be_Type_Tbl(MTYPE_I4) ), addr );
04479   else if (TY_mtype(ty) == MTYPE_U1)
04480         wn = WN_CreateIstore ( OPC_U1ISTORE, 0,
04481                        Make_Pointer_Type(Be_Type_Tbl(MTYPE_U1), FALSE),
04482                        WN_CreateLdid ( OPC_U4U4LDID, 0, st,
04483                                        Be_Type_Tbl(MTYPE_U4) ), addr );
04484   else if (TY_mtype(ty) == MTYPE_I2)
04485         wn = WN_CreateIstore ( OPC_I2ISTORE, 0,
04486                        Make_Pointer_Type(Be_Type_Tbl(MTYPE_I2), FALSE),
04487                        WN_CreateLdid ( OPC_I4I4LDID, 0, st,
04488                                        Be_Type_Tbl(MTYPE_I4) ), addr );
04489   else if (TY_mtype(ty) == MTYPE_U2)
04490         wn = WN_CreateIstore ( OPC_U2ISTORE, 0,
04491                        Make_Pointer_Type(Be_Type_Tbl(MTYPE_U2), FALSE),
04492                        WN_CreateLdid ( OPC_U4U4LDID, 0, st,
04493                                        Be_Type_Tbl(MTYPE_U4) ), addr );
04494   else if (TY_mtype(ty) == MTYPE_I8)
04495         wn = WN_CreateIstore ( OPC_I8ISTORE, 0,
04496                        Make_Pointer_Type(Be_Type_Tbl(MTYPE_I8), FALSE),
04497                        WN_CreateLdid ( OPC_I8I4LDID, 0, st,
04498                                        Be_Type_Tbl(MTYPE_I4) ), addr );
04499   else if (TY_mtype(ty) == MTYPE_U8)
04500         wn = WN_CreateIstore ( OPC_U8ISTORE, 0,
04501                        Make_Pointer_Type(Be_Type_Tbl(MTYPE_U8), FALSE),
04502                        WN_CreateLdid ( OPC_U8U4LDID, 0, st,
04503                                        Be_Type_Tbl(MTYPE_U4) ), addr );
04504   else
04505     Fail_FmtAssertion("copyout_temp_to_var: unexpected type (%s)"
04506           " in I/O processing", MTYPE_name(TY_mtype(ty)));
04507 
04508   if (copyout_block == NULL) 
04509     copyout_block = WN_CreateBlock();
04510 
04511   WN_INSERT_BlockLast ( copyout_block, wn );
04512 
04513 }
04514 
04515 /* ====================================================================
04516  *
04517  * WN * get_32bit_cilist_item(WN *cilist_item, TY_IDX ty)
04518  *
04519  * For F90, for certain control list items, eg. iostat, exist, size, etc.,
04520  * the library expects the item to be an 32bit item. If the cilist_item
04521  * is not a 32-bit item, a temp will be generated in this routine and 
04522  * copyout_temp_to_var will be called to generate a block that copies the temp
04523  * back to the user variable. Otherwise, the original item is returned.
04524  * The block, if generated, is grafted after the runtime call in 
04525  * process_iostat.
04526  *
04527  * ====================================================================
04528  */
04529 
04530 static WN *
04531 get_32bit_cilist_item(WN *cilist_item, TY_IDX ty)
04532 {
04533   TYPE_ID mtype = TY_mtype(ty);
04534   ST *st;
04535   WN *wn;
04536 
04537   if (mtype != MTYPE_I4 && mtype != MTYPE_U4) {
04538 
04539      if (MTYPE_is_signed(mtype)) {
04540        st = Gen_Temp_Symbol( MTYPE_To_TY(MTYPE_U4), "temp_cilist_item");
04541        copyout_temp_to_var(cilist_item, st, ty);
04542        wn = WN_CreateLda (opc_lda, 0,
04543                           Make_Pointer_Type (MTYPE_To_TY(MTYPE_U4), FALSE),
04544                           st);
04545      } else {
04546        st = Gen_Temp_Symbol( MTYPE_To_TY(MTYPE_I4), "temp_cilist_item");
04547        copyout_temp_to_var(cilist_item, st, ty);
04548        wn = WN_CreateLda (opc_lda, 0,
04549                           Make_Pointer_Type (MTYPE_To_TY(MTYPE_I4), FALSE),
04550                           st);
04551      }
04552      return wn;
04553   } else {
04554      return cilist_item;
04555   }
04556 }
04557 
04558 /* ====================================================================
04559  *
04560  * void process_iostat ( WN ** block1, WN ** block2, BOOL flag,
04561  *       WN * iostat, ST * err, ST * end, ST * eor,
04562  *                       BOOL zero_escape_freq )
04563  *
04564  * Called by the I/O lowerer to process all uses of the I/O status return.
04565  * The possible uses are IOSTAT=var, ERR=label, END=label or EOR=LABEL. This 
04566  * routine generates two blocks of code to deal with I/O status. The first 
04567  * (block1) is grafted after all but the last runtime call for the current I/O
04568  * statement.  The second (block2) is grafted after the final runtime
04569  * call.  Gen_Io_Call does the actual work of attaching these blocks of
04570  * code after the runtime call.  As an optimization, the flag argument is
04571  * TRUE if both blocks need to be generated (in the context of a particular
04572  * I/O statement, lower_io_statement knows if one or more runtime calls
04573  * will be required) or FALSE if only a degenerate version of block2 needs
04574  * to be generated.  zero_escape_freq is TRUE iff feedback is available
04575  * and feedback indicates that all branches to err, end, and eor have
04576  * exact zero frequency.
04577  *
04578  * ==================================================================== */
04579 
04580 static void process_iostat ( WN **block1, WN **block2, BOOL flag, WN *iostat,
04581                              LABEL_IDX err, LABEL_IDX end, LABEL_IDX eor,
04582            BOOL zero_escape_freq )
04583 {
04584   PREG_NUM rreg1, rreg2;
04585   PREG_NUM pregnum;
04586   WN * wn;
04587   WN * iostatx;
04588   WN * test_label = NULL;
04589   ST * pregst;
04590   TY_IDX  iostatty;
04591   BOOL only_copyout_needed = FALSE;
04592 
04593   /*  If no error handling is specified, then return NULL blocks. */
04594 
04595 #ifdef KEY
04596   // Under -IPA, different PUs may have different src_lang, but the driver
04597   // always passes -LANG:=ansi_c
04598   if (PU_f90_lang(Get_Current_PU())) {
04599 #else
04600   if (Language == LANG_F90) {
04601 #endif // KEY
04602     if (iostat == NULL &&
04603   end == (LABEL_IDX) 0 &&
04604   err == (LABEL_IDX) 0 &&
04605   eor == (LABEL_IDX) 0) {
04606       if (copyout_block) {
04607    only_copyout_needed = TRUE;
04608       } else {
04609          *block1 = NULL;
04610          *block2 = NULL;
04611          return;
04612       }
04613     }
04614   } else {
04615     if (iostat == NULL && end == (LABEL_IDX) 0 && err == (LABEL_IDX) 0) {
04616       *block1 = NULL;
04617       *block2 = NULL;
04618       return;
04619     }
04620   }
04621 
04622   /*  Create BLOCK nodes to hold WHIRL trees.  */
04623 
04624   if (flag)
04625     *block1 = WN_CreateBlock();
04626   else
04627     *block1 = NULL;
04628   *block2 = WN_CreateBlock();
04629 
04630 
04631 #ifdef KEY
04632   // Under -IPA, different PUs may have different src_lang, but the driver
04633   // always passes -LANG:=ansi_c
04634   if ((PU_f90_lang(Get_Current_PU())) && only_copyout_needed) {
04635 #else
04636   if ((Language == LANG_F90) && only_copyout_needed) {
04637 #endif // KEY
04638     if (flag)
04639        WN_INSERT_BlockLast ( *block1, WN_COPY_Tree(copyout_block) );
04640     WN_INSERT_BlockLast ( *block2, copyout_block );
04641     return;
04642   } 
04643 
04644   /*  Generate error test label if needed.  */
04645 
04646   if (flag)
04647     test_label = WN_CreateNewLabel();
04648 
04649   /*  Generate a preg to hold I/O status return.  */
04650 
04651   if (WHIRL_Return_Info_On) {
04652 
04653     RETURN_INFO return_info = Get_Return_Info (Be_Type_Tbl(MTYPE_I4),
04654                  Use_Simulated);
04655 
04656     if (RETURN_INFO_count(return_info) <= 2) {
04657 
04658       rreg1 = RETURN_INFO_preg (return_info, 0);
04659       rreg2 = RETURN_INFO_preg (return_info, 1);
04660     }
04661 
04662     else
04663       Fail_FmtAssertion ("process_iostat: more than 2 return registers");
04664   }
04665 
04666   else
04667     Get_Return_Pregs ( MTYPE_I4, MTYPE_UNKNOWN, &rreg1, &rreg2 );
04668 
04669   pregst = MTYPE_To_PREG ( MTYPE_I4 );
04670   pregnum = Create_Preg ( MTYPE_I4, "io_status");
04671   wn = WN_CreateStid ( OPC_I4STID, pregnum, pregst, Be_Type_Tbl(MTYPE_I4),
04672            WN_CreateLdid ( OPC_I4I4LDID, rreg1, Int32_Preg,
04673                Be_Type_Tbl(MTYPE_I4) ));
04674   if (flag)
04675     WN_INSERT_BlockLast ( *block1, WN_COPY_Tree(wn) );
04676   WN_INSERT_BlockLast ( *block2, wn );
04677 
04678 #ifdef KEY
04679   // Under -IPA, different PUs may have different src_lang, but the driver
04680   // always passes -LANG:=ansi_c
04681   if ((PU_f90_lang(Get_Current_PU())) && copyout_block) {
04682 #else
04683   if ((Language == LANG_F90) && copyout_block) {
04684 #endif // KEY
04685     if (flag)
04686        WN_INSERT_BlockLast ( *block1, WN_COPY_Tree(copyout_block) );
04687     WN_INSERT_BlockLast ( *block2, copyout_block );
04688   }
04689 
04690   /*  Generate a store into a user variable if requested. */
04691 
04692   if (current_io_library == IOLIB_MIPS && iostat != NULL) {
04693     if (WN_operator(iostat) == OPR_LDA) {
04694       iostatty = WN_ty(iostat);
04695       while (TY_kind(iostatty) == KIND_POINTER)
04696         iostatty = TY_pointed(iostatty);
04697       if (TY_mtype(iostatty) == MTYPE_I1)
04698   wn = WN_CreateStid ( OPC_I1STID, 0, WN_st(iostat),
04699            Be_Type_Tbl(MTYPE_I1),
04700            WN_CreateLdid ( OPC_I4I4LDID, pregnum, pregst,
04701                Be_Type_Tbl(MTYPE_I4) ));
04702       else if (TY_mtype(iostatty) == MTYPE_I2)
04703   wn = WN_CreateStid ( OPC_I2STID, 0, WN_st(iostat),
04704            Be_Type_Tbl(MTYPE_I2),
04705            WN_CreateLdid ( OPC_I4I4LDID, pregnum, pregst,
04706                Be_Type_Tbl(MTYPE_I4) ));
04707       else if (TY_mtype(iostatty) == MTYPE_I4)
04708   wn = WN_CreateStid ( OPC_I4STID, 0, WN_st(iostat),
04709            Be_Type_Tbl(MTYPE_I4),
04710            WN_CreateLdid ( OPC_I4I4LDID, pregnum, pregst,
04711                Be_Type_Tbl(MTYPE_I4) ));
04712       else if (TY_mtype(iostatty) == MTYPE_I8)
04713   wn = WN_CreateStid ( OPC_I8STID, 0, WN_st(iostat),
04714            Be_Type_Tbl(MTYPE_I8),
04715            WN_CreateLdid ( OPC_I8I4LDID, pregnum, pregst,
04716                Be_Type_Tbl(MTYPE_I8) ));
04717       else
04718   Fail_FmtAssertion("unexpected iostat type (%s) in"
04719         " I/O processing",
04720         MTYPE_name(TY_mtype(iostatty)));
04721     } else {
04722       iostatx = iostat;
04723       while (WN_operator(iostatx) == OPR_ARRAY)
04724   iostatx = WN_kid0(iostatx);
04725       iostatty = WN_ty(iostatx);
04726       while (TY_kind(iostatty) == KIND_POINTER ||
04727        TY_kind(iostatty) == KIND_ARRAY)
04728         if (TY_kind(iostatty) == KIND_POINTER)
04729           iostatty = TY_pointed(iostatty);
04730         else
04731           iostatty = TY_AR_etype(iostatty);
04732       if (TY_mtype(iostatty) == MTYPE_I1)
04733   wn = WN_CreateIstore ( OPC_I1ISTORE, 0,
04734              Make_Pointer_Type(Be_Type_Tbl(MTYPE_I1), FALSE),
04735              WN_CreateLdid ( OPC_I4I4LDID, pregnum, pregst,
04736                  Be_Type_Tbl(MTYPE_I4) ),
04737              iostat );
04738       else if (TY_mtype(iostatty) == MTYPE_I2)
04739   wn = WN_CreateIstore ( OPC_I2ISTORE, 0,
04740              Make_Pointer_Type(Be_Type_Tbl(MTYPE_I2), FALSE),
04741              WN_CreateLdid ( OPC_I4I4LDID, pregnum, pregst,
04742                  Be_Type_Tbl(MTYPE_I4) ),
04743              iostat );
04744       else if (TY_mtype(iostatty) == MTYPE_I4)
04745   wn = WN_CreateIstore ( OPC_I4ISTORE, 0,
04746              Make_Pointer_Type(Be_Type_Tbl(MTYPE_I4), FALSE),
04747              WN_CreateLdid ( OPC_I4I4LDID, pregnum, pregst,
04748                  Be_Type_Tbl(MTYPE_I4) ),
04749              iostat );
04750       else if (TY_mtype(iostatty) == MTYPE_I8)
04751   wn = WN_CreateIstore ( OPC_I8ISTORE, 0,
04752              Make_Pointer_Type(Be_Type_Tbl(MTYPE_I8), FALSE),
04753              WN_CreateLdid ( OPC_I8I4LDID, pregnum, pregst,
04754                  Be_Type_Tbl(MTYPE_I8) ),
04755              iostat );
04756       else
04757   Fail_FmtAssertion("unexpected iostat type (%s) in I/O processing",
04758         MTYPE_name(TY_mtype(iostatty)));
04759     }
04760     if (flag)
04761       WN_INSERT_BlockLast ( *block1, WN_COPY_Tree(wn) );
04762     WN_INSERT_BlockLast ( *block2, wn );
04763   }
04764 
04765   /*  Generate general error branch if needed.  */
04766 
04767   if (flag) {
04768     wn = WN_CreateTruebr ( WN_label_number(test_label),
04769          WN_CreateExp2 ( OPC_I4I4NE,
04770              WN_CreateLdid ( OPC_I4I4LDID,
04771                  pregnum, pregst,
04772               Be_Type_Tbl(MTYPE_I4) ),
04773              WN_CreateIntconst ( OPC_I4INTCONST,
04774                      0 )));
04775     WN_INSERT_BlockLast ( *block1, wn );
04776     WN_INSERT_BlockLast ( *block2, test_label );
04777   }
04778 
04779   if (current_io_library == IOLIB_MIPS) {
04780      /*  Generate a conditional branch to an end statement if requested.  */
04781      
04782      if (end != (LABEL_IDX) 0) {
04783        LABEL_IDX end_label;
04784        end_label = end;
04785        wn = WN_CreateTruebr ( end_label,
04786            WN_CreateExp2 ( OPC_I4I4LT,
04787                WN_CreateLdid ( OPC_I4I4LDID,
04788                    pregnum, pregst,
04789                 Be_Type_Tbl(MTYPE_I4) ),
04790                WN_CreateIntconst ( OPC_I4INTCONST,
04791                        0 )));
04792        WN_INSERT_BlockLast ( *block2, wn );
04793 
04794        // Update feedback
04795        if ( zero_escape_freq && Cur_PU_Feedback )
04796    Cur_PU_Feedback->Annot( wn, FB_EDGE_BRANCH_TAKEN, FB_FREQ_ZERO );
04797      }
04798    
04799      /*  Generate a conditional branch to an error statement if requested.  */
04800    
04801      if (err != (LABEL_IDX) 0) {
04802        LABEL_IDX err_label;
04803        err_label = err;
04804        if (!end && !iostat)
04805          wn = WN_CreateTruebr ( err_label,
04806            WN_CreateExp2 ( OPC_I4I4NE,
04807                WN_CreateLdid ( OPC_I4I4LDID,
04808                    pregnum, pregst,
04809                 Be_Type_Tbl(MTYPE_I4) ),
04810                WN_CreateIntconst ( OPC_I4INTCONST,
04811                        0 )));
04812        else
04813          wn = WN_CreateTruebr ( err_label,
04814            WN_CreateExp2 ( OPC_I4I4GT,
04815                WN_CreateLdid ( OPC_I4I4LDID,
04816                    pregnum, pregst,
04817                 Be_Type_Tbl(MTYPE_I4) ),
04818                WN_CreateIntconst ( OPC_I4INTCONST,
04819                        0 )));
04820        WN_INSERT_BlockLast ( *block2, wn );
04821 
04822        // Update feedback
04823        if ( zero_escape_freq && Cur_PU_Feedback )
04824    Cur_PU_Feedback->Annot( wn, FB_EDGE_BRANCH_TAKEN, FB_FREQ_ZERO );
04825      }
04826   } else {      /* IOLIB_CRAY */
04827      if (err != (LABEL_IDX) 0) {
04828        LABEL_IDX err_label;
04829        err_label = err;
04830        wn = WN_CreateTruebr ( err_label,
04831            WN_CreateExp2 ( OPC_I4I4EQ,
04832                WN_CreateLdid ( OPC_I4I4LDID,
04833                    pregnum, pregst,
04834                 Be_Type_Tbl(MTYPE_I4) ),
04835                WN_CreateIntconst ( OPC_I4INTCONST,
04836                        1 )));
04837        WN_INSERT_BlockLast ( *block2, wn );
04838 
04839        // Update feedback
04840        if ( zero_escape_freq && Cur_PU_Feedback )
04841    Cur_PU_Feedback->Annot( wn, FB_EDGE_BRANCH_TAKEN, FB_FREQ_ZERO );
04842      }
04843 
04844      if (end != (LABEL_IDX) 0) {
04845        LABEL_IDX end_label;
04846        end_label = end;
04847        wn = WN_CreateTruebr ( end_label,
04848            WN_CreateExp2 ( OPC_I4I4EQ,
04849                WN_CreateLdid ( OPC_I4I4LDID,
04850                    pregnum, pregst,
04851                 Be_Type_Tbl(MTYPE_I4) ),
04852                WN_CreateIntconst ( OPC_I4INTCONST,
04853                        2 )));
04854        WN_INSERT_BlockLast ( *block2, wn );
04855 
04856        // Update feedback
04857        if ( zero_escape_freq && Cur_PU_Feedback )
04858    Cur_PU_Feedback->Annot( wn, FB_EDGE_BRANCH_TAKEN, FB_FREQ_ZERO );
04859      }
04860 
04861      if (eor != (LABEL_IDX) 0) {
04862        LABEL_IDX eor_label;
04863        eor_label = eor;
04864        wn = WN_CreateTruebr ( eor_label,
04865            WN_CreateExp2 ( OPC_I4I4EQ,
04866                WN_CreateLdid ( OPC_I4I4LDID,
04867                    pregnum, pregst,
04868                 Be_Type_Tbl(MTYPE_I4) ),
04869                WN_CreateIntconst ( OPC_I4INTCONST,
04870                        3 )));
04871        WN_INSERT_BlockLast ( *block2, wn );
04872 
04873        // Update feedback
04874        if ( zero_escape_freq && Cur_PU_Feedback )
04875    Cur_PU_Feedback->Annot( wn, FB_EDGE_BRANCH_TAKEN, FB_FREQ_ZERO );
04876      }
04877   }
04878 }
04879 
04880 /* ====================================================================
04881  *
04882  * void process_inqvar ( WN ** block, WN *var )
04883  *
04884  * Called by the I/O lowerer to process the return val for 
04885  * inquire(iolength=var). This routine generates a block of code to 
04886  * store the value returned by the inquire call into the user variable.
04887  * Gen_Io_Call does the actual work of attaching this block after the
04888  * runtime call.
04889  *
04890  *
04891  * ==================================================================== */
04892 
04893 static void process_inqvar ( WN ** block, WN * var)
04894 {
04895   PREG_NUM rreg1, rreg2;
04896   PREG_NUM pregnum;
04897   WN * wn;
04898   WN * varx;
04899   ST * pregst;
04900   TY_IDX  varty;
04901 
04902   if (var != NULL) {
04903     *block = WN_CreateBlock();
04904 
04905     /*  Generate a preg to hold I/O status return.  */
04906 
04907     if (WHIRL_Return_Info_On) {
04908 
04909       RETURN_INFO return_info = Get_Return_Info (Be_Type_Tbl(MTYPE_I4),
04910                                                  Use_Simulated);
04911 
04912       if (RETURN_INFO_count(return_info) <= 2) {
04913 
04914   rreg1 = RETURN_INFO_preg (return_info, 0);
04915   rreg2 = RETURN_INFO_preg (return_info, 1);
04916       }
04917 
04918       else
04919         Fail_FmtAssertion ("process_inqvar: more than 2 return registers");
04920     }
04921 
04922     else
04923       Get_Return_Pregs ( MTYPE_I4, MTYPE_UNKNOWN, &rreg1, &rreg2 );
04924 
04925     pregst = MTYPE_To_PREG ( MTYPE_I4 );
04926     pregnum = Create_Preg ( MTYPE_I4, "io_status");
04927     wn = WN_CreateStid ( OPC_I4STID, pregnum, pregst, Be_Type_Tbl(MTYPE_I4),
04928              WN_CreateLdid ( OPC_I4I4LDID, rreg1, Int32_Preg,
04929                  Be_Type_Tbl(MTYPE_I4) ));
04930     WN_INSERT_BlockLast ( *block, wn );
04931 
04932     if (WN_operator(var) == OPR_LDA) {
04933       varty = WN_ty(var);
04934       while (TY_kind(varty) == KIND_POINTER)
04935         varty = TY_pointed(varty);
04936       if (TY_mtype(varty) == MTYPE_I1)
04937   wn = WN_CreateStid ( OPC_I1STID, 0, WN_st(var),
04938            Be_Type_Tbl(MTYPE_I1),
04939            WN_CreateLdid ( OPC_I4I4LDID, pregnum, pregst,
04940                Be_Type_Tbl(MTYPE_I4) ));
04941       else if (TY_mtype(varty) == MTYPE_I2)
04942   wn = WN_CreateStid ( OPC_I2STID, 0, WN_st(var),
04943            Be_Type_Tbl(MTYPE_I2),
04944            WN_CreateLdid ( OPC_I4I4LDID, pregnum, pregst,
04945                Be_Type_Tbl(MTYPE_I4) ));
04946       else if (TY_mtype(varty) == MTYPE_I4)
04947   wn = WN_CreateStid ( OPC_I4STID, 0, WN_st(var),
04948            Be_Type_Tbl(MTYPE_I4),
04949            WN_CreateLdid ( OPC_I4I4LDID, pregnum, pregst,
04950                Be_Type_Tbl(MTYPE_I4) ));
04951       else if (TY_mtype(varty) == MTYPE_I8)
04952   wn = WN_CreateStid ( OPC_I8STID, 0, WN_st(var),
04953            Be_Type_Tbl(MTYPE_I8),
04954            WN_CreateLdid ( OPC_I8I4LDID, pregnum, pregst,
04955                Be_Type_Tbl(MTYPE_I8) ));
04956       else
04957   Fail_FmtAssertion("process_inqvar, LDA: unexpected var type (%s)"
04958         " in I/O processing", MTYPE_name(TY_mtype(varty)));
04959     } else {
04960       varx = var;
04961       while (WN_operator(varx) == OPR_ARRAY)
04962   varx = WN_kid0(varx);
04963       varty = WN_ty(varx);
04964       while (TY_kind(varty) == KIND_POINTER ||
04965        TY_kind(varty) == KIND_ARRAY)
04966         if (TY_kind(varty) == KIND_POINTER)
04967           varty = TY_pointed(varty);
04968         else
04969           varty = TY_AR_etype(varty);
04970       if (TY_mtype(varty) == MTYPE_I1)
04971   wn = WN_CreateIstore ( OPC_I1ISTORE, 0,
04972              Make_Pointer_Type(Be_Type_Tbl(MTYPE_I1), FALSE),
04973              WN_CreateLdid ( OPC_I4I4LDID, pregnum, pregst,
04974                  Be_Type_Tbl(MTYPE_I4) ),
04975              var );
04976       else if (TY_mtype(varty) == MTYPE_I2)
04977   wn = WN_CreateIstore ( OPC_I2ISTORE, 0,
04978              Make_Pointer_Type(Be_Type_Tbl(MTYPE_I2), FALSE),
04979              WN_CreateLdid ( OPC_I4I4LDID, pregnum, pregst,
04980                  Be_Type_Tbl(MTYPE_I4) ),
04981              var );
04982       else if (TY_mtype(varty) == MTYPE_I4)
04983   wn = WN_CreateIstore ( OPC_I4ISTORE, 0,
04984              Make_Pointer_Type(Be_Type_Tbl(MTYPE_I4), FALSE),
04985              WN_CreateLdid ( OPC_I4I4LDID, pregnum, pregst,
04986                  Be_Type_Tbl(MTYPE_I4) ),
04987              var );
04988       else if (TY_mtype(varty) == MTYPE_I8)
04989   wn = WN_CreateIstore ( OPC_I8ISTORE, 0,
04990              Make_Pointer_Type(Be_Type_Tbl(MTYPE_I8), FALSE),
04991              WN_CreateLdid ( OPC_I8I4LDID, pregnum, pregst,
04992                  Be_Type_Tbl(MTYPE_I8) ),
04993              var );
04994       else
04995   Fail_FmtAssertion("process_inqvar: unexpected var type (%s)"
04996         " in I/O processing", MTYPE_name(TY_mtype(varty)));
04997     }
04998     WN_INSERT_BlockLast ( *block, wn );
04999   }
05000 }
05001 
05002 
05003 static mINT32 search_implied_do_index ( WN *array_index, ST *implied_do_index )
05004 {
05005 
05006     if ((WN_operator( array_index ) == OPR_CALL) ||
05007   (WN_operator( array_index ) == OPR_ICALL) ||
05008   (WN_operator( array_index ) == OPR_PICCALL) ||
05009   (WN_operator( array_index ) == OPR_INTRINSIC_CALL)) {
05010       return( 1 );
05011     } else if (WN_kid_count( array_index ) == 0) {
05012       if (WN_operator( array_index ) == OPR_LDID 
05013     && WN_st( array_index ) == implied_do_index)
05014   return( 1 );
05015     } else if (WN_kid_count( array_index ) == 1) {
05016       return( search_implied_do_index( WN_kid0( array_index ),
05017                implied_do_index));
05018     } else if (WN_kid_count( array_index ) == 2) {
05019       if (search_implied_do_index( WN_kid0( array_index ), implied_do_index))
05020     return( 1 );
05021       if (search_implied_do_index( WN_kid1( array_index ), implied_do_index))
05022     return( 1 );
05023     } else 
05024       /* return found for unrecognizable expression so no optimization
05025       ** will be done and to ensure correctness
05026       */
05027       return( 1 );
05028   return( 0 );
05029 }
05030 
05031 
05032 static FIOITEMTYPE get_FIT_type ( TY_IDX ty )
05033 {
05034   FIOITEMTYPE type;
05035   INT32       mtype = TY_mtype(ty);
05036   BOOL        char_flag = TY_is_character(Ty_Table [ty]);
05037   BOOL        logical_flag = TY_is_logical(Ty_Table [ty]);
05038 
05039   switch (mtype) {
05040 
05041     case MTYPE_U1:
05042   type = FIT_CHARACTER;
05043   break;
05044 
05045     case MTYPE_I1:
05046   if (char_flag)
05047     type = FIT_CHARACTER;
05048   else if (logical_flag)
05049     type = FIT_LOGICAL1;
05050   else
05051     type = FIT_INTEGER1;
05052   break;
05053 
05054     case MTYPE_I2:
05055   if (logical_flag)
05056     type = FIT_LOGICAL2;
05057   else
05058     type = FIT_INTEGER2;
05059   break;
05060 
05061     case MTYPE_I4:
05062   if (logical_flag)
05063     type = FIT_LOGICAL4;
05064   else
05065     type = FIT_INTEGER4;
05066   break;
05067 
05068     case MTYPE_I8:
05069   if (logical_flag)
05070     type = FIT_LOGICAL8;
05071   else
05072     type = FIT_INTEGER8;
05073   break;
05074 
05075     case MTYPE_U4:
05076   type = FIT_ADDRESS4;
05077   break;
05078 
05079     case MTYPE_U8:
05080   type = FIT_ADDRESS8;
05081   break;
05082 
05083     case MTYPE_F4:
05084   type = FIT_REAL4;
05085   break;
05086 
05087     case MTYPE_F8:
05088   type = FIT_REAL8;
05089   break;
05090 
05091     case MTYPE_F10:
05092     case MTYPE_FQ:
05093   type = FIT_REAL16;
05094   break;
05095 
05096     case MTYPE_C4:
05097   type = FIT_COMPLEX4;
05098   break;
05099 
05100     case MTYPE_C8:
05101   type = FIT_COMPLEX8;
05102   break;
05103 
05104     case MTYPE_CQ:
05105   type = FIT_COMPLEX16;
05106   break;
05107 
05108     case MTYPE_M:
05109   type = FIT_RECORD;
05110   break;
05111 
05112     case MTYPE_UNKNOWN:
05113   if (char_flag) {
05114     type = FIT_CHARACTER;
05115     break;
05116         }
05117   /*  Allow to fall through to error.  */
05118 
05119     default:
05120       Fail_FmtAssertion("get_FIT_type: unexpected type (%s) in I/O processing",
05121       MTYPE_name(mtype));
05122 
05123   }
05124 
05125   return type;
05126 
05127 }
05128 
05129 
05130 
05131 /* ====================================================================
05132  *
05133  * void lower_record_items (WN * block, FIOFORMATTYPE form, WN * iostat,
05134  *          BOOL mode, TY_IDX  rty_idx, WN * addr, INT64 offset)
05135  *
05136  * Perform lowering of record io item list in fortran io statements.
05137  *
05138  * ==================================================================== */
05139 
05140 static void lower_record_items ( WN * block, FIOFORMATTYPE form, WN * iostat,
05141          BOOL mode, TY_IDX rty_idx, WN * addr, INT64 roffset)
05142 {
05143   TY_IDX ty_idx;
05144   TY_IDX ety_idx;
05145   FIOITEMTYPE type;
05146   FIOITEMTYPE etype;
05147   ST *unit_ptr;
05148   INT64 offset;
05149   WN *wn;
05150   WN *wn1;
05151   WN *wn2;
05152   WN *wn3;
05153   INT64 size;
05154   INT64 nelem;
05155   ST *ctrst;
05156   ST *adrst;
05157   PREG_NUM ctrnum;
05158   PREG_NUM adrnum;
05159   WN *raddr;
05160   WN *recblk;
05161 
05162   TY& rty = Ty_Table [rty_idx];
05163 
05164   Is_True (TY_kind(rty) == KIND_STRUCT,
05165      ("non record type passed to lower_record_items"));
05166 
05167   /*  Process all fields in the record.  */
05168 
05169   FLD_ITER fld_iter = Make_fld_iter (TY_fld(rty));
05170 
05171   do {
05172     FLD_HANDLE fld (fld_iter);
05173 
05174     ty_idx = FLD_type(fld);
05175     TY& ty = Ty_Table [ty_idx];
05176     offset = roffset + FLD_ofst(fld);
05177 
05178     switch (TY_kind(ty)) {
05179 
05180       case KIND_SCALAR:
05181       case KIND_POINTER:
05182 
05183   type = get_FIT_type ( ty_idx );
05184   if (mode) {
05185     (void) Make_Pointer_Type ( ty_idx, FALSE );
05186     if (offset <= INT32_MAX)
05187       wn1 = WN_CreateLda ( opc_lda, offset, TY_pointer(ty_idx, FALSE),
05188          WN_st(addr) );
05189     else
05190       wn1 = WN_Add ( Pointer_type,
05191          WN_CreateLda ( opc_lda, 0, TY_pointer(ty_idx, FALSE),
05192             WN_st(addr) ),
05193          WN_CreateIntconst ( opc_const, offset ) );
05194   } else
05195     wn1 = WN_Add ( Pointer_type, WN_COPY_Tree(addr),
05196        WN_CreateIntconst ( opc_const, offset ) );
05197   if (mp_io) {
05198           unit_ptr = Get_UnitPointer_ST();
05199     GEN_IO_CALL_3 ( block, fio_item_ops[form][type], iostat, NULL,
05200         wn1, WN_CreateIntconst ( OPC_I4INTCONST, 1 ),
05201         Make_IoAddr_WN(unit_ptr) );
05202   } else
05203     GEN_IO_CALL_2 ( block, fio_item_ops[form][type], iostat, NULL,
05204         wn1, WN_CreateIntconst ( OPC_I4INTCONST, 1 ));
05205   break;
05206 
05207       case KIND_ARRAY:
05208 
05209       {
05210 
05211   ety_idx = TY_AR_etype(ty);
05212         TY& ety = Ty_Table [ety_idx];
05213   etype = get_FIT_type ( ety_idx );
05214   switch (etype) {
05215 
05216     case FIT_ADDRESS4:
05217     case FIT_ADDRESS8:
05218     case FIT_INTEGER1:
05219     case FIT_INTEGER2:
05220     case FIT_INTEGER4:
05221     case FIT_INTEGER8:
05222     case FIT_LOGICAL1:
05223     case FIT_LOGICAL2:
05224     case FIT_LOGICAL4:
05225     case FIT_LOGICAL8:
05226     case FIT_REAL4:
05227     case FIT_REAL8:
05228     case FIT_REAL16:
05229     case FIT_COMPLEX4:
05230     case FIT_COMPLEX8:
05231     case FIT_COMPLEX16:
05232       if (mode) {
05233         (void) Make_Pointer_Type ( ety_idx, FALSE );
05234         if (offset <= INT32_MAX)
05235     wn1 = WN_CreateLda ( opc_lda, offset, TY_pointer(ety_idx, FALSE),
05236              WN_st(addr) );
05237         else
05238     wn1 = WN_Add ( Pointer_type,
05239              WN_CreateLda ( opc_lda, 0, TY_pointer(ety_idx, FALSE),
05240                 WN_st(addr) ),
05241              WN_CreateIntconst ( opc_const, offset ) );
05242       } else
05243         wn1 = WN_Add ( Pointer_type, WN_COPY_Tree(addr),
05244            WN_CreateIntconst ( opc_const, offset ) );
05245       nelem = TY_size(ty) / TY_size(ety);
05246       if (nelem <= INT32_MAX)
05247         wn2 = WN_CreateIntconst ( OPC_I4INTCONST, nelem );
05248       else
05249         wn2 = WN_CreateIntconst ( OPC_I8INTCONST, nelem );
05250       if (mp_io) {
05251               unit_ptr = Get_UnitPointer_ST();
05252         GEN_IO_CALL_3 ( block, fio_item_ops[form][etype], iostat, NULL,
05253             wn1, wn2, Make_IoAddr_WN(unit_ptr) );
05254       } else
05255         GEN_IO_CALL_2 ( block, fio_item_ops[form][etype], iostat, NULL,
05256             wn1, wn2 );
05257       break;
05258 
05259     case FIT_CHARACTER:
05260       if (mode) {
05261         (void) Make_Pointer_Type ( ety_idx, FALSE );
05262         if (offset <= INT32_MAX)
05263     wn1 = WN_CreateLda ( opc_lda, offset, TY_pointer(ety_idx, FALSE),
05264              WN_st(addr) );
05265         else
05266     wn1 = WN_Add ( Pointer_type,
05267              WN_CreateLda ( opc_lda, 0, TY_pointer(ety_idx, FALSE),
05268                 WN_st(addr) ),
05269              WN_CreateIntconst ( opc_const, offset ) );
05270       } else
05271         wn1 = WN_Add ( Pointer_type, WN_COPY_Tree(addr),
05272            WN_CreateIntconst ( opc_const, offset ) );
05273       if (TY_kind(ety) == KIND_ARRAY) {
05274         size = TY_size(ety);
05275         nelem = TY_size(ty) / size;
05276       } else {
05277         size = TY_size(ty);
05278         nelem = 1;
05279       }
05280       if (size <= INT32_MAX)
05281         wn2 = WN_CreateIntconst ( OPC_I4INTCONST, size );
05282       else
05283         wn2 = WN_CreateIntconst ( OPC_I8INTCONST, size );
05284       if (nelem <= INT32_MAX)
05285         wn3 = WN_CreateIntconst ( OPC_I4INTCONST, nelem );
05286       else
05287         wn3 = WN_CreateIntconst ( OPC_I8INTCONST, nelem );
05288       if (mp_io) {
05289               unit_ptr = Get_UnitPointer_ST();
05290         GEN_IO_CALL_4 ( block, fio_item_ops[form][etype], iostat, NULL,
05291             wn1, wn2, wn3, Make_IoAddr_WN(unit_ptr) );
05292       } else
05293         GEN_IO_CALL_3 ( block, fio_item_ops[form][etype], iostat, NULL,
05294             wn1, wn2, wn3 );
05295       break;
05296 
05297     case FIT_RECORD:
05298       if (mode) {
05299         (void) Make_Pointer_Type ( ety_idx, FALSE );
05300         if (offset <= INT32_MAX)
05301     wn = WN_CreateLda ( opc_lda, offset, TY_pointer(ety_idx, FALSE),
05302             WN_st(addr) );
05303         else
05304     wn = WN_Add ( Pointer_type,
05305             WN_CreateLda ( opc_lda, 0, TY_pointer(ety_idx, FALSE),
05306                WN_st(addr) ),
05307             WN_CreateIntconst ( opc_const, offset ) );
05308       } else
05309         wn = WN_Add ( Pointer_type, WN_COPY_Tree(addr),
05310           WN_CreateIntconst ( opc_const, offset ) );
05311       adrst = MTYPE_To_PREG ( Pointer_type );
05312       adrnum = Create_Preg ( Pointer_type, "record_address");
05313       WN_INSERT_BlockLast ( block,
05314           WN_StidIntoPreg ( Pointer_type, adrnum, adrst,
05315                 wn ));
05316       recblk = WN_CreateBlock();
05317       ctrst = MTYPE_To_PREG ( MTYPE_I4 );
05318       ctrnum = Create_Preg ( MTYPE_I4, "record_counter");
05319       size = TY_size(ety);
05320       nelem = TY_size(ty) / size;
05321       WN_INSERT_BlockLast ( block,
05322           WN_CreateDO (
05323             WN_CreateIdname ( ctrnum, ctrst ),
05324             WN_StidIntoPreg ( MTYPE_I4, ctrnum, ctrst,
05325                WN_CreateIntconst ( OPC_I4INTCONST, 1 )),
05326             WN_LE ( MTYPE_I4,
05327               WN_LdidPreg ( MTYPE_I4, ctrnum ),
05328               WN_CreateIntconst ( OPC_I4INTCONST,
05329                 nelem )),
05330             WN_StidIntoPreg ( MTYPE_I4, ctrnum, ctrst,
05331                   WN_Add ( MTYPE_I4,
05332                      WN_LdidPreg ( MTYPE_I4,
05333                        ctrnum ),
05334                WN_CreateIntconst ( OPC_I4INTCONST,
05335                  (INT64)1 ))),
05336             recblk, NULL ));
05337       raddr = WN_LdidPreg ( Pointer_type, adrnum );
05338       lower_record_items ( recblk, form, iostat, FALSE, ety_idx, raddr,
05339          (INT64)0 );
05340       WN_INSERT_BlockLast ( recblk,
05341           WN_StidIntoPreg ( Pointer_type, adrnum, adrst,
05342             WN_Add ( Pointer_type, raddr,
05343               WN_CreateIntconst ( opc_const, size ))));
05344       break;
05345 
05346     default:
05347       Fail_FmtAssertion("unexpected type (%s) in record I/O processing",
05348             MTYPE_name(TY_mtype(ety)));
05349 
05350   }
05351 
05352   break;
05353 
05354       }
05355 
05356       case KIND_STRUCT:
05357   lower_record_items ( block, form, iostat, mode, ty_idx, addr, offset );
05358   break;
05359 
05360       case KIND_VOID:
05361   break;
05362 
05363       default:
05364   Fail_FmtAssertion("unexpected type (%s) in record I/O processing",
05365         MTYPE_name(TY_mtype(ty)));
05366 
05367     }
05368 
05369   } while (! FLD_last_field (fld_iter++));
05370 }
05371 
05372 
05373 /* ====================================================================
05374  *
05375  * void lower_io_items (WN * block, WN * tree, FIOFORMATTYPE form,
05376  *            WN * iostat, INT32 kid_first, INT32 kid_last)
05377  *
05378  * Perform lowering of the io item list in fortran io statements.
05379  *
05380  * ==================================================================== */
05381 
05382 static void lower_io_items ( WN * block, WN * tree, FIOFORMATTYPE form,
05383            WN * iostat, INT32 kid_first, INT32 kid_last )
05384 {
05385   INT32 i;
05386   INT32 j;
05387   INT32 mtype;
05388   INT32 ntype;
05389   INT64 size;
05390   INT64 nelem;
05391   FIOITEMTYPE type;
05392   TY_IDX ty;
05393   TY_IDX ety;
05394   WN *item;
05395   WN *top_label;
05396   WN *cont_label;
05397   WN *start;
05398   WN *step;
05399   WN *end;
05400   WN *load_index;
05401   WN *raddr;
05402   WN *recblk;
05403   ST *pregst;
05404   ST *unit_ptr;
05405   ST *ctrst;
05406   ST *adrst;
05407   PREG_NUM pregnum;
05408   PREG_NUM ctrnum;
05409   PREG_NUM adrnum;
05410   IOITEM io_item;
05411 
05412   /*  Process all of the I/O items.  */
05413 
05414   for (i=kid_first; i<kid_last; i++) {
05415 
05416     item = WN_kid(tree,i);
05417     io_item = (IOITEM) WN_intrinsic(item);
05418 
05419     /*  If a real I/O item preprocess and determine type.  */
05420 
05421     if (io_item != IOL_IMPLIED_DO && io_item != IOL_IMPLIED_DO_1TRIP) {
05422       item = extract_calls ( block, item );
05423       if (io_item != IOL_ARRAY)
05424   type = get_FIT_type ( WN_ty(item) );
05425     }
05426 
05427     /*  Generate the appropriate I/O runtime call for the item.  */
05428 
05429     switch (io_item) {
05430 
05431       case IOL_ARRAY:
05432     ety = TY_AR_etype(WN_ty(item));
05433     type = get_FIT_type ( ety );
05434     if (type == FIT_RECORD) {
05435       adrst = MTYPE_To_PREG ( Pointer_type );
05436       adrnum = Create_Preg ( Pointer_type, "record_address");
05437       WN_INSERT_BlockLast ( block,
05438           WN_StidIntoPreg ( Pointer_type, adrnum, adrst,
05439                 WN_kid0(item) ));
05440       recblk = WN_CreateBlock();
05441       ctrst = MTYPE_To_PREG ( MTYPE_I4 );
05442       ctrnum = Create_Preg ( MTYPE_I4, "record_counter");
05443       size = TY_size(ety);
05444       nelem = TY_size(WN_ty(item)) / size;
05445       WN_INSERT_BlockLast ( block,
05446           WN_CreateDO (
05447             WN_CreateIdname ( ctrnum, ctrst ),
05448             WN_StidIntoPreg ( MTYPE_I4, ctrnum, ctrst,
05449                WN_CreateIntconst ( OPC_I4INTCONST, 1 )),
05450             WN_LE ( MTYPE_I4,
05451               WN_LdidPreg ( MTYPE_I4, ctrnum ),
05452               WN_CreateIntconst ( OPC_I4INTCONST,
05453                 nelem )),
05454             WN_StidIntoPreg ( MTYPE_I4, ctrnum, ctrst,
05455                   WN_Add ( MTYPE_I4,
05456                      WN_LdidPreg ( MTYPE_I4,
05457                        ctrnum ),
05458                WN_CreateIntconst ( OPC_I4INTCONST,
05459                  (INT64)1 ))),
05460             recblk, NULL ));
05461       raddr = WN_LdidPreg ( Pointer_type, adrnum );
05462       lower_record_items ( recblk, form, iostat, FALSE, ety, raddr,
05463          (INT64)0 );
05464       WN_INSERT_BlockLast ( recblk,
05465           WN_StidIntoPreg ( Pointer_type, adrnum, adrst,
05466             WN_Add ( Pointer_type, raddr,
05467               WN_CreateIntconst ( opc_const, size ))));
05468       WN_DELETE_Tree ( WN_kid1(item) );
05469     } else {
05470       if (mp_io) {
05471         unit_ptr = Get_UnitPointer_ST();
05472         GEN_IO_CALL_3 ( block, fio_item_ops[form][type], iostat, NULL,
05473             WN_kid0(item), WN_kid1(item), 
05474             Make_IoAddr_WN(unit_ptr) );
05475       }
05476       else
05477         GEN_IO_CALL_2 ( block, fio_item_ops[form][type], iostat, NULL,
05478             WN_kid0(item), WN_kid1(item) );
05479     }
05480     break;
05481 
05482       case IOL_CHAR:
05483     if (mp_io) {
05484             unit_ptr = Get_UnitPointer_ST();
05485       GEN_IO_CALL_4 ( block, fio_item_ops[form][type], iostat, NULL,
05486         WN_kid0(item), WN_kid1(item), 
05487         WN_CreateIntconst ( OPC_I4INTCONST, 1 ),
05488         Make_IoAddr_WN(unit_ptr) );
05489     }
05490     else
05491       GEN_IO_CALL_3 ( block, fio_item_ops[form][type], iostat, NULL,
05492         WN_kid0(item), WN_kid1(item),
05493         WN_CreateIntconst ( OPC_I4INTCONST, 1 ) );
05494     break;
05495 
05496       case IOL_CHAR_ARRAY:
05497     if (mp_io) {
05498             unit_ptr = Get_UnitPointer_ST();
05499       GEN_IO_CALL_4 ( block, fio_item_ops[form][type], iostat, NULL,
05500         WN_kid0(item), WN_kid1(item), 
05501         WN_kid2(item),
05502         Make_IoAddr_WN(unit_ptr) );
05503     }
05504     else
05505       GEN_IO_CALL_3 ( block, fio_item_ops[form][type], iostat, NULL,
05506         WN_kid0(item), WN_kid1(item), WN_kid2(item) );
05507     break;
05508 
05509       case IOL_EXPR:
05510     switch (type) {
05511       case FIT_COMPLEX4:
05512     pregst = MTYPE_To_PREG ( MTYPE_C4 );
05513     pregnum = Create_Preg ( MTYPE_C4, "complex_io_item");
05514     WN_INSERT_BlockLast ( block,
05515               WN_StidIntoPreg ( MTYPE_C4, pregnum,
05516               pregst,
05517               WN_kid0(item) ));
05518           if (mp_io) {
05519                   unit_ptr = Get_UnitPointer_ST();
05520             GEN_IO_CALL_3 ( block, fio_value_ops[form][type], iostat, 
05521         NULL, WN_CreateExp1 ( OPC_F4REALPART,
05522           WN_LdidPreg ( MTYPE_C4, pregnum )),
05523         WN_CreateExp1 ( OPC_F4IMAGPART,
05524           WN_LdidPreg ( MTYPE_C4, pregnum )),
05525         Make_IoAddr_WN(unit_ptr) );
05526           }
05527           else
05528       GEN_IO_CALL_2 ( block, fio_value_ops[form][type], iostat, 
05529         NULL, WN_CreateExp1 ( OPC_F4REALPART,
05530           WN_LdidPreg ( MTYPE_C4, pregnum )),
05531         WN_CreateExp1 ( OPC_F4IMAGPART,
05532           WN_LdidPreg ( MTYPE_C4, pregnum )));
05533     break;
05534       case FIT_COMPLEX8:
05535     pregst = MTYPE_To_PREG ( MTYPE_C8 );
05536     pregnum = Create_Preg ( MTYPE_C8, "complex_io_item");
05537 
05538     WN_INSERT_BlockLast ( block,
05539               WN_StidIntoPreg ( MTYPE_C8, pregnum,
05540               pregst,
05541               WN_kid0(item) ));
05542           if (mp_io) {
05543                   unit_ptr = Get_UnitPointer_ST();
05544             GEN_IO_CALL_3 ( block, fio_value_ops[form][type], iostat, 
05545         NULL, WN_CreateExp1 ( OPC_F8REALPART,
05546           WN_LdidPreg ( MTYPE_C8, pregnum )),
05547         WN_CreateExp1 ( OPC_F8IMAGPART,
05548           WN_LdidPreg ( MTYPE_C8, pregnum )),
05549         Make_IoAddr_WN(unit_ptr) );
05550           }
05551           else
05552       GEN_IO_CALL_2 ( block, fio_value_ops[form][type], iostat, 
05553         NULL, WN_CreateExp1 ( OPC_F8REALPART,
05554           WN_LdidPreg ( MTYPE_C8, pregnum )),
05555         WN_CreateExp1 ( OPC_F8IMAGPART,
05556           WN_LdidPreg ( MTYPE_C8, pregnum )));
05557     break;
05558       case FIT_COMPLEX16:
05559     pregst = MTYPE_To_PREG ( MTYPE_CQ );
05560     pregnum = Create_Preg ( MTYPE_CQ, "complex_io_item");
05561     WN_INSERT_BlockLast ( block,
05562               WN_StidIntoPreg ( MTYPE_CQ, pregnum,
05563               pregst,
05564               WN_kid0(item) ));
05565           if (mp_io) {
05566                   unit_ptr = Get_UnitPointer_ST();
05567             GEN_IO_CALL_3 ( block, fio_value_ops[form][type], iostat, 
05568         NULL, WN_CreateExp1 ( OPC_FQREALPART,
05569           WN_LdidPreg ( MTYPE_CQ, pregnum )),
05570         WN_CreateExp1 ( OPC_FQIMAGPART,
05571           WN_LdidPreg ( MTYPE_CQ, pregnum )),
05572         Make_IoAddr_WN(unit_ptr) );
05573           }
05574           else
05575       GEN_IO_CALL_2 ( block, fio_value_ops[form][type], iostat, 
05576         NULL, WN_CreateExp1 ( OPC_FQREALPART,
05577           WN_LdidPreg ( MTYPE_CQ, pregnum )),
05578         WN_CreateExp1 ( OPC_FQIMAGPART,
05579           WN_LdidPreg ( MTYPE_CQ, pregnum )));
05580     break;
05581       case FIT_RECORD:
05582     if (WN_operator(WN_kid0(item)) == OPR_LDA) {
05583       lower_record_items ( block, form, iostat, TRUE,
05584                WN_ty(item), WN_kid0(item),
05585                (INT64)WN_offset(WN_kid0(item)) );
05586       WN_Delete ( WN_kid0(item) );
05587     } else if (WN_operator(WN_kid0(item)) == OPR_LDID) {
05588       lower_record_items ( block, form, iostat, FALSE,
05589                WN_ty(item), WN_kid0(item), (INT64)0 );
05590       WN_Delete ( WN_kid0(item) );
05591     } else {
05592       pregst = MTYPE_To_PREG ( Pointer_type );
05593       pregnum = Create_Preg ( Pointer_type, "record_address");
05594 
05595       WN_INSERT_BlockLast ( block,
05596                 WN_StidIntoPreg ( Pointer_type, pregnum,
05597                 pregst,
05598                 WN_kid0(item) ));
05599       raddr = WN_LdidPreg ( Pointer_type, pregnum );
05600       lower_record_items ( block, form, iostat, FALSE,
05601                WN_ty(item), raddr, (INT64)0 );
05602       WN_Delete ( raddr );
05603     }
05604     break;
05605       default:
05606           if (mp_io) {
05607                   unit_ptr = Get_UnitPointer_ST();
05608             GEN_IO_CALL_2 ( block, fio_value_ops[form][type], iostat, 
05609         NULL, WN_kid0(item), Make_IoAddr_WN(unit_ptr) );
05610           }
05611           else
05612       GEN_IO_CALL_1 ( block, fio_value_ops[form][type], iostat, 
05613         NULL, WN_kid0(item) );
05614     }
05615     break;
05616 
05617       case IOL_IMPLIED_DO:
05618       case IOL_IMPLIED_DO_1TRIP:
05619     top_label = WN_CreateNewLabel();
05620     cont_label = WN_CreateNewLabel();
05621     WN_start(item) = extract_calls ( block, WN_start(item) );
05622     WN_end(item)   = extract_calls ( block, WN_end(item) );
05623     WN_step(item)  = extract_calls ( block, WN