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 00038 #pragma ident "@(#) libf/fio/rb.c 92.2 06/21/99 10:37:55" 00039 00040 #include <errno.h> 00041 #include <liberrno.h> 00042 #include <fortran.h> 00043 #include <cray/nassert.h> 00044 #ifdef _CRAYT3D 00045 #include <cray/mppsdd.h> 00046 #endif 00047 #include "fio.h" 00048 #include "f90io.h" 00049 00050 static void 00051 _rb(FIOSPTR css, unit *cup, _f_int *recmode, gfptr_t bloc, gfptr_t eloc, 00052 type_packet *tip); 00053 00054 #ifdef _CRAYT3D 00055 #define MAXSH 4096 00056 #else 00057 #define MAXSH 1 00058 #endif 00059 00060 #ifdef _UNICOS 00061 /* 00062 * $RB$ CFT77 BUFFER IN wrapper 00063 */ 00064 00065 void 00066 $RB$( 00067 _f_int *biunit, /* Unit */ 00068 _f_int *recmode, /* Mode */ 00069 gfptr_t bloc, /* Beginning location */ 00070 gfptr_t eloc, /* Ending location */ 00071 int *type) /* Data type */ 00072 { 00073 register short type77; 00074 register unum_t unum; 00075 type_packet tip; 00076 struct f90_type ts; 00077 unit *cup; 00078 struct fiostate cfs; 00079 00080 unum = *biunit; 00081 00082 STMT_BEGIN(unum, 0, T_BUFIN, NULL, &cfs, cup); 00083 /* 00084 * If not connected, do an implicit open. Abort if the open fails. 00085 */ 00086 if (cup == NULL) 00087 cup = _imp_open77(&cfs, SEQ, UNF, unum, 0, NULL); 00088 00089 type77 = *type & 017; 00090 00091 CREATE_F90_INFO(ts, tip, type77); 00092 00093 #if NUMERIC_DATA_CONVERSION_ENABLED 00094 00095 if (cup->unumcvrt || cup->ucharset) { 00096 register int ret; 00097 00098 ret = _get_dc_param(&cfs, cup, ts, &tip); 00099 00100 if (ret != 0) 00101 _ferr(&cfs, ret); 00102 } 00103 00104 #endif 00105 00106 _PRAGMA_INLINE(_rb) 00107 _rb(&cfs, cup, recmode, bloc, eloc, &tip); 00108 00109 return; 00110 } 00111 #endif /* _UNICOS */ 00112 00113 /* 00114 * _BUFFERIN f90 BUFFER IN wrapper (also a headache remedy) 00115 */ 00116 void 00117 _BUFFERIN(struct bio_spec_list *bisl) 00118 { 00119 register unum_t unum; 00120 type_packet tip; 00121 struct f90_type ts; 00122 unit *cup; 00123 struct fiostate cfs; 00124 00125 assert ( bisl->version == 0 ); 00126 00127 unum = *bisl->unit; 00128 ts = *bisl->tiptr; 00129 00130 STMT_BEGIN(unum, 0, T_BUFIN, NULL, &cfs, cup); 00131 /* 00132 * If not connected, do an implicit open. Abort if the open fails. 00133 */ 00134 if (cup == NULL) 00135 cup = _imp_open(&cfs, SEQ, UNF, unum, 0, NULL); 00136 00137 tip.type77 = -1; 00138 tip.type90 = ts.type; 00139 tip.intlen = ts.int_len; 00140 tip.extlen = ts.int_len; 00141 tip.elsize = ts.int_len >> 3; 00142 tip.stride = 1; 00143 00144 #if NUMERIC_DATA_CONVERSION_ENABLED 00145 00146 if (cup->unumcvrt || cup->ucharset) { 00147 register int ret; 00148 00149 ret = _get_dc_param(&cfs, cup, ts, &tip); 00150 00151 if (ret != 0) 00152 _ferr(&cfs, ret); 00153 } 00154 00155 #endif 00156 00157 _PRAGMA_INLINE(_rb); 00158 _rb( &cfs, cup, bisl->recmode, bisl->bloc, bisl->eloc, &tip); 00159 00160 return; 00161 } 00162 00163 /* 00164 * _RB "Old" f90 BUFFER IN wrapper (not used by f90 2.0 and 00165 * later compilers). This routine can be deprecated one 00166 * of these millenia. 00167 */ 00168 void 00169 _RB( 00170 _f_int *biunit, /* Unit */ 00171 _f_int *recmode, /* Mode */ 00172 gfptr_t bloc, /* Beginning location */ 00173 gfptr_t eloc, /* Ending location */ 00174 f90_type_t *tiptr) /* Data type word */ 00175 { 00176 struct bio_spec_list bsl; 00177 00178 bsl.version = 0; 00179 bsl.unit = biunit; 00180 bsl.recmode = recmode; 00181 bsl.bloc = bloc; 00182 bsl.eloc = eloc; 00183 bsl.tiptr = tiptr; 00184 00185 _BUFFERIN(&bsl); 00186 00187 return; 00188 } 00189 00190 static void 00191 _rb( 00192 FIOSPTR css, /* Current Fortran I/O state */ 00193 unit *cup, /* Unit pointer */ 00194 _f_int *recmode, /* Mode */ 00195 gfptr_t bloc, /* Beginning location */ 00196 gfptr_t eloc, /* Ending location */ 00197 type_packet *tip) /* Type information packet */ 00198 { 00199 register int bytshft; 00200 register int mode; 00201 register long bytes; 00202 register long elsize; 00203 register long itemlen; 00204 register long items; 00205 register long stat; 00206 register ftype_t type90; 00207 int state; 00208 char *uda, *udax; 00209 #ifdef _CRAYT3D 00210 register short shared; 00211 register long ntot; 00212 register long numleft; 00213 long shrd[MAXSH]; 00214 #endif 00215 00216 if (cup->useq == 0) /* If direct access file */ 00217 _ferr(css, FEBIONDA, "BUFFER IN"); 00218 00219 if (cup->ufmt) /* If formatted file */ 00220 _ferr(css, FEBIONFM, "BUFFER IN"); 00221 00222 if (cup->uerr && !cup->unitchk) 00223 _ferr(css, cup->uffsw.sw_error); 00224 00225 /* 00226 * This check taken out temporarily because we'd like to be able to 00227 * follow an ENDFILE statement or a READ which encounters an endfile 00228 * record with a BUFFER IN statement. The sticky EOF principle should 00229 * permit such a BUFFER IN to simply return an EOF status. But what 00230 * really happens is the preceding ENDFILE or READ statement sets 00231 * cup->uend, triggering an error here. We really need a flag to 00232 * store the status of the previous BUFFER IN/OUT statement which is 00233 * separate from cup->uend. 00234 * 00235 * if (cup->uend && !cup->unitchk) 00236 * _ferr(css, FERDPEOF); 00237 */ 00238 00239 cup->unitchk = 0; 00240 cup->uerr = 0; 00241 elsize = tip->elsize; /* Data size in bytes */ 00242 type90 = tip->type90; 00243 00244 /* 00245 * Adjust the word count depending on the type. 00246 */ 00247 bytshft = ((sizeof(elsize) << 3) - 1) - _leadz(elsize); /* log2(elsize) */ 00248 00249 if (type90 == DVTYPE_ASCII) { /* If character item */ 00250 uda = _fcdtocp(bloc.fcd); 00251 udax = _fcdtocp(eloc.fcd); 00252 itemlen = _fcdlen (eloc.fcd); 00253 } 00254 else { 00255 #ifdef _CRAYT3D 00256 shared = 0; 00257 00258 if (_issddptr(bloc.v)) { 00259 int *tmpptr; 00260 00261 /* Shared data */ 00262 00263 if (!_issddptr(eloc.v)) { 00264 _ferr(css, FEINTUNK); 00265 } 00266 00267 shared = 1; 00268 ntot = 0; 00269 00270 if ((cup->ufs == FS_FDC) && 00271 (cup->uflagword & FFC_ASYNC)) { 00272 /* When we can do I/O from shared memory */ 00273 /* we can support this. */ 00274 _ferr(css, FESHRSUP); 00275 } 00276 /* 00277 * When compiler spr 76429 (on T3D) is closed, we can try replacing 00278 * the lines that use tmpptr with this. 00279 * items = _sdd_read_offset((void *)eloc.v) - 00280 * _sdd_read_offset((void *)bloc.v) + 1; 00281 */ 00282 uda = bloc.v; /* temporary */ 00283 udax = eloc.v; 00284 tmpptr = (int *)((int)udax & 0x7fffffffffffffff); 00285 items = *(tmpptr + 1); 00286 tmpptr = (int *)((int)uda & 0x7fffffffffffffff); 00287 items = items - *(tmpptr + 1) + 1; 00288 } 00289 else 00290 #endif /* _CRAYT3D */ 00291 { 00292 uda = bloc.v; 00293 udax = eloc.v; 00294 } 00295 00296 itemlen = elsize; 00297 } 00298 00299 #ifdef _CRAYT3D 00300 if (shared) { 00301 bytes = items << bytshft; 00302 } 00303 else 00304 #endif 00305 { 00306 bytes = (udax - uda) + itemlen; 00307 items = bytes >> bytshft; 00308 } 00309 00310 if (bytes < 0) 00311 _ferr(css, FEBIOFWA, "BUFFER IN"); 00312 00313 mode = (*recmode < 0) ? PARTIAL : FULL; 00314 cup->urecmode = mode; 00315 cup->uwrt = 0; 00316 state = CNT; 00317 00318 if ((items << bytshft) != bytes) 00319 _ferr(css, FEBIOFWD); 00320 00321 #ifdef _CRAYT3D 00322 if ( !shared && cup->uasync ) { 00323 #else 00324 if (cup->uasync) { 00325 #endif 00326 int ubc = 0; 00327 00328 WAITIO(cup, _ferr(css, cup->uffsw.sw_error)); 00329 00330 #if defined(_UNICOS) || defined(NUMERIC_DATA_CONVERSION_ENABLED) 00331 /* 00332 * Pad word-aligned numeric data on word boundaries within 00333 * the record for CRI and some foreign data formats. 00334 */ 00335 if ((cup->urecpos & cup->ualignmask) != 0 && 00336 type90 != DVTYPE_ASCII && 00337 elsize > 4 ) { 00338 int padubc; 00339 register int pbytes; 00340 int padval; 00341 00342 COMPADD(cup, pbytes, padubc, padval); 00343 00344 if (pbytes != 0) { 00345 stat = XRCALL(cup->ufp.fdc, readrtn) 00346 cup->ufp.fdc, 00347 WPTR2BP(&padval), 00348 pbytes, 00349 &cup->uffsw, 00350 PARTIAL, 00351 &padubc); 00352 if (stat != pbytes || 00353 FFSTAT(cup->uffsw) != FFCNT) { 00354 cup->uerr = 1; 00355 goto badpart; 00356 } 00357 cup->urecpos += (stat << 3) - padubc; 00358 } 00359 } 00360 #endif /* _UNICOS || NUMERIC_DATA_CONVERSION_ENABLED */ 00361 00362 CLRSTAT(cup->uffsw); /* clear status word */ 00363 FFSTAT(cup->uffsw) = 0; /* flag no status */ 00364 00365 stat = XRCALL(cup->ufp.fdc, readartn) cup->ufp.fdc, 00366 CPTR2BP(uda), 00367 bytes, 00368 &cup->uffsw, 00369 mode, 00370 &ubc); 00371 00372 cup->uasync = ASYNC_ACTIVE; /* flag last op was async */ 00373 00374 if (stat < 0) 00375 cup->uerr = 1; 00376 } 00377 else { 00378 #ifdef _CRAYT3D 00379 register long chunk; 00380 00381 if (shared) { 00382 chunk = (MAXSH / elsize) * sizeof(long); 00383 uda = (char *)shrd; 00384 numleft = items; 00385 } 00386 do { 00387 if (shared) { 00388 items = MIN(chunk, numleft); 00389 numleft = numleft - items; 00390 00391 if (numleft == 0) 00392 mode = cup->urecmode; 00393 else 00394 mode = PARTIAL; 00395 } 00396 #endif 00397 00398 tip->count = items; 00399 00400 stat = _frwd(cup, uda, tip, mode, (int *) NULL, 00401 (long *) NULL, &state); 00402 00403 #ifdef _CRAYT3D 00404 if (stat > 0) 00405 if (shared) { 00406 _cpytosdd(bloc.v, (long *)uda, stat, 00407 elsize / sizeof(long), 1, ntot); 00408 ntot = ntot + stat; 00409 } 00410 00411 } while (shared && (stat == items) && (numleft > 0)); 00412 #endif 00413 00414 cup->ulrecl = 0; 00415 00416 if ( stat == IOERR ) { 00417 cup->uerr = 1; 00418 cup->uffsw.sw_error = errno; 00419 } 00420 else if (state == EOF) 00421 cup->uend = PHYSICAL_ENDFILE; 00422 else if (state == EOD) { 00423 if (cup->uend == 0) 00424 cup->uend = LOGICAL_ENDFILE; 00425 } 00426 else { 00427 /* 00428 * Set ulrecl to returned item count -> bits 00429 */ 00430 #ifdef _CRAYT3D 00431 if (shared) 00432 cup->ulrecl = ntot << (bytshft + 3); 00433 else 00434 #endif 00435 cup->ulrecl = stat << (bytshft + 3); 00436 00437 cup->uend = BEFORE_ENDFILE; 00438 } 00439 00440 } 00441 00442 /* 00443 * If mode is FULL or status is BOD, EOR, EOF, EOD, ERR then 00444 * clear ulastyp to avoid padd on next operation. 00445 */ 00446 cup->ulastyp = type90; 00447 00448 if (cup->urecmode == FULL || state != CNT) { 00449 badpart: 00450 cup->ulastyp = DVTYPE_TYPELESS; 00451 cup->urecpos = 0; 00452 } 00453 00454 #ifdef _CRAYT3D 00455 if (shared) 00456 _remote_write_barrier(); 00457 #endif 00458 00459 STMT_END(cup, T_BUFIN, NULL, css); 00460 00461 return; 00462 }