Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
00001 /* 00002 00003 Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved. 00004 00005 This program is free software; you can redistribute it and/or modify it 00006 under the terms of version 2.1 of the GNU Lesser General Public License 00007 as published by the Free Software Foundation. 00008 00009 This program is distributed in the hope that it would be useful, but 00010 WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00012 00013 Further, this software is distributed without any warranty that it is 00014 free of the rightful claim of any third person regarding infringement 00015 or the like. Any license provided herein, whether implied or 00016 otherwise, applies only to this software file. Patent licenses, if 00017 any, provided herein do not apply to combinations of this program with 00018 other software, or any other product whatsoever. 00019 00020 You should have received a copy of the GNU Lesser General Public 00021 License along with this program; if not, write the Free Software 00022 Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 00023 USA. 00024 00025 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 00026 Mountain View, CA 94043, or: 00027 00028 http://www.sgi.com 00029 00030 For further information regarding this notice, see: 00031 00032 http://oss.sgi.com/projects/GenInfo/NoticeExplan 00033 00034 */ 00035 00036 00037 /* USMID @(#) libf/include/f90io.h 92.3 10/29/99 21:41:49 */ 00038 00039 00040 #ifndef _F90IO_H 00041 #define _F90IO_H 00042 00043 /******************************************************************************* 00044 * 00045 * This header file contains declarations of compiler-library interface 00046 * routines, constants, and information packets. 00047 * 00048 * Header files which must be included in addition to this header file: 00049 * 00050 * "fio.h" 00051 * 00052 ******************************************************************************/ 00053 00054 #include <stdlib.h> 00055 #include <string.h> 00056 #include <cray/dopevec.h> 00057 00058 /******************************************************************************* 00059 * 00060 * Constants 00061 * 00062 ******************************************************************************/ 00063 00064 /* 00065 * The following values are returned by the single call I/O interface 00066 * routines for use in condition handling, i.e., END=, ERR=, and EOR= 00067 * specifiers in I/O statements. 00068 */ 00069 00070 #define IO_OKAY 0 /* Normal completion */ 00071 #define IO_ERR 1 /* Error status */ 00072 #define IO_END 2 /* End status */ 00073 #define IO_EOR 3 /* End of record status */ 00074 00075 /******************************************************************************* 00076 * 00077 * General structures 00078 * 00079 ******************************************************************************/ 00080 00081 /* 00082 * gfptr_t represents all forms of pointers to Fortran data. 00083 */ 00084 00085 typedef union { 00086 _fcd fcd; /* Fortran character descriptor */ 00087 void *v; /* pointer to byte address */ 00088 _f_int *wa; /* pointer to word address */ 00089 struct DopeVector *dv; /* pointer to dope vector */ 00090 } gfptr_t; 00091 00092 00093 /******************************************************************************* 00094 * 00095 * Packets for OPEN, CLOSE, INQUIRE, BUFFER IN, and BUFFER OUT 00096 * 00097 ******************************************************************************/ 00098 00099 /* 00100 * In open_spec_list, inquire_spec_list, close_spec_list structures, 00101 * some common conventions exist. 00102 * 00103 * 1) all specifier fields are in the order as listed in the ANSI standard 00104 * 00105 * 2) For fields of type (_f_int *), NULL implies that the specifier is 00106 * not passed. For fields x of type _fcd, the absence of the specifier is 00107 * implied when _fcdtocp(x) == NULL, 00108 * 00109 * 3) All version numbers are 0 in initial release. The numbers are 00110 * incremented when incompatible changes are made to the structures. 00111 */ 00112 00113 /* 00114 * open_spec_list is the interface packet passed to _OPEN. 00115 */ 00116 struct open_spec_list { 00117 #if defined(_UNICOS) || defined(__mips) || defined(_LITTLE_ENDIAN) 00118 unsigned int :32; /* reserved */ 00119 #endif 00120 unsigned int :24; /* reserved */ 00121 unsigned int version :8; /* version number */ 00122 _f_int *unit; 00123 _f_int *iostat; 00124 long err; /* -1 if ERR= specified; 0 otherwise */ 00125 _fcd file; 00126 _fcd status; 00127 _fcd access; 00128 _fcd form; 00129 _f_int *recl; 00130 _fcd blank; 00131 _fcd position; 00132 _fcd action; 00133 _fcd delim; 00134 _fcd pad; 00135 }; 00136 00137 /* 00138 * inquire_spec_list is the interface packet passed to _INQUIRE. 00139 */ 00140 struct inquire_spec_list { 00141 #if defined(_UNICOS) || defined(__mips) || defined(_LITTLE_ENDIAN) 00142 unsigned int :32; /* reserved */ 00143 #endif 00144 unsigned int :24; /* reserved */ 00145 unsigned int version :8; /* version number */ 00146 _f_int *unit; 00147 _fcd file; 00148 _f_int *iostat; 00149 long err; /* -1 if ERR= specified; 0 otherwise */ 00150 _f_log *exist; 00151 _f_log *opened; 00152 _f_int *number; 00153 _f_log *named; 00154 _fcd name; 00155 _fcd access; 00156 _fcd sequential; 00157 _fcd direct; 00158 _fcd form; 00159 _fcd formatted; 00160 _fcd unformatted; 00161 _f_int *recl; 00162 _f_int *nextrec; 00163 _fcd blank; 00164 _fcd position; 00165 _fcd action; 00166 _fcd read; 00167 _fcd write; 00168 _fcd readwrite; 00169 _fcd delim; 00170 _fcd pad; 00171 }; 00172 00173 /* 00174 * close_spec_list is the interface packet passed to _OPEN. 00175 */ 00176 struct close_spec_list { 00177 #if defined(_UNICOS) || defined(__mips) || defined(_LITTLE_ENDIAN) 00178 unsigned int :32; /* reserved */ 00179 #endif 00180 unsigned int :24; /* reserved */ 00181 unsigned int version :8; /* version number */ 00182 _f_int *unit; 00183 _f_int *iostat; 00184 long err; /* -1 if ERR= specified; 0 otherwise */ 00185 _fcd status; 00186 }; 00187 00188 /* 00189 * bio_spec_list is the interface packet passed to _BUFFERIN and 00190 * _BUFFEROUT. 00191 */ 00192 struct bio_spec_list { 00193 #if defined(_UNICOS) || defined(__mips) || defined(_LITTLE_ENDIAN) 00194 unsigned int :32; /* reserved */ 00195 #endif 00196 unsigned int :24; /* reserved */ 00197 unsigned int version :8; /* version number */ 00198 _f_int *unit; /* Unit */ 00199 _f_int *recmode; /* Mode */ 00200 gfptr_t bloc; /* Beginning location */ 00201 gfptr_t eloc; /* Ending location */ 00202 f90_type_t *tiptr; /* Data type word */ 00203 }; 00204 00205 /******************************************************************************* 00206 * 00207 * Packets for _FRF, _FWF, _FRU, and _FWU 00208 * 00209 ******************************************************************************/ 00210 00211 /* 00212 * The cilist describes all specifiers passed to a READ or WRITE 00213 * statement. 00214 */ 00215 00216 #ifndef CILIST_VERSION 00217 #define CILIST_VERSION 1 /* cilist version number */ 00218 #endif 00219 00220 typedef struct ControlList { 00221 unsigned int version :8; /* contains CILIST_VERSION */ 00222 enum uflag_spec { 00223 CI_UNITNUM = 0, /* Unit number */ 00224 CI_UNITASTERK = 1, /* Asterisk */ 00225 CI_UNITCHAR = 2, /* Character variable (_fcd) */ 00226 /* internal file or ENCODE/DECODE */ 00227 CI_UNITDOPEVEC = 3 /* character array */ 00228 } uflag :8; /* type of unit identifier */ 00229 unsigned int :4; /* unused */ 00230 unsigned int iostatflg:1; /* iostat= present flag */ 00231 unsigned int eorflag :1; /* eor= present flag */ 00232 unsigned int endflag :1; /* end= present flag */ 00233 unsigned int errflag :1; /* err= present flag */ 00234 unsigned int :2; /* unused */ 00235 enum advan_spec { 00236 CI_ADVYES = 0, /* ADVANCE=YES or not specified */ 00237 CI_ADVNO = 1, /* ADVANCE=NO */ 00238 CI_ADVVAR = 2 /* ADVANCE=variable */ 00239 } advcode :3; /* ADVANCE= specifier value */ 00240 unsigned int edcode :1; /* 1 if ENCODE/DECODE flag */ 00241 unsigned int internal :1; /* 1 if internal file */ 00242 /* must be 1 if edcode is 1 */ 00243 unsigned int dflag :1; /* 1 if direct access */ 00244 enum fmtflag_spec { 00245 CI_LISTDIR = 0, /* List-directed formatting */ 00246 CI_EDITCHAR = 1, /* Format in character variable */ 00247 CI_EDITCHARAY = 2, /* Format in char array section */ 00248 CI_EDITHOL = 3, /* Format in Hollerith */ 00249 CI_EDITHOLARAY = 4, /* Format in Hollerith array */ 00250 CI_NAMELIST = 5 /* Namelist formatting */ 00251 } fmt :8; /* type of format (or list-directed) */ 00252 unsigned int stksize :8; /* size in words of stack space */ 00253 /* passed as 3rd arg to */ 00254 /* _FRF/_FWF/_FRU/_FWU */ 00255 unsigned int :8; /* unused */ 00256 unsigned int icount :8; /* size of struct control list in */ 00257 /* words */ 00258 00259 gfptr_t unit; /* pointer to unit */ 00260 00261 _f_int *iostat_spec; /* address of IOSTAT= variable */ 00262 _f_int *rec_spec; /* address of REC= variable */ 00263 struct fmt_entry *parsfmt; /* pointer to parsed fmt */ 00264 00265 gfptr_t fmtsrc; /* pointer to format text */ 00266 00267 _fcd advance_spec; /* addr of ADVANCE= variable */ 00268 _f_int *size_spec; /* addr of SIZE= variable */ 00269 } ControlListType; 00270 00271 /* 00272 * The IO item list passed to a Fortran 90 single call data transfer (IO) 00273 * interface routine can take any of these forms: 00274 * 00275 * One IO item list is passed with each call to an interface routine. 00276 * IO item lists from a sequence of one or more library calls are needed 00277 * to completely process each data transfer (READ or WRITE) statements. 00278 * 00279 * 00280 * An IO item list has the following structure (using grammar notation): 00281 * 00282 * IO-item-list is 00283 * iolist_header compound-item 00284 * 00285 * compound-item is 00286 * compound-item iolist-item 00287 * or iolist-item 00288 * 00289 * iolist-item is 00290 * ioentry_header ioscalar_entry 00291 * or ioentry_header ioarray_entry 00292 * or ioentry_header implieddo-item 00293 * 00294 * implieddo-item is 00295 * ioimplieddo_entry iolist_header compound-item 00296 */ 00297 00298 #ifndef IOLIST_VERSION 00299 #define IOLIST_VERSION 1 /* current iolist version number */ 00300 #endif 00301 00302 /* 00303 * iolist_header is the first structure of an I/O item list. One I/O 00304 * item list is passed with each call to a compiler-library interface 00305 * routine. Several calls, and several I/O item lists, may be needed 00306 * to completely process a data transfer (READ or WRITE) statement. 00307 * 00308 * iolist_header is also passed immediately following the ioimplieddo_entry 00309 * in an implied do control list. 00310 */ 00311 00312 typedef struct { 00313 unsigned int version :3; /* contains IOLIST_VERSION */ 00314 unsigned int :27; /* unused */ 00315 00316 /* 00317 * Iolist table entry bits indicate whether data transfer statement 00318 * contains more than one iolist table. If iolfirst=iollast=1, then 00319 * table is entire iolist. If iolfirst=iollast=0, then table is 00320 * middle iolist table. 00321 */ 00322 00323 unsigned int iolfirst:1; /* 1 if first IO item list for current*/ 00324 /* statment IO statement */ 00325 unsigned int iollast :1; /* 1 if last IO item list for current */ 00326 /* statment IO statement */ 00327 unsigned int icount :16; /* number of iolist-items in this */ 00328 /* IO item list. If zero and it is */ 00329 /* both first and last io list, there */ 00330 /* is no io list in statement */ 00331 unsigned int ioetsize:16; /* number of words in the current */ 00332 /* IO item list, including this */ 00333 /* iolist_header */ 00334 /* On SGI systems, in 32-bit mode */ 00335 /* this is the number of 32-bit */ 00336 /* words, and in 64-bit mode this is */ 00337 /* the number of 64-bit words. */ 00338 } iolist_header; 00339 00340 /* 00341 * ioentry_header describes the type of iolist item. 00342 */ 00343 typedef struct { 00344 enum valtype_spec { 00345 IO_VALUNUSED = 0, 00346 IO_SCALAR = 1, /* scalar */ 00347 IO_DOPEVEC = 2, /* dopevector */ 00348 IO_LOOP = 3, /* implied-DO loop */ 00349 IO_STRUC_A = 4, /* struc for namelist array */ 00350 IO_STRUC_S = 5 /* struc for namelist scalar */ 00351 } valtype :8; /* type of iolist entry */ 00352 #if defined(_UNICOS) || defined(__mips) || defined(_LITTLE_ENDIAN) 00353 unsigned int :24; /* unused */ 00354 unsigned int :16; /* unused */ 00355 #else 00356 unsigned int :8; /* unused */ 00357 #endif 00358 unsigned int ioentsize:16; /* number of words of the current */ 00359 /* iolist item, including this */ 00360 /* ioentry_header */ 00361 /* On SGI systems, in 32-bit mode */ 00362 /* this is the number of 32-bit */ 00363 /* words, and in 64-bit mode this is */ 00364 /* the number of 64-bit words. */ 00365 } ioentry_header; 00366 00367 /* 00368 * ioscalar_entry describes a scalar IO list item. Pointers to scalars 00369 * are processed with the ioarray_entry type of IO list item. 00370 */ 00371 typedef struct { 00372 f90_type_t tinfo; /* type information for variable */ 00373 gfptr_t iovar_address; /* pointer to variable */ 00374 } ioscalar_entry; 00375 00376 /* 00377 * ioarray_entry describes an array section IO list item. It contains an 00378 * implied-DO multiplier address for each dimension of the array iff 00379 * indflag is set. 00380 */ 00381 typedef struct { 00382 struct DopeVector *dv; /* pointer to dope vector */ 00383 unsigned int indflag :1; /* 1 if indexed array */ 00384 unsigned int boundchk:1; /* Array bounds checking flag */ 00385 /* Not used for F90 release 1. */ 00386 /* 0=no bounds checking on array */ 00387 /* 1=bounds checking on array */ 00388 00389 unsigned int :30; /* pad to end of word */ 00390 #if defined(_UNICOS) || defined(__mips) || defined(_LITTLE_ENDIAN) 00391 unsigned int :32; 00392 #endif 00393 00394 int *dovar[MAXDIM]; /* array of pointers to indices. A */ 00395 /* NULL index pointer references the */ 00396 /* entire extent of a dimension. */ 00397 } ioarray_entry; 00398 00399 /* 00400 * ioimplieddo_entry describes an implied-DO loop IO list item. This 00401 * structure is followed by idcount iolist-items, which each consist 00402 * of an ioentry_header structure followed by an ioscalar_entry, 00403 * an ioarray_entry structure, or a nested implieddo-item. 00404 */ 00405 typedef struct { 00406 int *ioloopvar; /* address of loop variable */ 00407 int *iobegcnt; /* address of beginning count of loop */ 00408 int *ioendcnt; /* address of ending count of loop */ 00409 int *ioinccnt; /* address of increment of loop */ 00410 } ioimplieddo_entry; 00411 00412 /****************************************************************************** 00413 * 00414 * Inline function definitions. 00415 * 00416 ******************************************************************************/ 00417 00418 /* 00419 * _is_nonadv returns 00420 * 00421 * 0 ADVANCE='YES' 00422 * 1 ADVANCE='NO' 00423 * -1 invalid ADVANCE= specifier 00424 */ 00425 _PRAGMA_INLINE(_is_nonadv) 00426 static int 00427 _is_nonadv(ControlListType *cilist) 00428 { 00429 if (cilist->advcode == CI_ADVYES) { 00430 return(0); /* ADVANCE='YES' */ 00431 } 00432 else if (cilist->advcode == CI_ADVNO) { 00433 return(1); /* ADVANCE='NO' */ 00434 } 00435 else { /* (cilist->advcode == CI_ADVVAR) */ 00436 if (_string_cmp("YES", _fcdtocp(cilist->advance_spec), 00437 _fcdlen(cilist->advance_spec))) 00438 return(0); /* ADVANCE='YES' */ 00439 else if (_string_cmp("NO", _fcdtocp(cilist->advance_spec), 00440 _fcdlen(cilist->advance_spec))) 00441 return(1); /* ADVANCE='NO' */ 00442 } 00443 return(-1); 00444 } 00445 00446 /* 00447 * setup_format Initialize unit table fields and obtain the 00448 * parsed format. 00449 * 00450 * Returns 00451 * 0 on normal return 00452 * >0 error status 00453 */ 00454 _PRAGMA_INLINE(setup_format) 00455 static int 00456 setup_format( 00457 struct fiostate *css, 00458 unit *cup, 00459 ControlListType *cilist) 00460 { 00461 register long flen; 00462 register int fnum; 00463 register int stsz; 00464 char *fptr; /* Pointer to unparsed format */ 00465 fmt_type *ppfmt; /* Pointer to parsed format */ 00466 00467 /* 00468 * For formats passed as hollerith (integer) variables, 00469 * cft90 guarantees that they are terminated by a zero byte. 00470 * We use strlen() to obtain the length. 00471 * 00472 * For static formats (FORMAT statements) or formats 00473 * which are character constants or simple character 00474 * variables, the length of the format is the length of 00475 * the character string. 00476 * 00477 * For formats passed as character or Hollerith arrays, the 00478 * length of the format is the length of the entire array. 00479 * We compute this by multiplying the length of the element 00480 * passed times the dimension of the array. 00481 */ 00482 00483 switch (cilist->fmt) { 00484 00485 case CI_EDITCHAR: /* character variable */ 00486 fptr = _fcdtocp(cilist->fmtsrc.fcd); 00487 flen = _fcdlen (cilist->fmtsrc.fcd); 00488 break; 00489 00490 case CI_EDITCHARAY: /* dopevector */ 00491 case CI_EDITHOLARAY: 00492 { 00493 register int errn; 00494 int nocontig = 0; 00495 long extent = 0; 00496 long nbytes = 0; 00497 void *newar; 00498 DopeVectorType *dv = cilist->fmtsrc.dv; 00499 00500 if (dv->p_or_a && (dv->assoc == 0)) 00501 _ferr(css, FEFMTPAL); /* array or ptr not alloc/assoc */ 00502 00503 /* Check for contiguous array */ 00504 00505 errn = _cntig_chk(dv, &newar, &nocontig, &extent, &nbytes); 00506 00507 if (errn > 0) 00508 _ferr(css, errn); /* No memory available */ 00509 00510 css->u.fmt.freefmtbuf = nocontig; 00511 00512 fptr = (nocontig) ? newar : _fcdtocp(dv->base_addr.charptr); 00513 00514 /* Zero length array or character is bad format */ 00515 00516 if (extent == 0) 00517 _ferr(css, FEFMTNUL); 00518 00519 /* 00520 * flen is the element length in bytes times the number 00521 * of elements in the array 00522 */ 00523 00524 flen = nbytes; 00525 break; 00526 } 00527 00528 case CI_EDITHOL: /* Null-terminated hollerith */ 00529 fptr = (char *) cilist->fmtsrc.wa; 00530 flen = (long) strlen(fptr); 00531 break; 00532 00533 default: 00534 _ferr(css, FEINTUNK); /* Deep weeds... */ 00535 } 00536 00537 /* 00538 * For compatibility with ancient compilers, pull an optional 00539 * statement number off of the beginning of the format and save 00540 * it. If a statement number is found, update the format string 00541 * pointer and length. Someday, Obi-wan, we'll do this only for 00542 * static formats; or not at all. 00543 */ 00544 00545 fnum = 0; 00546 00547 while (isdigit(*fptr) && flen-- > 0) 00548 fnum = (fnum << 3) + (fnum << 1) + 00549 ((int) *fptr++ - (int) '0'); 00550 00551 css->u.fmt.u.fe.fmtbuf = fptr; 00552 css->u.fmt.u.fe.fmtlen = flen; 00553 css->u.fmt.u.fe.fmtnum = fnum; 00554 00555 /* 00556 * If the format is a variable format, or if it has not yet 00557 * been parsed, or if it was parsed by an incompatible version 00558 * of the format parser, then parse it. 00559 */ 00560 00561 ppfmt = cilist->parsfmt; 00562 00563 if (ppfmt == NULL || ppfmt->offset != PARSER_LEVEL) { /* not parsed */ 00564 register int errn; 00565 00566 errn = _parse(css, cup, (fmt_type **) ppfmt); 00567 00568 /* 00569 * If the parsed format was of an old version, store the 00570 * new version of the parsed format in the cilist for 00571 * subsequent executions of this I/O statement. 00572 */ 00573 00574 if (ppfmt != NULL) 00575 cilist->parsfmt = ppfmt; 00576 00577 if (errn != 0) 00578 return(errn); 00579 } 00580 else 00581 css->u.fmt.u.fe.pfmt = ppfmt; 00582 00583 /* 00584 * Ensure that the format count stack is allocated and is 00585 * large enough to accomodate the maximum nesting depth of 00586 * this format. 00587 */ 00588 00589 stsz = css->u.fmt.u.fe.pfmt->rep_count; 00590 00591 if (stsz > cup->upfcstsz) { 00592 00593 cup->upfcstsz = stsz; /* Set new depth */ 00594 00595 if (cup->upfcstk != NULL) 00596 free(cup->upfcstk); /* Free old stack */ 00597 00598 cup->upfcstk = (int *) malloc(sizeof(int) * stsz); 00599 00600 if (cup->upfcstk == NULL) 00601 return(FENOMEMY); /* No memory */ 00602 00603 } 00604 00605 css->u.fmt.u.fe.pftocs = cup->upfcstk; /* Set top of count stack */ 00606 00607 /* Skip first entry of parsed format */ 00608 00609 css->u.fmt.u.fe.pfcp = css->u.fmt.u.fe.pfmt + 1; 00610 00611 /* Set initial repeat count */ 00612 00613 *css->u.fmt.u.fe.pftocs = css->u.fmt.u.fe.pfcp->rep_count; 00614 00615 return(0); 00616 } 00617 00618 /****************************************************************************** 00619 * 00620 * Function prototypes and declarations. 00621 * 00622 ******************************************************************************/ 00623 00624 extern int _FRF(ControlListType *cilist, iolist_header *iolist, void *stck); 00625 extern int _FWF(ControlListType *cilist, iolist_header *iolist, void *stck); 00626 extern int _FRU(ControlListType *cilist, iolist_header *iolist, void *stck); 00627 extern int _FWU(ControlListType *cilist, iolist_header *iolist, void *stck); 00628 extern int _OPEN(struct open_spec_list *osl); 00629 extern int _CLOSE(struct close_spec_list *csl); 00630 extern int _INQUIRE(struct inquire_spec_list *isl); 00631 extern void _BUFFERIN(struct bio_spec_list *bisl); 00632 extern void _BUFFEROUT(struct bio_spec_list *bosl); 00633 00634 /****************************************************************************** 00635 * 00636 * External symbols 00637 * 00638 ******************************************************************************/ 00639 00640 typedef enum valtype_spec entrycode_t; /* io or namelist entry codes */ 00641 00642 #endif /* !_F90IO_H */