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 of the GNU General Public License as 00007 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 General Public License along 00021 with this program; if not, write the Free Software Foundation, Inc., 59 00022 Temple Place - Suite 330, Boston MA 02111-1307, USA. 00023 00024 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 00025 Mountain View, CA 94043, or: 00026 00027 http://www.sgi.com 00028 00029 For further information regarding this notice, see: 00030 00031 http://oss.sgi.com/projects/GenInfo/NoticeExplan 00032 00033 */ 00034 00035 static const char USMID[] = "@(#)30/cray1_sim.c 30.0 03/18/98 12:06:00"; 00036 00037 00038 #include <stdio.h> 00039 #include <stdlib.h> 00040 #include <string.h> 00041 #include <fcntl.h> 00042 #include <errno.h> 00043 #include <sys/types.h> 00044 #include <unistd.h> 00045 00046 /************************* Cray Intrinsic Simulator **********************/ 00047 00048 /* Simulate Cray library intrinsics if this module is loaded */ 00049 00050 /* Primary machine types (Triton_IEEE = T90 + ar_float_format == IEEE) */ 00051 00052 #define YMP 7 00053 #define C90 8 00054 #define T3D 10 00055 #define T90 11 00056 #define T3E 12 00057 00058 #include "arith.internal.h" 00059 #include "int64.h" 00060 00061 #if !defined(__mips) 00062 00063 int ar_mach_type = 0; 00064 int ar_rounding_modes = 0; 00065 int ar_underflow_modes = 0; 00066 00067 extern char AR_libmv2[]; 00068 extern char AR_version[]; 00069 00070 #define CRAY_FLOAT_64 (UNROUNDED_TYPE(AR_Float_Cray1_64)) 00071 #define CRAY_FLOAT_128 (UNROUNDED_TYPE(AR_Float_Cray1_128)) 00072 #define CRAY_COMPLEX_64 (UNROUNDED_TYPE(AR_Complex_Cray1_64)) 00073 #define CRAY_COMPLEX_128 (UNROUNDED_TYPE(AR_Complex_Cray1_128)) 00074 00075 #define IEEE_FLOAT_64 (UNROUNDED_TYPE(AR_Float_IEEE_NR_64)) 00076 #define IEEE_FLOAT_128 (UNROUNDED_TYPE(AR_Float_IEEE_NR_128)) 00077 #define IEEE_COMPLEX_64 (UNROUNDED_TYPE(AR_Complex_IEEE_NR_64)) 00078 #define IEEE_COMPLEX_128 (UNROUNDED_TYPE(AR_Complex_IEEE_NR_128)) 00079 00080 static AR_TYPE integer_64_s = AR_Int_64_S; 00081 static AR_TYPE integer_64_u = AR_Int_64_U; 00082 static AR_TYPE integer_128_s = AR_Int_128_S; 00083 static AR_TYPE integer_128_u = AR_Int_128_U; 00084 00085 static AR_TYPE cray_float_64 = (AR_TYPE) CRAY_FLOAT_64; 00086 static AR_TYPE cray_float_128 = (AR_TYPE) CRAY_FLOAT_128; 00087 static AR_TYPE cray_complex_64 = (AR_TYPE) CRAY_COMPLEX_64; 00088 static AR_TYPE cray_complex_128 = (AR_TYPE) CRAY_COMPLEX_128; 00089 00090 static AR_TYPE ieee_float_64 = (AR_TYPE) IEEE_FLOAT_64; 00091 static AR_TYPE ieee_float_128 = (AR_TYPE) IEEE_FLOAT_128; 00092 static AR_TYPE ieee_complex_64 = (AR_TYPE) IEEE_COMPLEX_64; 00093 static AR_TYPE ieee_complex_128 = (AR_TYPE) IEEE_COMPLEX_128; 00094 00095 #if _CRAY 00096 typedef unsigned long int64; 00097 #else 00098 typedef unsigned long long int64; 00099 #endif 00100 00101 static int ar_sim_version = 0; /* Simulation interface version id */ 00102 00103 #define DATA 0 /* Implicit data segment identifier */ 00104 #define STACK 1 /* Stack segment identifier */ 00105 00106 #define STACK_SIZE 20480 /* # words to allocate for stack space */ 00107 00108 #define MAX_ARGS 8 /* Max # of arguments supported */ 00109 #define MAX_EXT_ADDRS 16 /* Max # of EXT addresses passed */ 00110 00111 static unsigned char* code=NULL; 00112 static int64* stack=NULL; 00113 00114 /* Define machine register and size variables */ 00115 00116 static int JSZP; /* # parcels in a jump instruction */ 00117 static int VSZ; /* Max # words in vector register */ 00118 00119 static int64 AMASK; /* A-register size mask */ 00120 static int64 ASB; /* A-register sign bit mask */ 00121 00122 static int64 A[8]; 00123 static int64 S[8]; 00124 00125 static int64 B[64]; 00126 static int64 T[64]; 00127 00128 static int SR0; /* Status/mode Register 0 */ 00129 00130 static int VL; /* Current vector length register */ 00131 static int64 VM; 00132 static int64 VM1; 00133 static int64* V; /* V-registers allocated later */ 00134 00135 /* Intrinsic function interface variables */ 00136 00137 static int numargs; 00138 static int numargwds; 00139 static int n_external_addresses; /* Must be > 0 to be special */ 00140 static char* external_address[MAX_EXT_ADDRS]; 00141 static long external_length[MAX_EXT_ADDRS]; 00142 00143 /* Internal intrinsic-specified modes */ 00144 00145 #define RMMASK 6 /* Masks RM[01] bits in SR0 */ 00146 00147 #define INTERRUPT_INV 8 00148 #define INTERRUPT_DIV 16 00149 #define INTERRUPT_OVF 32 00150 #define INTERRUPT_UNF 64 00151 #define INTERRUPT_INX 128 00152 #define INTERRUPT_INP 256 00153 00154 /* Debugging and disassembly variables */ 00155 00156 #ifdef DEBUG 00157 int ar_disasm = 0; /* =1 turns on disassembly output */ 00158 int ar_disasm_BT = 0; /* =1 turns on B/T load display output */ 00159 int ar_disasm_V = 0; /* =1 turns on vector results display output */ 00160 00161 #define DISASM0(fmt) if(ar_disasm) fprintf(stderr,fmt); else 00162 #define DISASM1(fmt,u) if(ar_disasm) fprintf(stderr,fmt,u); else 00163 #define DISASM2(fmt,u,v) \ 00164 if(ar_disasm) fprintf(stderr,fmt,u,v); else 00165 #define DISASM3(fmt,u,v,w) \ 00166 if(ar_disasm) fprintf(stderr,fmt,u,v,w); else 00167 #define DISASM4(fmt,u,v,w,x) \ 00168 if(ar_disasm) fprintf(stderr,fmt,u,v,w,x); else 00169 #define DISASM5(fmt,u,v,w,x,y) \ 00170 if(ar_disasm) fprintf(stderr,fmt,u,v,w,x,y); else 00171 #define DISASMB(b,c,ft) if (ar_disasm) { \ 00172 if (ar_disasm_BT) { \ 00173 for(i=0; i<(c); i++) \ 00174 DISASM2("%s0x%*.*llx\n", \ 00175 ((i==0)?ft:"\t\t\t\t\t"), \ 00176 BVAL(((b)+i)&077)); \ 00177 if(i==0) \ 00178 DISASM0("\n"); \ 00179 } else { \ 00180 DISASM0("\n"); \ 00181 } \ 00182 } else 00183 #define DISASMT(t,c,ft) if (ar_disasm) { \ 00184 if (ar_disasm_BT) { \ 00185 for(i=0; i<(c); i++) \ 00186 DISASM2("%s0x%16.16llx\n", \ 00187 ((i==0)?ft:"\t\t\t\t\t"), \ 00188 T[((t)+i)&077]); \ 00189 if(i==0) \ 00190 DISASM0("\n"); \ 00191 } else { \ 00192 DISASM0("\n"); \ 00193 } \ 00194 } else 00195 #define DISASMV(v,ft) if (ar_disasm) { \ 00196 if (ar_disasm_V) { \ 00197 for(i=0; i<VL; i++) \ 00198 DISASM2("%s0x%16.16llx\n", \ 00199 ((i==0)?ft:"\t\t\t\t\t"), \ 00200 V[v*VSZ+i]); \ 00201 if(VL==0) \ 00202 DISASM0("\n"); \ 00203 } else { \ 00204 DISASM0("\n"); \ 00205 } \ 00206 } else 00207 00208 static int a_size; 00209 #define set_a_size(s) a_size = (s) >> 2 00210 #define AVAL(i) a_size, a_size, A[i] 00211 #define BVAL(jk) a_size, a_size, B[jk] 00212 00213 #else 00214 00215 #define DISASM0(fmt) 00216 #define DISASM1(fmt,x) 00217 #define DISASM2(fmt,x,y) 00218 #define DISASM3(fmt,x,y,z) 00219 #define DISASM4(fmt,x,y,z,v) 00220 #define DISASM5(fmt,x,y,z,v,w) 00221 #define DISASMB(b,c,ft) 00222 #define DISASMT(t,c,ft) 00223 #define DISASMV(v,ft) 00224 00225 #define set_a_size(s) 00226 00227 #endif 00228 00229 /* Internal prototype function specifications */ 00230 00231 static void open_arith_file(); 00232 static int64 load_pvp_word(long vaddr); 00233 static void store_pvp_word(long vaddr, int64 word); 00234 00235 static int ar_imul64u(int64* result, int64 opnd1, int64 opnd2); 00236 00237 int 00238 ar_clear_sim_state(AR_TYPE resulttype) 00239 { 00240 00241 #ifdef DEBUG 00242 if (getenv("AR_DISASM") != NULL) { 00243 ar_disasm = 1; 00244 } 00245 if (getenv("AR_DISASM_BT") != NULL) { 00246 ar_disasm_BT = 1; 00247 } 00248 if (getenv("AR_DISASM_V") != NULL) { 00249 ar_disasm_V = 1; 00250 } 00251 #endif 00252 00253 /* Load arith data file on first intrinsic called */ 00254 00255 if(code == NULL) 00256 open_arith_file(); 00257 00258 if(AR_CLASS(resulttype) == AR_CLASS_FLOAT) { 00259 if((AR_FLOAT_FORMAT(resulttype) == AR_FLOAT_CRAY && 00260 ar_state_register.ar_float_format != AR_CRAY_FLOATING_POINT) || 00261 (AR_FLOAT_FORMAT(resulttype) == AR_FLOAT_IEEE && 00262 ar_state_register.ar_float_format != AR_IEEE_FLOATING_POINT)) 00263 ar_internal_error(2018, __FILE__, __LINE__); 00264 } 00265 00266 numargwds = numargs = 0; /* Set up next intrinsic simulation */ 00267 n_external_addresses = 1; /* Forget all external addresses */ 00268 return AR_STAT_OK; 00269 } 00270 00271 int 00272 ar_ext_address(int64* intaddr, const char* extaddr, int length) 00273 { 00274 #if MAX_EXT_ADDRS >= DATA 00275 if(n_external_addresses == DATA) 00276 external_address[n_external_addresses++] = NULL; 00277 #if MAX_EXT_ADDRS >= STACK 00278 if(n_external_addresses == STACK) 00279 external_address[n_external_addresses++] = NULL; 00280 #endif 00281 #endif 00282 *intaddr = n_external_addresses<<24; 00283 00284 if(n_external_addresses >= MAX_EXT_ADDRS) 00285 return AR_STAT_UNDEFINED; 00286 00287 external_address[n_external_addresses] = (char*)extaddr; 00288 external_length[n_external_addresses++] = length; 00289 00290 return AR_STAT_OK; 00291 } 00292 00293 int 00294 ar_pass_arg_address(const ar_data* arg, const AR_TYPE* argtype) 00295 { 00296 int iarg; 00297 int nbytes; 00298 int arg_offset; 00299 int arg_value_offset; 00300 00301 iarg = numargwds; 00302 numargs++; 00303 numargwds++; /* Increment number of arguments */ 00304 00305 if(iarg >= MAX_ARGS) /* Test for unsupported # of args */ 00306 ar_internal_error(2014, __FILE__, __LINE__); 00307 00308 /* Call-by-address must 1) copy the value of the argument into 00309 * the address space known to the simulator and 2) store the address 00310 * of this copied value into the argument list. 5*MAX_ARGS words 00311 * are assumed to exist beyond the base of the stack for this purpose. 00312 * These words emulate the argument setup in a caller's stack frame. 00313 * The first MAX_ARGS are used to store arguments 00314 * (addresses) that are not passed in registers. Then 4 words are 00315 * available to store the value of each argument. 00316 */ 00317 00318 /* 00319 * Handle special case of a NULL pointer (no value). If not NULL, 00320 * Compute address of argument value (to be copied in switch below). 00321 */ 00322 00323 if(arg == NULL) 00324 S[0] = 0; 00325 else { 00326 arg_value_offset = (STACK_SIZE+1+MAX_ARGS+iarg*4); 00327 S[0] = (STACK<<24) | arg_value_offset; 00328 } 00329 00330 /* 00331 * Store argument address in the stack extension of the argument list. 00332 */ 00333 00334 arg_offset = (STACK<<24) | (STACK_SIZE+1+iarg); 00335 store_pvp_word(arg_offset, S[0]); 00336 00337 if(arg == NULL) /* If no value, simply return */ 00338 return AR_STAT_OK; 00339 00340 /* Copy the value of the argument to stack slot reserved for it */ 00341 00342 switch (UNROUNDED_TYPE(*argtype)) { 00343 00344 case CRAY_FLOAT_64: 00345 case IEEE_FLOAT_64: 00346 nbytes = 8; 00347 break; 00348 00349 case CRAY_FLOAT_128: 00350 case CRAY_COMPLEX_64: 00351 case IEEE_FLOAT_128: 00352 case IEEE_COMPLEX_64: 00353 nbytes = 16; 00354 break; 00355 00356 case CRAY_COMPLEX_128: 00357 case IEEE_COMPLEX_128: 00358 nbytes = 32; 00359 break; 00360 00361 default: 00362 switch (*argtype) { 00363 00364 case AR_Int_46_S: 00365 case AR_Int_64_S: 00366 case AR_Logical: 00367 nbytes = 8; 00368 break; 00369 00370 default: 00371 return AR_STAT_INVALID_TYPE; 00372 } 00373 } 00374 00375 memcpy((char*)&stack[arg_value_offset], (char*)(arg), nbytes); 00376 return AR_STAT_OK; 00377 } 00378 00379 int 00380 ar_pass_ext_address(int64 *extdesc, const char *addr, int nwords) 00381 { 00382 int iarg; 00383 int arg_offset; 00384 int arg_value_offset; 00385 00386 int status; 00387 00388 iarg = numargwds; 00389 numargs++; 00390 numargwds++; /* Increment number of arguments */ 00391 00392 if(iarg >= MAX_ARGS) /* Test for unsupported # of args */ 00393 ar_internal_error(2014, __FILE__, __LINE__); 00394 00395 /* Passing an external address must 1) obtain an external address 00396 * descriptor for the address (from ar_ext_address) and 2) store this 00397 * descriptor into the argument list. 00398 */ 00399 00400 /* 00401 * Handle special case of a NULL pointer (no value). If not NULL, 00402 * Compute address of argument value (to be copied in switch below). 00403 */ 00404 00405 if(addr == NULL) 00406 S[0] = 0; 00407 else { 00408 status = ar_ext_address(&S[0], addr, nwords); 00409 if(IS_ERROR_STATUS(status)) 00410 return status; 00411 } 00412 00413 if(extdesc != NULL) 00414 *extdesc = S[0]; 00415 00416 /* 00417 * Store argument address in the stack extension of the argument list. 00418 */ 00419 00420 arg_offset = (STACK<<24) | (STACK_SIZE+1+iarg); 00421 store_pvp_word(arg_offset, S[0]); 00422 00423 return AR_STAT_OK; 00424 } 00425 00426 int 00427 ar_pass_fcd_address(const char* str, long lenstr) 00428 { 00429 int iarg; 00430 int arg_offset; 00431 int arg_value_offset; 00432 00433 int status; 00434 00435 long nbits; 00436 00437 iarg = numargwds; 00438 numargs++; 00439 numargwds++; /* Increment number of arguments */ 00440 00441 if(iarg >= MAX_ARGS) /* Test for unsupported # of args */ 00442 ar_internal_error(2014, __FILE__, __LINE__); 00443 00444 if(str == NULL) 00445 return AR_STAT_UNDEFINED; 00446 00447 /* Store external address descriptor in fcd */ 00448 nbits = lenstr<<3; 00449 status = ar_ext_address(&S[0], str, (lenstr+7)>>3); 00450 if(IS_ERROR_STATUS(status)) 00451 return status; 00452 00453 /* 00454 * Store fcd in the stack extension of the argument list. 00455 */ 00456 00457 arg_offset = (STACK<<24) | (STACK_SIZE+1+iarg); 00458 if(ar_mach_type == T90) { 00459 /* Store C pointer and bit length in fcd */ 00460 store_pvp_word(arg_offset, S[0]); 00461 S[0] = nbits; 00462 numargwds++; 00463 store_pvp_word(arg_offset+1, S[0]); 00464 } 00465 else { 00466 /* Store bit offset and item length in fcd */ 00467 S[0] |= (int64)nbits<<32; 00468 store_pvp_word(arg_offset, S[0]); 00469 } 00470 00471 return AR_STAT_OK; 00472 } 00473 00474 int 00475 ar_pass_arg_value(const ar_data* arg, const AR_TYPE* argtype) 00476 { 00477 int iarg; 00478 int nbytes; 00479 int arg_offset; 00480 int status; 00481 00482 iarg = numargwds; 00483 numargs++; 00484 numargwds++; /* Increment number of arguments */ 00485 00486 if(iarg >= MAX_ARGS) /* Test for unsupported # of args */ 00487 ar_internal_error(2014, __FILE__, __LINE__); 00488 00489 /* Call-by-value must copy the value of the argument into an 00490 * argument register. 00491 */ 00492 00493 if(arg == NULL) /* Test for NULL pointer (no value) */ 00494 return AR_STAT_UNDEFINED; 00495 00496 switch (UNROUNDED_TYPE(*argtype)) { 00497 00498 case CRAY_FLOAT_64: 00499 case IEEE_FLOAT_64: 00500 nbytes = 8; 00501 break; 00502 00503 case CRAY_FLOAT_128: 00504 case CRAY_COMPLEX_64: 00505 case IEEE_FLOAT_128: 00506 case IEEE_COMPLEX_64: 00507 numargwds++; 00508 nbytes = 16; 00509 break; 00510 00511 case CRAY_COMPLEX_128: 00512 case IEEE_COMPLEX_128: 00513 numargwds += 3; 00514 nbytes = 32; 00515 break; 00516 00517 default: 00518 switch (*argtype) { 00519 00520 case AR_Int_46_S: 00521 case AR_Int_64_S: 00522 case AR_Logical: 00523 nbytes = 8; 00524 break; 00525 00526 default: 00527 return AR_STAT_INVALID_TYPE; 00528 } 00529 } 00530 00531 memcpy(&S[1+iarg], (char*)arg, nbytes); 00532 return AR_STAT_OK; 00533 } 00534 00535 00536 int 00537 ar_put_real_address(AR_INT_64* extdesc) 00538 { 00539 int segment = extdesc->part3>>8; 00540 00541 if(segment >= n_external_addresses) 00542 return AR_STAT_UNDEFINED; 00543 00544 extdesc->part3 = ((long)external_address[segment]) >> 16; 00545 extdesc->part4 = ((long)external_address[segment]) & 0xffff; 00546 00547 return AR_STAT_OK; 00548 } 00549 00550 00551 int 00552 ar_get_function_value(ar_data *result, AR_TYPE *resulttype) 00553 { 00554 int status; 00555 00556 /* 00557 * Return function value in result if register conventions known 00558 * for the result type. Otherwise, the function value is assumed 00559 * to be returned through memory and the caller must retrieve it. 00560 * Use AR_convert to set ZERO and NEGATIVE status flags. Note 00561 * that error flags such as AR_STAT_OVERFLOW are cleared (these 00562 * would have been returned by the intrinsic function simulation 00563 * performed by ar_sim if run-time evaluation would have produced 00564 * them). So effectively, this routine only returns the bit 00565 * pattern of the result plus zero or negative status. 00566 */ 00567 00568 switch (AR_CLASS(*resulttype)) { 00569 00570 case AR_CLASS_INT: 00571 00572 status = ar_convert_to_integral(result, resulttype, 00573 (ar_data*)&S[1], resulttype); 00574 break; 00575 00576 case AR_CLASS_FLOAT: 00577 00578 switch(UNROUNDED_TYPE(*resulttype)) { 00579 00580 case CRAY_FLOAT_64: 00581 status = ar_convert_to_float(result, resulttype, 00582 (ar_data*)&S[1], &cray_float_64); 00583 break; 00584 00585 case CRAY_FLOAT_128: 00586 status = ar_convert_to_float(result, resulttype, 00587 (ar_data*)&S[1], &cray_float_128); 00588 break; 00589 00590 case CRAY_COMPLEX_64: 00591 status = ar_convert_to_complex(result, resulttype, 00592 (ar_data*)&S[1], &cray_complex_64); 00593 break; 00594 00595 case CRAY_COMPLEX_128: 00596 status = ar_convert_to_complex(result, resulttype, 00597 (ar_data*)&S[1], &cray_complex_128); 00598 break; 00599 00600 case IEEE_FLOAT_64: 00601 status = ar_convert_to_float(result, resulttype, 00602 (ar_data*)&S[1], &ieee_float_64); 00603 break; 00604 00605 case IEEE_FLOAT_128: 00606 status = ar_convert_to_float(result, resulttype, 00607 (ar_data*)&S[1], &ieee_float_128); 00608 break; 00609 00610 case IEEE_COMPLEX_64: 00611 status = ar_convert_to_complex(result, resulttype, 00612 (ar_data*)&S[1], &ieee_complex_64); 00613 break; 00614 00615 case IEEE_COMPLEX_128: 00616 status = ar_convert_to_complex(result, resulttype, 00617 (ar_data*)&S[1], &ieee_complex_128); 00618 break; 00619 00620 default: 00621 return AR_STAT_INVALID_TYPE; 00622 } 00623 break; 00624 00625 default: 00626 return AR_STAT_INVALID_TYPE; 00627 } 00628 return status &~ AR_ERROR_STATUS; 00629 } 00630 00631 static int 00632 call_host_external(char* func) 00633 { 00634 char* ptr1, ptr2; 00635 00636 int status; 00637 00638 long length; 00639 00640 if(strncmp(func, "malloc", 6) == 0) { 00641 length = S[1]; 00642 ptr1 = malloc(length); 00643 status = ar_ext_address(&S[1], (const char*)ptr1, (length+7)>>3); 00644 return status; 00645 } 00646 00647 return AR_STAT_UNDEFINED; 00648 } 00649 00650 #define NOINTRIN 1 /* Unknown/unsupported intrinsic name */ 00651 #define ARITHERR 2 /* Arithmetic error detected by intrinsic */ 00652 #define EXTERROR 3 /* Unsupported external called by intrinsic */ 00653 #define SETERRNO 4 /* Set errno = ERANGE */ 00654 #define IFACEERR 5 /* Unsupported simulation interface */ 00655 #define HOSTEXT 6 /* Call host system external */ 00656 #define UNIMPL_INST 7 /* Unimplemented instruction encountered */ 00657 #define UNIMPL_PRFX 8 /* Unimplemented prefixed instruction encountered */ 00658 00659 00660 #if _CRAY 00661 #define getp1(pc) ( (*(((long*)code)+((pc)>>2))>>(48-(((pc)&3)<<4)) & 0xffff) ) 00662 #else 00663 #define getp1(pc) ( (((int) code[(pc)*2])<<8) | code[(pc)*2+1] ) 00664 #endif 00665 00666 #define prefix_check(p) if (p) { status = UNIMPL_PRFX; break; } else 00667 00668 static int 00669 ar_check_status(int status, AR_IEEE_64* rr) 00670 { 00671 if(!IS_ERROR_STATUS(status)) 00672 return AR_STAT_OK; 00673 00674 if((status & AR_STAT_OVERFLOW) && (SR0 & (INTERRUPT_OVF|INTERRUPT_DIV))) 00675 return status; 00676 00677 if((status & AR_STAT_UNDEFINED) && (SR0 & INTERRUPT_INV)) 00678 if(rr->expo > AR_IEEE64_MAX_EXPO && 00679 (rr->coeff0 | rr->coeff1 | rr->coeff2 | rr->coeff3)) 00680 return status; 00681 00682 return AR_STAT_OK; 00683 } 00684 00685 int 00686 ar_sim(char* intrinsic) 00687 { 00688 char* name; 00689 char* str; 00690 00691 int i,j,n; 00692 int status; 00693 00694 int p1; 00695 int op; 00696 int I,J,K; 00697 int JK; 00698 int prefix; 00699 00700 unsigned long pc, inst_pc; 00701 AR_HOST_UINT64 wa; 00702 AR_HOST_UINT64 rtc, rtcpc; 00703 00704 int64 zero; 00705 int64 one; 00706 int64 ones; 00707 int64 sb; 00708 int64 reg64; 00709 00710 int64 *rr, *oj, *ok; 00711 00712 int save_trunc_bits; 00713 00714 AR_COMPARE_TYPE cmpres; 00715 00716 /* Set up initial Cray stack and register values */ 00717 00718 /* 00719 * The following test verifies that at least one argument 00720 * has been passed via ar_pass_arg_{value|address}. This in turn 00721 * guarantees that the arith data file has been opened and read into 00722 * memory so that the simulation is ready to begin. 00723 */ 00724 00725 if(numargwds == 0) 00726 ar_internal_error(2014, __FILE__, __LINE__); 00727 00728 S[0] = (numargs<<20) | numargwds; 00729 A[6] = (STACK<<24)|STACK_SIZE; /* Argument list pointer */ 00730 store_pvp_word((long)A[6], S[0]); 00731 00732 VL = 0; 00733 B[000] = 0; /* Force return address = 0 */ 00734 B[066] = (STACK<<24) | 0; /* Define stack pointers */ 00735 B[067] = B[066]+STACK_SIZE; 00736 00737 /* 00738 * At this point all necessary registers (except pc) contain values 00739 * that correspond with being at the entry point of the called function. 00740 */ 00741 00742 /* 00743 * Pass my simulation interface identifier. The logic within the 00744 * pvp simulation file (arith data file) can then validate and/or 00745 * translate to its interface. This allows this routine and a 00746 * newer pvp simulation file to still function correctly. In 00747 * practice, this permits older (archived?) products to still work 00748 * with a newer default arith data file. 00749 */ 00750 00751 B[065] = ar_sim_version; /* Specify sim interface id */ 00752 00753 /* 00754 * Store LJ'd, zero-filled, uppercase intrinsic name into S[7] 00755 * as part of the simulation interface with the pvp simulation file 00756 * (arith data file). The simulation is assumed to begin (at pc=0) 00757 * with a lookup of this name followed by an unconditional branch to 00758 * the associated entry point when found. The simulation continues 00759 * until either an error condition occurs or the pc becomes 0 again 00760 * corresponding to the 0 forced into the return address register 00761 * B[000]) above. 00762 */ 00763 00764 name = (char*)&S[7]; 00765 for(i=0; i<8 && isalnum(intrinsic[i]); i++) 00766 name[i] = toupper(intrinsic[i]); 00767 while(i < 8) 00768 name[i++] = 0; 00769 00770 /* User-specified truncation is not used when emulating library functions */ 00771 00772 save_trunc_bits = ar_state_register.ar_truncate_bits; /* save trunc bits */ 00773 ar_state_register.ar_truncate_bits = 0; 00774 zero = 0; 00775 one = 1; 00776 ones = ~zero; 00777 sb = one<<63; 00778 00779 /* 00780 * Simulate Cray intrinsic function. Simulation normally ends with 00781 * a J B00 (to word 0) and register S1,... containing the desired 00782 * result. An ERREXIT (opcode 000) also terminates simulation. In 00783 * this case if S0 = (NOINTRIN, ARITHERR, EXTERROR, IFACEERR, SETERRNO), 00784 * actions are taken to handle the error condition. 00785 */ 00786 00787 pc = 0; 00788 rtcpc = 0; 00789 prefix = 0; 00790 status = AR_STAT_OK; 00791 SR0 = (INTERRUPT_INV|INTERRUPT_DIV|INTERRUPT_OVF) | 00792 (ar_state_register.ar_rounding_mode<<1); 00793 while(status == AR_STAT_OK) { 00794 00795 /* Decode next instruction */ 00796 DISASM2("0p%6.6o%c\t", pc>>2, 'a'+(pc&3)); 00797 p1 = getp1(pc); pc++; 00798 op = p1>>9; 00799 I = (p1>>6)&7; 00800 J = (p1>>3)&7; 00801 K = p1&7; 00802 00803 switch(op) { 00804 case 000: 00805 prefix_check(prefix); 00806 status = S[0]; 00807 DISASM1("ERR\t\t\t0x%4.4x\n", status); 00808 switch (status) { 00809 case IFACEERR: /* Unsupported simulation interface */ 00810 ar_internal_error(2014, __FILE__, __LINE__); 00811 status = AR_STAT_UNDEFINED; 00812 break; 00813 case NOINTRIN: /* Unsupported intrinsic name */ 00814 PRINTMSG(0, 2015, Internal, 0, __FILE__, __LINE__, intrinsic, ""); 00815 status = AR_STAT_UNDEFINED; 00816 break; 00817 case EXTERROR: /* Unsupported EXT called by intrinsic */ 00818 if(status == EXTERROR) 00819 ar_internal_error(2012, __FILE__, __LINE__); 00820 case ARITHERR: /* Error detected by libm routine */ 00821 status = AR_STAT_UNDEFINED; 00822 break; 00823 case SETERRNO: /* Set errno = ERANGE */ 00824 errno = ERANGE; 00825 status = AR_STAT_OVERFLOW; 00826 pc = 0; 00827 break; 00828 case HOSTEXT: 00829 status = call_host_external((char*)&S[7]); 00830 pc = B[00]; 00831 break; 00832 default: 00833 ar_internal_error(2013, __FILE__, __LINE__); 00834 status = AR_STAT_UNDEFINED; 00835 } 00836 break; 00837 00838 case 001: 00839 prefix_check(prefix); 00840 if(!(I|J|K)) 00841 DISASM0("PASS\n"); 00842 else 00843 status = UNIMPL_INST; 00844 break; 00845 00846 case 002: 00847 prefix_check(prefix); 00848 if(I == 0) { /* VL Ak */ 00849 if(K == 0) 00850 VL = 1; 00851 else if((A[K]&(VSZ-1)) == 0) 00852 VL = VSZ; 00853 else 00854 VL = A[K]&(VSZ-1); 00855 DISASM2("VL\tA%1o\t\t%d\n", K, VL); 00856 } 00857 else if(I <= 2 && K > 0 && 00858 ar_state_register.ar_float_format == AR_IEEE_FLOATING_POINT) { 00859 switch(K) { 00860 case 1: 00861 if(I == 1) 00862 SR0 |= INTERRUPT_INV; 00863 else 00864 SR0 &=~INTERRUPT_INV; 00865 break; 00866 case 2: 00867 if(I == 1) 00868 SR0 |= INTERRUPT_DIV; 00869 else 00870 SR0 &=~INTERRUPT_DIV; 00871 break; 00872 case 3: 00873 if(I == 1) 00874 SR0 |= INTERRUPT_OVF; 00875 else 00876 SR0 &=~INTERRUPT_OVF; 00877 break; 00878 case 4: 00879 if(I == 1) 00880 SR0 |= INTERRUPT_UNF; 00881 else 00882 SR0 &=~INTERRUPT_UNF; 00883 break; 00884 case 5: 00885 if(I == 1) 00886 SR0 |= INTERRUPT_INX; 00887 else 00888 SR0 &=~INTERRUPT_INX; 00889 break; 00890 case 6: 00891 if(I == 1) 00892 SR0 |= INTERRUPT_INP; 00893 else 00894 SR0 &=~INTERRUPT_INP; 00895 break; 00896 } 00897 DISASM2("%cFI\t%3.3s\n", 'F'-I, "INVDIVOVFUNFINXINP"+(K-1)*3); 00898 } 00899 else /* Ignore all others */ 00900 DISASM1("%6.6o\n", p1); 00901 break; 00902 00903 case 003: 00904 prefix_check(prefix); 00905 if(I == 0) { 00906 if(K < 4) { /* VM A/Sj */ 00907 if(J == 0) 00908 VM = 0; 00909 else { 00910 switch(K) { 00911 case 0: 00912 VM = S[J]; 00913 break; 00914 case 1: 00915 VM1 = S[J]; 00916 break; 00917 case 2: 00918 VM = A[J]; 00919 break; 00920 case 3: 00921 VM1 = A[J]; 00922 break; 00923 } 00924 } 00925 DISASM4("VM%1o\t%c%1o\t\t0x%16.16llx\n", K&1, (K&2)?'A':'S', J, 00926 ((K&1)?VM1:VM)); 00927 } 00928 else if(ar_state_register.ar_float_format == AR_IEEE_FLOATING_POINT) { 00929 SR0 = (SR0 &~ RMMASK) | ((K<<1) & RMMASK); 00930 SR0 ^= ((SR0&04)>>1); /* Flip rounding mode order */ 00931 DISASM1("R%1.1sM\n", "NUZD"+(K&3)); 00932 } 00933 } 00934 else /* Ignore SM insts */ 00935 DISASM1("%6.6o\n", p1); 00936 break; 00937 00938 case 004: 00939 prefix_check(prefix); 00940 status = UNIMPL_INST; 00941 break; 00942 00943 case 005: 00944 prefix_check(prefix); 00945 JK = p1&077; 00946 if(I <= 1) { 00947 pc = B[JK]; 00948 DISASM3("J\tB%2.2o\t\t0p%6.6o%c\n", JK, pc>>2, 'a'+(pc&3)); 00949 if(pc == 0) { /* Check for end of simulation */ 00950 ar_state_register.ar_truncate_bits = save_trunc_bits; 00951 return(status); 00952 } 00953 } 00954 else if((I == 4 && J == 0 && K == 0) || 00955 (I == 5 && (J == 0 || J == 2 || J == 4) && K >= 1 && K <= 7)) { 00956 prefix = p1; 00957 DISASM1("%05o\n", prefix); 00958 } 00959 else { 00960 status = UNIMPL_INST; 00961 } 00962 break; 00963 00964 case 006: 00965 prefix_check(prefix); 00966 if(JSZP == 3 && I) 00967 status = UNIMPL_INST; 00968 else { 00969 pc = ((p1&0377)<<16) | getp1(pc); 00970 DISASM2("J\t0p%6.6o%c\n", pc>>2, 'a'+(pc&3)); 00971 } 00972 break; 00973 00974 case 007: 00975 prefix_check(prefix); 00976 B[00] = pc+JSZP-1; 00977 pc = ((p1&0377)<<16) | getp1(pc); 00978 DISASM2("R\t0p%6.6o%c\n", pc>>2, 'a'+(pc&3)); 00979 break; 00980 00981 case 010: 00982 prefix_check(prefix); 00983 inst_pc = ((p1&0377)<<16) | getp1(pc); 00984 if((A[0]&AMASK) == 0) 00985 pc = inst_pc; 00986 else 00987 pc += JSZP-1; 00988 DISASM2("JAZ\t0p%6.6o%c\n", inst_pc>>2, 'a'+(inst_pc&3)); 00989 break; 00990 00991 case 011: 00992 prefix_check(prefix); 00993 inst_pc = ((p1&0377)<<16) | getp1(pc); 00994 if((A[0]&AMASK) != 0) 00995 pc = inst_pc; 00996 else 00997 pc += JSZP-1; 00998 DISASM2("JAN\t0p%6.6o%c\n", inst_pc>>2, 'a'+(inst_pc&3)); 00999 break; 01000 01001 case 012: 01002 prefix_check(prefix); 01003 inst_pc = ((p1&0377)<<16) | getp1(pc); 01004 if((A[0]&ASB) == 0) 01005 pc = inst_pc; 01006 else 01007 pc += JSZP-1; 01008 DISASM2("JAP\t0p%6.6o%c\n", inst_pc>>2, 'a'+(inst_pc&3)); 01009 break; 01010 01011 case 013: 01012 prefix_check(prefix); 01013 inst_pc = ((p1&0377)<<16) | getp1(pc); 01014 if((A[0]&ASB) != 0) 01015 pc = inst_pc; 01016 else 01017 pc += JSZP-1; 01018 DISASM2("JAM\t0p%6.6o%c\n", inst_pc>>2, 'a'+(inst_pc&3)); 01019 break; 01020 01021 case 014: 01022 prefix_check(prefix); 01023 inst_pc = ((p1&0377)<<16) | getp1(pc); 01024 if(S[0]) 01025 pc += JSZP-1; 01026 else 01027 pc = inst_pc; 01028 DISASM2("JSZ\t0p%6.6o%c\n", inst_pc>>2, 'a'+(inst_pc&3)); 01029 break; 01030 01031 case 015: 01032 prefix_check(prefix); 01033 inst_pc = ((p1&0377)<<16) | getp1(pc); 01034 if(S[0]) 01035 pc = inst_pc; 01036 else 01037 pc += JSZP-1; 01038 DISASM2("JSN\t0p%6.6o%c\n", inst_pc>>2, 'a'+(inst_pc&3)); 01039 break; 01040 01041 case 016: 01042 prefix_check(prefix); 01043 inst_pc = ((p1&0377)<<16) | getp1(pc); 01044 if((S[0]>>63) == 0) 01045 pc = inst_pc; 01046 else 01047 pc += JSZP-1; 01048 DISASM2("JSP\t0p%6.6o%c\n", inst_pc>>2, 'a'+(inst_pc&3)); 01049 break; 01050 01051 case 017: 01052 prefix_check(prefix); 01053 inst_pc = ((p1&0377)<<16) | getp1(pc); 01054 if((S[0]>>63) != 0) 01055 pc = inst_pc; 01056 else 01057 pc += JSZP-1; 01058 DISASM2("JSM\t0p%6.6o%c\n", inst_pc>>2, 'a'+(inst_pc&3)); 01059 break; 01060 01061 case 020: 01062 prefix_check(prefix); 01063 wa = (getp1(pc) | (getp1(pc+1)<<16)); pc += 2; 01064 if(J == 0) { 01065 A[I] = wa; 01066 DISASM3("A%1o\t0x%8.8x\t0x%*.*llx\n", I, wa, AVAL(I)); 01067 } 01068 else if(J == 2) { 01069 A[I] = (A[I]&~(int64)0xffffffff) | wa; 01070 DISASM4("A%1o\tA%1o:0x%8.8x\t0x%*.*llx\n", I, I, wa, AVAL(I)); 01071 } 01072 else if(J == 4) { 01073 A[I] = (A[I]&(int64)0xffffffff) | ((int64)wa<<32); 01074 DISASM4("A%1o\t0x%8.8x:A%1o\t0x%*.*llx\n", I, wa, I, AVAL(I)); 01075 } 01076 else 01077 status = UNIMPL_INST; 01078 break; 01079 01080 case 021: 01081 prefix_check(prefix); 01082 wa = (getp1(pc) | (getp1(pc+1)<<16)); pc += 2; 01083 A[I] = ~wa; 01084 DISASM3("A%1o\t#0x%8.8x\t0x%*.*llx\n", I, wa, AVAL(I)); 01085 break; 01086 01087 case 022: 01088 prefix_check(prefix); 01089 A[I] = p1&077; 01090 DISASM3("A%1o\t0%2.2o\t\t0x%*.*llx\n", I, (long)A[I], AVAL(I)); 01091 break; 01092 01093 case 023: 01094 prefix_check(prefix); 01095 if(K == 0) { 01096 A[I] = S[J]; 01097 DISASM3("A%1o\tS%1o\t\t0x%*.*llx\n", I, J, AVAL(I)); 01098 } 01099 else if(K == 1) { 01100 if(VL == 0) 01101 A[I] = VSZ; 01102 else 01103 A[I] = VL; 01104 DISASM2("A%1o\tVL\t\t%d\n", I, (long)A[I]); 01105 } 01106 else 01107 status = UNIMPL_INST; 01108 break; 01109 01110 case 024: 01111 prefix_check(prefix); 01112 JK = p1&077; 01113 A[I] = B[JK]; 01114 DISASM3("A%1o\tB%2.2o\t\t0x%*.*llx\n", I, JK, AVAL(I)); 01115 break; 01116 01117 case 025: 01118 prefix_check(prefix); 01119 JK = p1&077; 01120 B[JK] = A[I]; 01121 DISASM3("B%2.2o\tA%1o\t\t0x%*.*llx\n", JK, I, BVAL(JK)); 01122 break; 01123 01124 case 026: 01125 prefix_check(prefix); 01126 if(J) { 01127 if(K&2) 01128 reg64 = A[J]; 01129 else 01130 reg64 = S[J]; 01131 if(reg64) { 01132 for(i=0,n=0; i<64; i++) { 01133 if(reg64&1) 01134 n++; 01135 reg64 >>= 1; 01136 } 01137 if(K & 1) 01138 n &= 1; 01139 } 01140 else 01141 n = 0; 01142 } 01143 else 01144 n = 0; 01145 A[I] = n; 01146 if(K & 4) 01147 status = UNIMPL_INST; 01148 DISASM5("A%1o\t%c%c%1o\t\t%d\n", I, (K&1)?'Q':'P', (K&2)?'A':'S', J, (long)A[I]); 01149 break; 01150 01151 case 027: 01152 prefix_check(prefix); 01153 if(J) { 01154 if(K&1) 01155 reg64 = A[J]; 01156 else 01157 reg64 = S[J]; 01158 if(reg64) { 01159 for(n=0; n<64; n++) 01160 if(reg64>>(63-n)) break; 01161 } 01162 else 01163 n = 64; 01164 DISASM4("A%1o\tZ%c%1o\t\t%d\n", I, (K&1)?'A':'S', J, (long)A[I]); 01165 } 01166 else 01167 n = 64; 01168 A[I] = n; 01169 if(K & 6) 01170 status = UNIMPL_INST; 01171 break; 01172 01173 case 030: 01174 prefix_check(prefix); 01175 if(J==0 && K==0) 01176 A[I] = 1; 01177 else if(J == 0) 01178 A[I] = A[K]; 01179 else if(K == 0) 01180 A[I] = (A[J]+1)&AMASK; 01181 else 01182 A[I] = (A[J]+A[K])&AMASK; 01183 DISASM4("A%1o\tA%1o+A%1o\t\t0x%*.*llx\n", I, J, K, AVAL(I)); 01184 break; 01185 01186 case 031: 01187 prefix_check(prefix); 01188 if(J==0 && K==0) 01189 A[I] = AMASK; 01190 else if(J == 0) 01191 A[I] = (-A[K])&AMASK; 01192 else if(K == 0) 01193 A[I] = (A[J]-1)&AMASK; 01194 else 01195 A[I] = (A[J]-A[K])&AMASK; 01196 DISASM4("A%1o\tA%1o-A%1o\t\t0x%*.*llx\n", I, J, K, AVAL(I)); 01197 break; 01198 01199 case 032: 01200 prefix_check(prefix); 01201 if(J == 0) 01202 A[I] = 0; 01203 else if(K == 0) 01204 A[I] = A[J]; 01205 else 01206 A[I] = (A[J]*A[K])&AMASK; 01207 DISASM4("A%1o\tA%1o*A%1o\t\t0x%*.*llx\n", I, J, K, AVAL(I)); 01208 break; 01209 01210 case 033: 01211 prefix_check(prefix); 01212 status = UNIMPL_INST; 01213 break; 01214 01215 case 034: 01216 prefix_check(prefix); 01217 JK = p1&077; 01218 wa = A[0]; 01219 n = A[I]; 01220 for(i=0; i<n; i++) 01221 B[(JK+i)&077] = load_pvp_word(wa+i) & AMASK; 01222 DISASM2("B%2.2o,A%1o\t0,A0", JK, I); 01223 DISASMB(JK, n, "\t\t"); 01224 break; 01225 01226 case 035: 01227 prefix_check(prefix); 01228 JK = p1&077; 01229 wa = A[0]; 01230 n = A[I]; 01231 for(i=0; i<n; i++) 01232 store_pvp_word(wa+i, B[(JK+i)&077]); 01233 DISASM2("0,A0\tB%2.2o,A%1o\n", JK, I); 01234 break; 01235 01236 case 036: 01237 prefix_check(prefix); 01238 JK = p1&077; 01239 wa = A[0]; 01240 n = A[I]; 01241 for(i=0; i<n; i++) 01242 T[(JK+i)&077] = load_pvp_word(wa+i); 01243 DISASM2("T%2.2o,A%1o\t0,A0", JK, I); 01244 DISASMT(JK, n, "\t\t"); 01245 break; 01246 01247 case 037: 01248 prefix_check(prefix); 01249 JK = p1&077; 01250 wa = A[0]; 01251 n = A[I]; 01252 for(i=0; i<n; i++) 01253 store_pvp_word(wa+i, T[(JK+i)&077]); 01254 DISASM2("0,A0\tT%2.2o,A%1o\n", JK, I); 01255 break; 01256 01257 case 040: 01258 prefix_check(prefix); 01259 wa = (getp1(pc) | (getp1(pc+1)<<16)); pc += 2; 01260 if(J == 0) { 01261 S[I] = wa; 01262 DISASM3("S%1o\t0x%8.8x\t0x%16.16llx\n", I, wa, S[I]); 01263 } 01264 else if(J == 2) { 01265 S[I] = (S[I]&~(int64)0xffffffff) | wa; 01266 DISASM4("S%1o\tS%1o:0x%8.8x\t0x%16.16llx\n", I, I, wa, S[I]); 01267 } 01268 else if(J == 4) { 01269 S[I] = (S[I]&(int64)0xffffffff) | ((int64)wa<<32); 01270 DISASM4("S%1o\t0x%8.8x:S%1o\t0x%16.16llx\n", I, wa, I, S[I]); 01271 } 01272 else 01273 status = UNIMPL_INST; 01274 break; 01275 01276 case 041: 01277 prefix_check(prefix); 01278 wa = (getp1(pc) | (getp1(pc+1)<<16)); pc += 2; 01279 S[I] = (((int64)0xffffffff)<<32) | ~wa; 01280 DISASM3("S%1o\t#0x%8.8x\t0x%16.16llx\n", I, wa, S[I]); 01281 break; 01282 01283 case 042: 01284 prefix_check(prefix != 0 && prefix != 05400); 01285 JK = p1&077; 01286 if (prefix == 0) { 01287 S[I] = ones>>JK; 01288 DISASM3("S%1o\t<0%2.2o\t\t0x%16.16llx\n", I, 64-JK, S[I]); 01289 } 01290 else { 01291 A[I] = ones>>JK; 01292 DISASM3("A%1o\t<0%2.2o\t\t0x%*.*llx\n", I, 64-JK, AVAL(I)); 01293 prefix = 0; 01294 } 01295 break; 01296 01297 case 043: 01298 prefix_check(prefix != 0 && prefix != 05400); 01299 JK = p1&077; 01300 if (prefix == 0) { 01301 if(JK) 01302 S[I] = ones<<(64-JK); 01303 else 01304 S[I] = 0; 01305 DISASM3("S%1o\t>0%2.2o\t\t0x%16.16llx\n", I, JK, S[I]); 01306 } 01307 else { 01308 if(JK) 01309 A[I] = ones<<(64-JK); 01310 else 01311 A[I] = 0; 01312 DISASM3("A%1o\t>0%2.2o\t\t0x%*.*llx\n", I, JK, AVAL(I)); 01313 prefix = 0; 01314 } 01315 break; 01316 01317 case 044: 01318 prefix_check(prefix != 0 && prefix != 05400); 01319 if (prefix == 0) { 01320 if(J == 0) 01321 S[I] = 0; 01322 else if(K == 0) 01323 S[I] = S[J]&sb; 01324 else 01325 S[I] = S[J]&S[K]; 01326 DISASM4("S%1o\tS%1o&S%1o\t\t0x%16.16llx\n", I, J, K, S[I]); 01327 } 01328 else { 01329 if(J == 0) 01330 A[I] = 0; 01331 else if(K == 0) 01332 A[I] = A[J]&one; 01333 else 01334 A[I] = A[J]&A[K]; 01335 DISASM4("A%1o\tA%1o&A%1o\t\t0x%*.*llx\n", I, J, K, AVAL(I)); 01336 prefix = 0; 01337 } 01338 break; 01339 01340 case 045: 01341 prefix_check(prefix != 0 && prefix != 05400); 01342 if (prefix == 0) { 01343 if(J == 0) 01344 S[I] = 0; 01345 else if(K == 0) 01346 S[I] = S[J]&~sb; 01347 else 01348 S[I] = S[J]&~S[K]; 01349 DISASM4("S%1o\tS%1o&#S%1o\t\t0x%16.16llx\n", I, J, K, S[I]); 01350 } 01351 else { 01352 if(J == 0) 01353 A[I] = 0; 01354 else if(K == 0) 01355 A[I] = A[J]&~one; 01356 else 01357 A[I] = A[J]&~A[K]; 01358 DISASM4("A%1o\tA%1o&#A%1o\t\t0x%*.*llx\n", I, J, K, AVAL(I)); 01359 prefix = 0; 01360 } 01361 break; 01362 01363 case 046: 01364 prefix_check(prefix != 0 && prefix != 05400); 01365 if (prefix == 0) { 01366 if(J == 0) 01367 if(K == 0) 01368 S[I] = sb; 01369 else 01370 S[I] = S[K]; 01371 else if(K == 0) 01372 S[I] = S[J]^sb; 01373 else 01374 S[I] = S[J]^S[K]; 01375 DISASM4("S%1o\tS%1o\\S%1o\t\t0x%16.16llx\n", I, J, K, S[I]); 01376 } 01377 else { 01378 if(J == 0) 01379 if(K == 0) 01380 A[I] = one; 01381 else 01382 A[I] = A[K]; 01383 else if(K == 0) 01384 A[I] = A[J]^one; 01385 else 01386 A[I] = A[J]^A[K]; 01387 DISASM4("A%1o\tA%1o\\A%1o\t\t0x%*.*llx\n", I, J, K, AVAL(I)); 01388 prefix = 0; 01389 } 01390 break; 01391 01392 case 047: 01393 prefix_check(prefix != 0 && prefix != 05400); 01394 if (prefix == 0) { 01395 if(J == 0) 01396 if(K == 0) 01397 S[I] = ~sb; 01398 else 01399 S[I] = ~S[K]; 01400 else if(K == 0) 01401 S[I] = ~S[J]^sb; 01402 else 01403 S[I] = ~S[J]^S[K]; 01404 DISASM4("S%1o\t#S%1o\\S%1o\t\t0x%16.16llx\n", I, J, K, S[I]); 01405 } 01406 else { 01407 if(J == 0) 01408 if(K == 0) 01409 A[I] = ~one; 01410 else 01411 A[I] = ~A[K]; 01412 else if(K == 0) 01413 A[I] = ~A[J]^one; 01414 else 01415 A[I] = ~A[J]^A[K]; 01416 DISASM4("A%1o\t#A%1o\\A%1o\t\t0x%*.*llx\n", I, J, K, AVAL(I)); 01417 prefix = 0; 01418 } 01419 break; 01420 01421 case 050: 01422 prefix_check(prefix != 0 && prefix != 05400); 01423 if (prefix == 0) { 01424 if(J == 0) 01425 if(K == 0) 01426 S[I] = S[I]&~sb; 01427 else 01428 S[I] = S[I]&~S[K]; 01429 else if(K == 0) 01430 S[I] = (S[J]&sb) | (S[I]&~sb); 01431 else 01432 S[I] = (S[J]&S[K]) | (S[I]&~S[K]); 01433 DISASM4("S%1o\t|S%1o&S%1o\t\t0x%16.16llx\n", I, J, K, S[I]); 01434 } 01435 else { 01436 if(J == 0) 01437 if(K == 0) 01438 A[I] = A[I]&~one; 01439 else 01440 A[I] = A[I]&~A[K]; 01441 else if(K == 0) 01442 A[I] = (A[J]&one) | (A[I]&~one); 01443 else 01444 A[I] = (A[J]&A[K]) | (A[I]&~A[K]); 01445 DISASM4("A%1o\t|A%1o&A%1o\t\t0x%*.*llx\n", I, J, K, AVAL(I)); 01446 prefix = 0; 01447 } 01448 break; 01449 01450 case 051: 01451 prefix_check(prefix != 0 && prefix != 05400); 01452 if (prefix == 0) { 01453 if(J == 0) 01454 if(K == 0) 01455 S[I] = sb; 01456 else 01457 S[I] = S[K]; 01458 else if(K == 0) 01459 S[I] = S[J]|sb; 01460 else 01461 S[I] = S[J]|S[K]; 01462 DISASM4("S%1o\tS%1o|S%1o\t\t0x%16.16llx\n", I, J, K, S[I]); 01463 } 01464 else { 01465 if(J == 0) 01466 if(K == 0) 01467 A[I] = one; 01468 else 01469 A[I] = A[K]; 01470 else if(K == 0) 01471 A[I] = A[J]|one; 01472 else 01473 A[I] = A[J]|A[K]; 01474 DISASM4("A%1o\tA%1o|A%1o\t\t0x%*.*llx\n", I, J, K, AVAL(I)); 01475 prefix = 0; 01476 } 01477 break; 01478 01479 case 052: 01480 prefix_check(prefix != 0 && prefix != 05400); 01481 if (prefix == 0) { 01482 S[0] = S[I] << (p1&077); 01483 DISASM3("S0\tS%1o<0%2.2o\t\t0x%16.16llx\n", I, p1&077, S[0]); 01484 } 01485 else { 01486 A[0] = A[I] << (p1&077); 01487 DISASM3("S0\tA%1o<0%2.2o\t\t0x%*.*llx\n", I, p1&077, AVAL(0)); 01488 prefix = 0; 01489 } 01490 break; 01491 01492 case 053: 01493 prefix_check(prefix != 0 && prefix != 05400); 01494 if (prefix == 0) { 01495 if(p1&077) 01496 S[0] = S[I] >> (64-(p1&077)); 01497 else 01498 S[0] = 0; 01499 DISASM3("S0\tS%1o>0%2.2o\t\t0x%16.16llx\n", I, 64-(p1&077), S[0]); 01500 } 01501 else { 01502 if(p1&077) 01503 A[0] = A[I] >> (64-(p1&077)); 01504 else 01505 A[0] = 0; 01506 DISASM3("S0\tA%1o>0%2.2o\t\t0x%*.*llx\n", I, 64-(p1&077), AVAL(0)); 01507 prefix = 0; 01508 } 01509 break; 01510 01511 case 054: 01512 prefix_check(prefix != 0 && prefix != 05400); 01513 if (prefix == 0) { 01514 S[I] <<= (p1&077); 01515 DISASM4("S%1o\tS%1o<0%2.2o\t\t0x%16.16llx\n", I, I, p1&077, S[I]); 01516 } 01517 else { 01518 A[I] <<= (p1&077); 01519 DISASM4("A%1o\tA%1o<0%2.2o\t\t0x%*.*llx\n", I, I, p1&077, AVAL(I)); 01520 prefix = 0; 01521 } 01522 break; 01523 01524 case 055: 01525 prefix_check(prefix != 0 && prefix != 05400); 01526 if (prefix == 0) { 01527 if(p1&077) 01528 S[I] >>= (64-(p1&077)); 01529 else 01530 S[I] = 0; 01531 DISASM4("S%1o\tS%1o>0%2.2o\t\t0x%16.16llx\n", I, I, 64-(p1&077), 01532 S[I]); 01533 } 01534 else { 01535 if(p1&077) 01536 A[I] >>= (64-(p1&077)); 01537 else 01538 A[I] = 0; 01539 DISASM4("A%1o\tA%1o>0%2.2o\t\t0x%*.*llx\n", I, I, 64-(p1&077), 01540 AVAL(I)); 01541 prefix = 0; 01542 } 01543 break; 01544 01545 case 056: 01546 prefix_check(prefix != 0 && prefix != 05400); 01547 if (prefix == 0) { 01548 if(J == 0) 01549 reg64 = 0; 01550 else 01551 reg64 = S[J]; 01552 if(K == 0) 01553 n = 1; 01554 else { 01555 n = A[K]; 01556 if(n >= 64) { 01557 if(n >= 128) { 01558 S[I] = 0; 01559 n = 0; 01560 } 01561 else { 01562 S[I] = reg64; 01563 reg64 = 0; 01564 n -= 64; 01565 } 01566 } 01567 } 01568 if(n) 01569 S[I] = (S[I]<<n) | (reg64>>(64-n)); 01570 DISASM5("S%1o\tS%1o,S%1o<A%1o\t0x%16.16llx\n", I, I, J, K, S[I]); 01571 } 01572 else { 01573 if(J == 0) 01574 reg64 = 0; 01575 else 01576 reg64 = A[J]; 01577 if(K == 0) 01578 n = 1; 01579 else { 01580 n = A[K]; 01581 if(n >= 64) { 01582 if(n >= 128) { 01583 A[I] = 0; 01584 n = 0; 01585 } 01586 else { 01587 A[I] = reg64; 01588 reg64 = 0; 01589 n -= 64; 01590 } 01591 } 01592 } 01593 if(n) 01594 A[I] = (A[I]<<n) | (reg64>>(64-n)); 01595 DISASM5("A%1o\tA%1o,A%1o<A%1o\t0x%*.*llx\n", I, I, J, K, AVAL(I)); 01596 prefix = 0; 01597 } 01598 break; 01599 01600 case 057: 01601 prefix_check(prefix != 0 && prefix != 05400); 01602 if (prefix == 0) { 01603 if(J == 0) 01604 reg64 = 0; 01605 else 01606 reg64 = S[J]; 01607 if(K == 0) 01608 n = 1; 01609 else { 01610 n = A[K]; 01611 if(n >= 64) { 01612 if(n >= 128) { 01613 S[I] = 0; 01614 n = 0; 01615 } 01616 else { 01617 S[I] = reg64; 01618 reg64 = 0; 01619 n -= 64; 01620 } 01621 } 01622 } 01623 if(n) 01624 S[I] = (reg64<<(64-n)) | (S[I]>>n); 01625 DISASM5("S%1o\tS%1o,S%1o>A%1o\t0x%16.16llx\n", I, J, I, K, S[I]); 01626 } 01627 else { 01628 if(J == 0) 01629 reg64 = 0; 01630 else 01631 reg64 = A[J]; 01632 if(K == 0) 01633 n = 1; 01634 else { 01635 n = A[K]; 01636 if(n >= 64) { 01637 if(n >= 128) { 01638 A[I] = 0; 01639 n = 0; 01640 } 01641 else { 01642 A[I] = reg64; 01643 reg64 = 0; 01644 n -= 64; 01645 } 01646 } 01647 } 01648 if(n) 01649 A[I] = (reg64<<(64-n)) | (A[I]>>n); 01650 DISASM5("A%1o\tA%1o,A%1o>A%1o\t0x%*.*llx\n", I, J, I, K, AVAL(I)); 01651 prefix = 0; 01652 } 01653 break; 01654 01655 case 060: 01656 prefix_check(prefix); 01657 if(J == 0) 01658 if(K == 0) 01659 S[I] = sb; 01660 else 01661 S[I] = S[K]; 01662 else if(K == 0) 01663 S[I] = S[J] + sb; 01664 else 01665 S[I] = S[J] + S[K]; 01666 DISASM4("S%1o\tS%1o+S%1o\t\t0x%16.16llx\n", I, J, K, S[I]); 01667 break; 01668 01669 case 061: 01670 prefix_check(prefix); 01671 if(J == 0) 01672 if(K == 0) 01673 S[I] = -sb; 01674 else 01675 S[I] = -S[K]; 01676 else if(K == 0) 01677 S[I] = S[J] - sb; 01678 else 01679 S[I] = S[J] - S[K]; 01680 DISASM4("S%1o\tS%1o-S%1o\t\t0x%16.16llx\n", I, J, K, S[I]); 01681 break; 01682 01683 case 062: 01684 prefix_check(prefix); 01685 if(K == 0) 01686 ok = &sb; 01687 else 01688 ok = &S[K]; 01689 if(J == 0) 01690 oj = &zero; 01691 else 01692 oj = &S[J]; 01693 rr = &S[I]; 01694 if(ar_state_register.ar_float_format == AR_CRAY_FLOATING_POINT) 01695 status = ar_cfadd64((AR_CRAY_64*)rr, 01696 (AR_CRAY_64*)oj, (AR_CRAY_64*)ok); 01697 else { 01698 status = ar_ifadd64((AR_IEEE_64*)rr, 01699 (AR_IEEE_64*)oj, (AR_IEEE_64*)ok, 01700 SR0&RMMASK); 01701 if(IS_ERROR_STATUS(status)) 01702 status = ar_check_status(status, (AR_IEEE_64*)rr); 01703 } 01704 status &= AR_ERROR_STATUS; 01705 DISASM4("S%1o\tS%1o+FS%1o\t\t0x%16.16llx\n", I, J, K, S[I]); 01706 break; 01707 01708 case 063: 01709 prefix_check(prefix); 01710 if(K == 0) 01711 ok = &sb; 01712 else 01713 ok = &S[K]; 01714 if(J == 0) 01715 oj = &zero; 01716 else 01717 oj = &S[J]; 01718 rr = &S[I]; 01719 if(ar_state_register.ar_float_format == AR_CRAY_FLOATING_POINT) 01720 status = ar_cfsub64((AR_CRAY_64*)rr, 01721 (AR_CRAY_64*)oj, (AR_CRAY_64*)ok); 01722 else { 01723 status = ar_ifsub64((AR_IEEE_64*)rr, 01724 (AR_IEEE_64*)oj, (AR_IEEE_64*)ok, 01725 SR0&RMMASK); 01726 if(IS_ERROR_STATUS(status)) 01727 status = ar_check_status(status, (AR_IEEE_64*)rr); 01728 } 01729 status &= AR_ERROR_STATUS; 01730 DISASM4("S%1o\tS%1o-FS%1o\t\t0x%16.16llx\n", I, J, K, S[I]); 01731 break; 01732 01733 case 064: 01734 prefix_check(prefix); 01735 if(K == 0) 01736 ok = &sb; 01737 else 01738 ok = &S[K]; 01739 if(J == 0) 01740 oj = &zero; 01741 else 01742 oj = &S[J]; 01743 rr = &S[I]; 01744 if(ar_state_register.ar_float_format == AR_CRAY_FLOATING_POINT) 01745 status = ar_cfmul64((AR_CRAY_64*)rr, 01746 (AR_CRAY_64*)oj, (AR_CRAY_64*)ok, 01747 AR_UNROUNDED); 01748 else { 01749 status = ar_ifmul64((AR_IEEE_64*)rr, 01750 (AR_IEEE_64*)oj, (AR_IEEE_64*)ok, 01751 SR0&RMMASK); 01752 if(IS_ERROR_STATUS(status)) 01753 status = ar_check_status(status, (AR_IEEE_64*)rr); 01754 } 01755 status &= AR_ERROR_STATUS; 01756 DISASM4("S%1o\tS%1o*FS%1o\t\t0x%16.16llx\n", I, J, K, S[I]); 01757 break; 01758 01759 case 065: 01760 prefix_check(prefix); 01761 if(K == 0) 01762 ok = &sb; 01763 else 01764 ok = &S[K]; 01765 if(J == 0) 01766 oj = &zero; 01767 else 01768 oj = &S[J]; 01769 rr = &S[I]; 01770 if(ar_state_register.ar_float_format == AR_CRAY_FLOATING_POINT) 01771 status = UNIMPL_INST; 01772 else { 01773 /* 01774 * Yes, it really is "Si Sk/FSj". 01775 */ 01776 status = ar_ifdiv64((AR_IEEE_64*)rr, 01777 (AR_IEEE_64*)ok, (AR_IEEE_64*)oj, 01778 SR0&RMMASK); 01779 status &= AR_ERROR_STATUS; 01780 if(status) 01781 status = ar_check_status(status, (AR_IEEE_64*)rr); 01782 DISASM4("S%1o\tS%1o/FS%1o\t\t0x%16.16llx\n", I, K, J, S[I]); 01783 } 01784 break; 01785 01786 case 066: 01787 prefix_check(prefix != 0 && prefix != 05400); 01788 if(K == 0) 01789 ok = &sb; 01790 else 01791 ok = &S[K]; 01792 if(J == 0) 01793 oj = &zero; 01794 else 01795 oj = &S[J]; 01796 rr = &S[I]; 01797 if (prefix == 0) { 01798 if(ar_state_register.ar_float_format == AR_CRAY_FLOATING_POINT) { 01799 status = ar_cfmul64((AR_CRAY_64*)rr, 01800 (AR_CRAY_64*)oj, (AR_CRAY_64*)ok, 01801 AR_ROUNDED); 01802 status &= AR_ERROR_STATUS; 01803 DISASM4("S%1o\tS%1o*RS%1o\t\t0x%16.16llx\n", I, J, K, S[I]); 01804 } 01805 else { 01806 S[I] = *oj * *ok; 01807 DISASM4("S%1o\tS%1o*LS%1o\t\t0x%16.16llx\n", I, J, K, S[I]); 01808 } 01809 } 01810 else { 01811 status = ar_imul64u(rr, *oj, *ok); 01812 DISASM4("S%1o\tS%1o*US%1o\t\t0x%16.16llx\n", I, J, K, S[I]); 01813 prefix = 0; 01814 } 01815 break; 01816 01817 case 067: 01818 prefix_check(prefix); 01819 if(K == 0) 01820 ok = &sb; 01821 else 01822 ok = &S[K]; 01823 if(J == 0) 01824 oj = &zero; 01825 else 01826 oj = &S[J]; 01827 rr = &S[I]; 01828 if(ar_state_register.ar_float_format == AR_CRAY_FLOATING_POINT) { 01829 status = ar_cfmul64((AR_CRAY_64*)rr, 01830 (AR_CRAY_64*)oj, (AR_CRAY_64*)ok, 01831 AR_RECIPROCAL_ITERATION); 01832 status &= AR_ERROR_STATUS; 01833 DISASM4("S%1o\tS%1o*IS%1o\t\t0x%16.16llx\n", I, J, K, S[I]); 01834 } 01835 else 01836 status = UNIMPL_INST; 01837 break; 01838 01839 case 070: 01840 prefix_check(prefix); 01841 if(J == 0) 01842 oj = &zero; 01843 else 01844 oj = &S[J]; 01845 rr = &S[I]; 01846 switch(K) { 01847 case 0: 01848 if(ar_state_register.ar_float_format == AR_CRAY_FLOATING_POINT) { 01849 status = ar_c1frecip((AR_CRAY_64*)rr, (AR_CRAY_64*)oj); 01850 DISASM3("S%1o\t/HS%1o\t\t0x%16.16llx\n", I, J, S[I]); 01851 } 01852 else { 01853 status = ar_isqrt64((AR_IEEE_64*)rr, 01854 (AR_IEEE_64*)oj, SR0&RMMASK); 01855 if(IS_ERROR_STATUS(status)) 01856 status = ar_check_status(status, (AR_IEEE_64*)rr); 01857 DISASM3("S%1o\tSQRT,S%1o\t\t0x%16.16llx\n", I, J, S[I]); 01858 } 01859 break; 01860 case 1: 01861 reg64 = 0; 01862 for(i=0,j=0; i<VL; i++) { 01863 if((VM>>(63-i)) & 1) 01864 V[I*VSZ+j++] = reg64; 01865 if(J) 01866 reg64 += S[J]; 01867 } 01868 DISASM2("V%1o\tCI,S%1o&VM\n", I, J); 01869 DISASMV(I, "\t\t"); 01870 break; 01871 case 2: 01872 if(ar_state_register.ar_float_format == AR_IEEE_FLOATING_POINT) { 01873 status = ar_ifix64((AR_INT_64*)rr, (const AR_IEEE_64*)oj, 01874 64, AR_ROUND_ZERO); 01875 if(IS_ERROR_STATUS(status)) 01876 status = ar_check_status(status, (AR_IEEE_64*)rr); 01877 DISASM3("S%1o\tINT,S%1o\t\t0x%16.16llx\n", I, J, S[I]); 01878 break; 01879 } 01880 case 3: 01881 if(ar_state_register.ar_float_format == AR_IEEE_FLOATING_POINT) { 01882 status = ar_ifix64((AR_INT_64*)rr, (const AR_IEEE_64*)oj, 01883 64, AR_ROUND_NEAREST); 01884 if(IS_ERROR_STATUS(status)) 01885 status = ar_check_status(status, (AR_IEEE_64*)rr); 01886 DISASM3("S%1o\tRINT,S%1o\t\t0x%16.16llx\n", I, J, S[I]); 01887 break; 01888 } 01889 case 4: 01890 if(ar_state_register.ar_float_format == AR_IEEE_FLOATING_POINT) { 01891 status = ar_iflt64((AR_IEEE_64*)rr, (const AR_INT_64*)oj, 01892 0, AR_ROUND_ZERO); 01893 if(IS_ERROR_STATUS(status)) 01894 status = ar_check_status(status, (AR_IEEE_64*)rr); 01895 DISASM3("S%1o\tFLT,S%1o\t\t0x%16.16llx\n", I, J, S[I]); 01896 break; 01897 } 01898 case 5: 01899 case 6: 01900 case 7: 01901 status = UNIMPL_INST; 01902 break; 01903 } 01904 status &= AR_ERROR_STATUS; 01905 break; 01906 01907 case 071: 01908 prefix_check(prefix); 01909 switch(J) { 01910 case 0: 01911 S[I] = A[K]; 01912 DISASM3("S%1o\tA%1o\t\t0x%16.16llx\n", I, K, S[I]); 01913 break; 01914 case 1: 01915 case 2: 01916 if(ar_state_register.ar_float_format == AR_CRAY_FLOATING_POINT) { 01917 if(ar_mach_type == T90) 01918 S[I] = A[K]; 01919 else if(A[K] & ASB) 01920 S[I] = (AMASK<<32) | A[K]; 01921 else 01922 S[I] = A[K]; 01923 if(J == 1) 01924 DISASM3("S%1o\t+A%1o\t\t0x%16.16llx\n", I, K, S[I]); 01925 else { 01926 if(S[I]>>63) 01927 S[I] = (S[I]^(ones>>1))+1; 01928 S[I] &= ~((int64)0x7fff<<48); 01929 S[I] |= ((int64)040060<<48); 01930 DISASM3("S%1o\t+FA%1o\t\t0x%16.16llx\n", I, K, S[I]); 01931 } 01932 break; 01933 } 01934 case 3: 01935 if(ar_state_register.ar_float_format == AR_CRAY_FLOATING_POINT) { 01936 S[I] = (int64)0400606<<45; 01937 DISASM1("S%1o\t0.6\n", I); 01938 break; 01939 } 01940 case 4: 01941 if(ar_state_register.ar_float_format == AR_CRAY_FLOATING_POINT) { 01942 S[I] = (int64)0400004<<45; 01943 DISASM1("S%1o\t0.4\n", I); 01944 break; 01945 } 01946 case 5: 01947 if(ar_state_register.ar_float_format == AR_CRAY_FLOATING_POINT) { 01948 S[I] = (int64)0400014<<45; 01949 DISASM1("S%1o\t1.\n", I); 01950 break; 01951 } 01952 case 6: 01953 if(ar_state_register.ar_float_format == AR_CRAY_FLOATING_POINT) { 01954 S[I] = (int64)0400024<<45; 01955 DISASM1("S%1o\t2.\n", I); 01956 break; 01957 } 01958 case 7: 01959 if(ar_state_register.ar_float_format == AR_CRAY_FLOATING_POINT) { 01960 S[I] = (int64)0400034<<45; 01961 DISASM1("S%1o\t4.\n", I); 01962 break; 01963 } 01964 default: 01965 status = UNIMPL_INST; 01966 } 01967 break; 01968 01969 case 072: 01970 prefix_check(prefix); 01971 if(J == 0 && K == 0) { 01972 if(rtcpc < pc) 01973 rtc += (pc-rtcpc); 01974 else 01975 rtc += (rtcpc-pc); 01976 rtcpc = pc; 01977 S[I] = rtc; 01978 DISASM1("S%1o\tRT\n", I); 01979 } 01980 else 01981 status = UNIMPL_INST; 01982 break; 01983 01984 case 073: /* Si VM */ 01985 prefix_check(prefix != 0 && prefix != 05400); 01986 if (prefix == 0) { 01987 if(K == 0 && J <= 3) { 01988 switch(J) { 01989 case 0: 01990 S[I] = VM; 01991 break; 01992 case 1: 01993 S[I] = VM1; 01994 break; 01995 case 2: 01996 A[I] = VM; 01997 break; 01998 case 3: 01999 A[I] = VM1; 02000 break; 02001 } 02002 DISASM4("%c%1o\tVM%1o\t\t0x%16.16llx\n", (K&2)?'A':'S', I, K&1, 02003 (J<2)?S[I]:A[I]); 02004 } 02005 else if (J == 0 && K == 1) { 02006 S[I] = SR0 ^ ((SR0&04)>>1); /* Flip rounding mode order */ 02007 DISASM3("S%1o\tSR%1o\t\t0x%16.16llx\n", I, J, S[I]); 02008 } 02009 else if (J == 0 && K == 5) { 02010 SR0 = S[I] ; 02011 SR0 ^= ((SR0&04)>>1); /* Flip rounding mode order */ 02012 DISASM3("SR%1o\tS%1o\t\t0x%8.8x\n", J, I, SR0); 02013 } 02014 else 02015 status = UNIMPL_INST; 02016 } 02017 else if(J == 0 && K == 5) { 02018 SR0 = (SR0 &~ RMMASK) | S[I]&RMMASK; 02019 SR0 ^= ((SR0&04)>>1); /* Flip rounding mode order */ 02020 prefix = 0; 02021 DISASM1("SETRM\tS%1o\n", I); 02022 } 02023 else { 02024 status = UNIMPL_INST; 02025 prefix = 0; 02026 } 02027 break; 02028 02029 case 074: 02030 prefix_check(prefix); 02031 JK = p1&077; 02032 S[I] = T[JK]; 02033 DISASM3("S%1o\tT%2.2o\t\t0x%16.16llx\n", I, JK, S[I]); 02034 break; 02035 02036 case 075: 02037 prefix_check(prefix); 02038 JK = p1&077; 02039 T[JK] = S[I]; 02040 DISASM3("T%2.2o\tS%1o\t\t0x%16.16llx\n", JK, I, T[JK]); 02041 break; 02042 02043 case 076: 02044 prefix_check(prefix); 02045 if(K == 0) 02046 i=1; 02047 else 02048 i=A[K]; 02049 S[I] = V[J*VSZ+i]; 02050 DISASM4("S%1o\tV%1o,A%1o\t\t0x%16.16llx\n", I, J, K, S[I]); 02051 break; 02052 02053 case 077: 02054 prefix_check(prefix); 02055 if(K == 0) 02056 i=1; 02057 else 02058 i=A[K]; 02059 if(J == 0) 02060 V[I*VSZ+i] = 0; 02061 else 02062 V[I*VSZ+i] = S[J]; 02063 DISASM4("V%1o,A%1o\tS%1o\t\t0x%16.16llx\n", I, K, J, V[I*VSZ+i]); 02064 break; 02065 02066 case 0100: 02067 case 0101: 02068 case 0102: 02069 case 0103: 02070 case 0104: 02071 case 0105: 02072 case 0106: 02073 case 0107: 02074 prefix_check(prefix); 02075 wa = (getp1(pc) | (getp1(pc+1)<<16)); pc += 2; 02076 if(J & 4) { 02077 /* Triton and TS-IEEE only */ 02078 wa |= (((AR_HOST_UINT64) getp1(pc)) << 32); 02079 pc++; 02080 } 02081 if(op&07) 02082 A[I] = load_pvp_word(wa+(long)A[op&07]) & AMASK; 02083 else 02084 A[I] = load_pvp_word(wa) & AMASK; 02085 DISASM4("A%1o\t0x%6.6x,A%1o\t0x%*.*llx\n", I, wa, op&7, AVAL(I)); 02086 break; 02087 02088 case 0110: 02089 case 0111: 02090 case 0112: 02091 case 0113: 02092 case 0114: 02093 case 0115: 02094 case 0116: 02095 case 0117: 02096 prefix_check(prefix); 02097 wa = (getp1(pc) | (getp1(pc+1)<<16)); pc += 2; 02098 if(J & 4) { 02099 /* Triton and TS-IEEE only */ 02100 wa |= (((AR_HOST_UINT64) getp1(pc)) << 32); 02101 pc++; 02102 } 02103 if(op&07) 02104 store_pvp_word(wa+(long)A[op&07], A[I]); 02105 else 02106 store_pvp_word(wa, A[I]); 02107 DISASM3("0x%6.6x,A%1o A%1o\n", wa, op&7, I); 02108 break; 02109 02110 case 0120: 02111 case 0121: 02112 case 0122: 02113 case 0123: 02114 case 0124: 02115 case 0125: 02116 case 0126: 02117 case 0127: 02118 prefix_check(prefix); 02119 wa = (getp1(pc) | (getp1(pc+1)<<16)); pc += 2; 02120 if(J & 4) { 02121 /* Triton and TS-IEEE only */ 02122 wa |= (((AR_HOST_UINT64) getp1(pc)) << 32); 02123 pc++; 02124 } 02125 if(op&07) 02126 S[I] = load_pvp_word(wa+(long)A[op&07]); 02127 else 02128 S[I] = load_pvp_word(wa); 02129 DISASM4("S%1o\t0x%6.6x,A%1o\t0x%16.16llx\n", I, wa, op&7, S[I]); 02130 break; 02131 02132 case 0130: 02133 case 0131: 02134 case 0132: 02135 case 0133: 02136 case 0134: 02137 case 0135: 02138 case 0136: 02139 case 0137: 02140 prefix_check(prefix); 02141 wa = (getp1(pc) | (getp1(pc+1)<<16)); pc += 2; 02142 if(J & 4) { 02143 /* Triton and TS-IEEE only */ 02144 wa |= (((AR_HOST_UINT64) getp1(pc)) << 32); 02145 pc++; 02146 } 02147 if(op&07) 02148 store_pvp_word(wa+(long)A[op&07], S[I]); 02149 else 02150 store_pvp_word(wa, S[I]); 02151 DISASM3("0x%6.6x,A%1o S%1o\n", wa, op&7, I); 02152 break; 02153 02154 case 0140: /* Vi Sj&Vk */ 02155 prefix_check(prefix); 02156 if(J == 0) 02157 oj = &zero; 02158 else 02159 oj = &S[J]; 02160 for(i=0; i<VL; i++) 02161 V[I*VSZ+i] = *oj & V[K*VSZ+i]; 02162 DISASM3("V%1o\tS%1o&V%1o", I, J, K); 02163 DISASMV(I, "\t\t"); 02164 break; 02165 02166 case 0141: /* Vi Vj&Vk */ 02167 prefix_check(prefix); 02168 for(i=0; i<VL; i++) 02169 V[I*VSZ+i] = V[J*VSZ+i] & V[K*VSZ+i]; 02170 DISASM3("V%1o\tV%1o&V%1o", I, J, K); 02171 DISASMV(I, "\t\t"); 02172 break; 02173 02174 case 0142: /* Vi Sj!Vk */ 02175 prefix_check(prefix); 02176 if(J == 0) 02177 oj = &zero; 02178 else 02179 oj = &S[J]; 02180 for(i=0; i<VL; i++) 02181 V[I*VSZ+i] = *oj | V[K*VSZ+i]; 02182 DISASM3("V%1o\tS%1o|V%1o", I, J, K); 02183 DISASMV(I, "\t\t"); 02184 break; 02185 02186 case 0143: /* Vi Vj!Vk */ 02187 prefix_check(prefix); 02188 for(i=0; i<VL; i++) 02189 V[I*VSZ+i] = V[J*VSZ+i] | V[K*VSZ+i]; 02190 DISASM3("V%1o\tV%1o|V%1o", I, J, K); 02191 DISASMV(I, "\t\t"); 02192 break; 02193 02194 case 0144: /* Vi Sj\Vk */ 02195 prefix_check(prefix); 02196 if(J == 0) 02197 oj = &zero; 02198 else 02199 oj = &S[J]; 02200 for(i=0; i<VL; i++) 02201 V[I*VSZ+i] = *oj ^ V[K*VSZ+i]; 02202 DISASM3("V%1o\tS%1o\\V%1o", I, J, K); 02203 DISASMV(I, "\t\t"); 02204 break; 02205 02206 case 0145: /* Vi Vj\Vk */ 02207 prefix_check(prefix); 02208 for(i=0; i<VL; i++) 02209 V[I*VSZ+i] = V[J*VSZ+i] ^ V[K*VSZ+i]; 02210 DISASM3("V%1o\tV%1o^V%1o", I, J, K); 02211 DISASMV(I, "\t\t"); 02212 break; 02213 02214 case 0146: /* Vi Sj!Vk&VM */ 02215 prefix_check(prefix); 02216 if(J == 0) 02217 oj = &zero; 02218 else 02219 oj = &S[J]; 02220 for(i=0; i<VL; i++) { 02221 if(i < 64) 02222 n = (VM>>(63-i)) & 1; 02223 else 02224 n = (VM1>>(127-i)) & 1; 02225 if(n) 02226 V[I*VSZ+i] = *oj; 02227 else 02228 V[I*VSZ+i] = V[K*VSZ+i]; 02229 } 02230 DISASM3("V%1o\tS%1o!V%1o&VM", I, J, K); 02231 DISASMV(I, "\t"); 02232 break; 02233 02234 case 0147: /* Vi Vj!Vk&VM */ 02235 prefix_check(prefix); 02236 for(i=0; i<VL; i++) { 02237 if(i < 64) 02238 n = (VM>>(63-i)) & 1; 02239 else 02240 n = (VM1>>(127-i)) & 1; 02241 if(n) 02242 V[I*VSZ+i] = V[J*VSZ+i]; 02243 else 02244 V[I*VSZ+i] = V[K*VSZ+i]; 02245 } 02246 DISASM3("V%1o\tV%1o!V%1o&VM", I, J, K); 02247 DISASMV(I, "\t"); 02248 break; 02249 02250 case 0150: /* Vi Vj<Ak */ 02251 prefix_check(prefix != 0 && prefix != 05400); 02252 if (prefix == 0) { 02253 if(K == 0) { 02254 for(i=0; i<VL; i++) 02255 V[I*VSZ+i] = V[J*VSZ+i]<<1; 02256 } 02257 else if(A[K] &~ (int64)077) { 02258 for(i=0; i<VL; i++) 02259 V[I*VSZ+i] = 0; 02260 } 02261 else { 02262 n = A[K]; 02263 for(i=0; i<VL; i++) 02264 V[I*VSZ+i] = V[J*VSZ+i]<<n; 02265 } 02266 DISASM3("V%1o\tV%1o<A%1o", I, J, K); 02267 DISASMV(I, "\t\t"); 02268 } 02269 else { 02270 if(K == 0) { 02271 for(i=0; i<VL; i++) { 02272 if(V[0*VSZ+i] &~ (int64)077) 02273 V[I*VSZ+i] = 0; 02274 else 02275 V[I*VSZ+i] = V[J*VSZ+i]<<V[0*VSZ+i]; 02276 } 02277 DISASM2("V%1o\tV%1o<V0", I, J); 02278 DISASMV(I, "\t\t"); 02279 } 02280 else { 02281 if(A[K] &~ (int64)077) { 02282 for(i=0; i<VL; i++) 02283 V[I*VSZ+i] = 0; 02284 } 02285 else { 02286 n = A[K]; 02287 for(i=0; i<VL; i++) 02288 V[I*VSZ+i] = V[J*VSZ+i]<<n; 02289 } 02290 DISASM3("V%1o\tV%1o<A%1o", I, J, K); 02291 DISASMV(I, "\t\t"); 02292 } 02293 prefix = 0; 02294 } 02295 break; 02296 02297 case 0151: /* Vi Vj>Ak */ 02298 prefix_check(prefix != 0 && prefix != 05400); 02299 if (prefix == 0) { 02300 if(K == 0) { 02301 for(i=0; i<VL; i++) 02302 V[I*VSZ+i] = V[J*VSZ+i]>>1; 02303 } 02304 else if(A[K] &~ (int64)077) { 02305 for(i=0; i<VL; i++) 02306 V[I*VSZ+i] = 0; 02307 } 02308 else { 02309 n = A[K]; 02310 for(i=0; i<VL; i++) 02311 V[I*VSZ+i] = V[J*VSZ+i]>>n; 02312 } 02313 DISASM3("V%1o\tV%1o>A%1o", I, J, K); 02314 DISASMV(I, "\t\t"); 02315 } 02316 else { 02317 if(K == 0) { 02318 for(i=0; i<VL; i++) { 02319 if(V[0*VSZ+i] &~ (int64)077) 02320 V[I*VSZ+i] = 0; 02321 else 02322 V[I*VSZ+i] = V[J*VSZ+i]>>V[0*VSZ+i]; 02323 } 02324 DISASM2("V%1o\tV%1o>V0", I, J); 02325 DISASMV(I, "\t\t"); 02326 } 02327 else { 02328 n = A[K]; 02329 if(n &~ (int64)077) { 02330 for(i=0; i<VL; i++) 02331 V[I*VSZ+i] = 0; 02332 } 02333 else { 02334 for(i=0; i<VL; i++) 02335 V[I*VSZ+i] = V[J*VSZ+i]>>n; 02336 } 02337 DISASM3("V%1o\tV%1o>A%1o", I, J, K); 02338 DISASMV(I, "\t\t"); 02339 } 02340 prefix = 0; 02341 } 02342 break; 02343 02344 case 0152: /* Vi Vj,Vj<Ak */ 02345 prefix_check(prefix != 0 && prefix != 05400); 02346 if (prefix == 0) { 02347 if(K == 0) { 02348 for(i=0; i<VL-1; i++) 02349 V[I*VSZ+i] = (V[J*VSZ+i]<<1) | (V[J*VSZ+i+1]>>63); 02350 V[I*VSZ+VL-1] = V[J*VSZ+VL-1]<<1; 02351 } 02352 else if(A[K] &~ (int64)0177) { 02353 for(i=0; i<VL; i++) 02354 V[I*VSZ+i] = 0; 02355 } 02356 else if(A[K] & (int64)0100) { 02357 n = A[K]&077; 02358 for(i=0; i<VL-1; i++) 02359 V[I*VSZ+i] = V[J*VSZ+i+1]<<n; 02360 V[I*VSZ+VL-1] = 0; 02361 } 02362 else { 02363 n = A[K]; 02364 for(i=0; i<VL-1; i++) 02365 V[I*VSZ+i] = (V[J*VSZ+i]<<n) | (V[J*VSZ+i+1]>>(64-n)); 02366 V[I*VSZ+VL-1] = V[J*VSZ+VL-1]<<n; 02367 } 02368 DISASM4("V%1o\tV%1o,V%1o<A%1o", I, J, J, K); 02369 DISASMV(I, "\t"); 02370 } 02371 else { 02372 n = A[K]&077; 02373 for(i=n; i<VL; i++) 02374 V[I*VSZ+i-n] = V[J*VSZ+i]; 02375 DISASM3("V%1o\tV%1o,A%1o", I, J, K); 02376 DISASMV(I, "\t\t"); 02377 prefix = 0; 02378 } 02379 break; 02380 02381 case 0153: /* Vi Vj,Vj>Ak */ 02382 prefix_check(prefix != 0 && prefix != 05400); 02383 if (prefix == 0) { 02384 if(K == 0) { 02385 for(i=VL-1; i>0; i--) 02386 V[I*VSZ+i] = (V[J*VSZ+i]>>1) | (V[J*VSZ+i-1]<<63); 02387 V[I*VSZ+0] = V[J*VSZ+0]>>1; 02388 } 02389 else if(A[K] &~ (int64)0177) { 02390 for(i=0; i<VL; i++) 02391 V[I*VSZ+i] = 0; 02392 } 02393 else if(A[K] & (int64)0100) { 02394 n = A[K]&077; 02395 for(i=VL-1; i>0; i--) 02396 V[I*VSZ+i] = V[J*VSZ+i-1]>>n; 02397 V[I*VSZ+0] = 0; 02398 } 02399 else { 02400 n = A[K]; 02401 for(i=VL-1; i>0; i--) 02402 V[I*VSZ+i] = (V[J*VSZ+i]>>n) | (V[J*VSZ+i-1]<<(64-n)); 02403 V[I*VSZ+0] = V[J*VSZ+0]>>n; 02404 } 02405 DISASM4("V%1o\tV%1o,V%1o>A%1o", I, J, J, K); 02406 DISASMV(I, "\t"); 02407 } 02408 else { 02409 if (K == 0) { 02410 i = 0; 02411 j = 0; 02412 n = 0; 02413 reg64 = 1; 02414 for(n=0; n<64; j++, n++, reg64 <<= 1) { 02415 if ((reg64 & VM) != 0) 02416 V[I*VSZ+(i++)] = V[J*VSZ+j]; 02417 } 02418 02419 n = 0; 02420 reg64 = 1; 02421 for(n=0; n<64; j++, n++, reg64 <<= 1) { 02422 if ((reg64 & VM1) != 0) 02423 V[I*VSZ+(i++)] = V[J*VSZ+j]; 02424 } 02425 02426 DISASM2("V%1o\tV%1o,[VM]", I, J); 02427 DISASMV(I, "\t\t"); 02428 } 02429 else if (K == 1) { 02430 i = 0; 02431 j = 0; 02432 n = 0; 02433 reg64 = 1; 02434 for(n=0; n<64; i++, n++, reg64 <<= 1) { 02435 if ((reg64 & VM) != 0) 02436 V[I*VSZ+i] = V[J*VSZ+(j++)]; 02437 } 02438 02439 n = 0; 02440 reg64 = 1; 02441 for(n=0; n<64; i++, n++, reg64 <<= 1) { 02442 if ((reg64 & VM1) != 0) 02443 V[I*VSZ+i] = V[J*VSZ+(j++)]; 02444 } 02445 02446 DISASM2("V%1o,[VM]\tV%1o", I, J); 02447 DISASMV(I, "\t\t"); 02448 } 02449 else 02450 status = UNIMPL_INST; 02451 prefix = 0; 02452 } 02453 break; 02454 02455 case 0154: /* Vi Sj+Vk */ 02456 prefix_check(prefix); 02457 if(J == 0) 02458 oj = &zero; 02459 else 02460 oj = &S[J]; 02461 for(i=0; i<VL; i++) 02462 V[I*VSZ+i] = *oj + V[K*VSZ+i]; 02463 DISASM3("V%1o\tS%1o+V%1o", I, J, K); 02464 DISASMV(I, "\t\t"); 02465 break; 02466 02467 case 0155: /* Vi Vj+Vk */ 02468 prefix_check(prefix); 02469 for(i=0; i<VL; i++) 02470 V[I*VSZ+i] = V[J*VSZ+i] + V[K*VSZ+i]; 02471 DISASM3("V%1o\tV%1o+V%1o", I, J, K); 02472 DISASMV(I, "\t\t"); 02473 break; 02474 02475 case 0156: /* Vi Sj-Vk */ 02476 prefix_check(prefix); 02477 if(J == 0) 02478 oj = &zero; 02479 else 02480 oj = &S[J]; 02481 for(i=0; i<VL; i++) 02482 V[I*VSZ+i] = *oj - V[K*VSZ+i]; 02483 DISASM3("V%1o\tS%1o-V%1o", I, J, K); 02484 DISASMV(I, "\t\t"); 02485 break; 02486 02487 case 0157: /* Vi Vj-Vk */ 02488 prefix_check(prefix); 02489 for(i=0; i<VL; i++) 02490 V[I*VSZ+i] = V[J*VSZ+i] - V[K*VSZ+i]; 02491 DISASM3("V%1o\tV%1o-V%1o", I, J, K); 02492 DISASMV(I, "\t\t"); 02493 break; 02494 02495 case 0160: /* Vi Sj*FVk */ 02496 prefix_check(prefix); 02497 if(J == 0) 02498 oj = &zero; 02499 else 02500 oj = &S[J]; 02501 rr = &V[I*VSZ]; 02502 ok = &V[K*VSZ]; 02503 for(i=0; i<VL && status==AR_STAT_OK; i++) { 02504 if(ar_state_register.ar_float_format == AR_CRAY_FLOATING_POINT) 02505 status = ar_cfmul64((AR_CRAY_64*)rr, 02506 (AR_CRAY_64*)oj, (AR_CRAY_64*)ok, 02507 AR_UNROUNDED); 02508 else { 02509 status = ar_ifmul64((AR_IEEE_64*)rr, 02510 (AR_IEEE_64*)oj, (AR_IEEE_64*)ok, 02511 SR0&RMMASK); 02512 if(IS_ERROR_STATUS(status)) 02513 status = ar_check_status(status, (AR_IEEE_64*)rr); 02514 } 02515 status &= AR_ERROR_STATUS; 02516 rr++; 02517 ok++; 02518 } 02519 DISASM3("V%1o\tS%1o*FV%1o", I, J, K); 02520 DISASMV(I, "\t\t"); 02521 break; 02522 02523 case 0161: /* Vi Vj*FVk */ 02524 prefix_check(prefix); 02525 rr = &V[I*VSZ]; 02526 oj = &V[J*VSZ]; 02527 ok = &V[K*VSZ]; 02528 for(i=0; i<VL && status==AR_STAT_OK; i++) { 02529 if(ar_state_register.ar_float_format == AR_CRAY_FLOATING_POINT) 02530 status = ar_cfmul64((AR_CRAY_64*)rr, 02531 (AR_CRAY_64*)oj, (AR_CRAY_64*)ok, 02532 AR_UNROUNDED); 02533 else { 02534 status = ar_ifmul64((AR_IEEE_64*)rr, 02535 (AR_IEEE_64*)oj, (AR_IEEE_64*)ok, 02536 SR0&RMMASK); 02537 if(IS_ERROR_STATUS(status)) 02538 status = ar_check_status(status, (AR_IEEE_64*)rr); 02539 } 02540 status &= AR_ERROR_STATUS; 02541 rr++; 02542 oj++; 02543 ok++; 02544 } 02545 DISASM3("V%1o\tV%1o*FV%1o", I, J, K); 02546 DISASMV(I, "\t\t"); 02547 break; 02548 02549 case 0162: 02550 prefix_check(prefix); 02551 if(ar_state_register.ar_float_format == AR_CRAY_FLOATING_POINT) { 02552 status = UNIMPL_INST; 02553 break; 02554 } 02555 if(J == 0) 02556 oj = &zero; 02557 else 02558 oj = &S[J]; 02559 rr = &V[I*VSZ]; 02560 ok = &V[K*VSZ]; 02561 for(i=0; i<VL && status==AR_STAT_OK; i++) { 02562 status = ar_ifdiv64((AR_IEEE_64*)rr, 02563 (AR_IEEE_64*)ok, 02564 (AR_IEEE_64*)oj, 02565 SR0&RMMASK); 02566 if(status) 02567 status = ar_check_status(status, (AR_IEEE_64*)rr); 02568 rr++; 02569 ok++; 02570 } 02571 DISASM3("V%1o\tS%1o/FV%1o", I, J, K); 02572 DISASMV(I, "\t\t"); 02573 break; 02574 02575 case 0163: 02576 prefix_check(prefix); 02577 if(ar_state_register.ar_float_format == AR_CRAY_FLOATING_POINT) { 02578 status = UNIMPL_INST; 02579 break; 02580 } 02581 rr = &V[I*VSZ]; 02582 oj = &V[J*VSZ]; 02583 ok = &V[K*VSZ]; 02584 for(i=0; i<VL && status==AR_STAT_OK; i++) { 02585 status = ar_ifdiv64((AR_IEEE_64*)rr, 02586 (AR_IEEE_64*)ok, 02587 (AR_IEEE_64*)oj, 02588 SR0&RMMASK); 02589 status &= AR_ERROR_STATUS; 02590 if(status) 02591 status = ar_check_status(status, (AR_IEEE_64*)rr); 02592 rr++; 02593 oj++; 02594 ok++; 02595 } 02596 DISASM3("V%1o\tV%1o/FV%1o", I, J, K); 02597 DISASMV(I, "\t\t"); 02598 break; 02599 02600 case 0164: /* Vi Sj*RVk */ 02601 prefix_check(prefix != 0 && 02602 !((prefix >= 05501 && prefix <= 05507) || 02603 (prefix >= 05521 && prefix <= 05527) || 02604 (prefix >= 05541 && prefix <= 05547))); 02605 if(J == 0) 02606 oj = &zero; 02607 else 02608 oj = &S[J]; 02609 if (prefix == 0) { 02610 rr = &V[I*VSZ]; 02611 ok = &V[K*VSZ]; 02612 for(i=0; i<VL && status==AR_STAT_OK; i++) { 02613 status = ar_cfmul64((AR_CRAY_64*)rr, 02614 (AR_CRAY_64*)oj, (AR_CRAY_64*)ok, 02615 AR_ROUNDED); 02616 status &= AR_ERROR_STATUS; 02617 if(status) 02618 status = ar_check_status(status, (AR_IEEE_64*)rr); 02619 rr++; 02620 ok++; 02621 } 02622 DISASM3("V%1o\tS%1o*RV%1o", I, J, K); 02623 DISASMV(I, "\t\t"); 02624 } 02625 else if (prefix >= 05501 && prefix <= 05507) { 02626 if(K == 0) 02627 ok = &sb; 02628 else 02629 ok = &S[K]; 02630 cmpres = AR_compare((AR_DATA*)oj, &ieee_float_64, 02631 (AR_DATA*)ok, &ieee_float_64); 02632 switch(prefix) { 02633 case 05501: 02634 S[I] = (cmpres == AR_Compare_EQ) ? ones : zero; 02635 break; 02636 case 05502: 02637 S[I] = (cmpres != AR_Compare_EQ) ? ones : zero; 02638 break; 02639 case 05503: 02640 S[I] = (cmpres == AR_Compare_GT) ? ones : zero; 02641 break; 02642 case 05504: 02643 S[I] = (cmpres == AR_Compare_LT || cmpres == AR_Compare_EQ) 02644 ? ones : zero; 02645 break; 02646 case 05505: 02647 S[I] = (cmpres == AR_Compare_LT) ? ones : zero; 02648 break; 02649 case 05506: 02650 S[I] = (cmpres == AR_Compare_GT || cmpres == AR_Compare_EQ) 02651 ? ones : zero; 02652 break; 02653 case 05507: 02654 S[I] = (cmpres == AR_Compare_Unord) ? ones : zero; 02655 break; 02656 } 02657 DISASM5("S%1o\tS%1o,%2.2s,S%1o\t0x%16.16llx\n", 02658 I, J, "EQNEGTLELTGEUN"+(((prefix&07)-1)*2), K, S[I]); 02659 prefix = 0; 02660 } 02661 else if (prefix >= 05521 && prefix <= 05527) { 02662 VM = VM1 = 0; 02663 for(i=0; i<VL; i++) { 02664 cmpres = AR_compare((AR_DATA*)oj, &ieee_float_64, 02665 (AR_DATA*)&V[K*VSZ+i], &ieee_float_64); 02666 switch(prefix) { 02667 case 05521: 02668 if (cmpres == AR_Compare_EQ) { 02669 if(i < 64) 02670 VM |= ((int64)1<<(63-i)); 02671 else 02672 VM1 |= ((int64)1<<(127-i)); 02673 } 02674 break; 02675 case 05522: 02676 if (cmpres != AR_Compare_EQ) { 02677 if(i < 64) 02678 VM |= ((int64)1<<(63-i)); 02679 else 02680 VM1 |= ((int64)1<<(127-i)); 02681 } 02682 break; 02683 case 05523: 02684 if (cmpres == AR_Compare_GT) { 02685 if(i < 64) 02686 VM |= ((int64)1<<(63-i)); 02687 else 02688 VM1 |= ((int64)1<<(127-i)); 02689 } 02690 break; 02691 case 05524: 02692 if (cmpres == AR_Compare_LT || cmpres == AR_Compare_EQ) { 02693 if(i < 64) 02694 VM |= ((int64)1<<(63-i)); 02695 else 02696 VM1 |= ((int64)1<<(127-i)); 02697 } 02698 break; 02699 case 05525: 02700 if (cmpres == AR_Compare_LT) { 02701 if(i < 64) 02702 VM |= ((int64)1<<(63-i)); 02703 else 02704 VM1 |= ((int64)1<<(127-i)); 02705 } 02706 break; 02707 case 05526: 02708 if (cmpres == AR_Compare_GT || cmpres == AR_Compare_EQ) { 02709 if(i < 64) 02710 VM |= ((int64)1<<(63-i)); 02711 else 02712 VM1 |= ((int64)1<<(127-i)); 02713 } 02714 break; 02715 case 05527: 02716 if (cmpres == AR_Compare_Unord) { 02717 if(i < 64) 02718 VM |= ((int64)1<<(63-i)); 02719 else 02720 VM1 |= ((int64)1<<(127-i)); 02721 } 02722 break; 02723 } 02724 } 02725 DISASM5("VM\tS%1o,%2.2s,V%1o\t0x%16.16llx,0x%16.16llx\n", 02726 J, "EQNEGTLELTGEUN"+(((prefix&07)-1)*2), K, VM, VM1); 02727 prefix = 0; 02728 } 02729 else if (prefix >= 05541 && prefix <= 05547) { 02730 VM = VM1 = 0; 02731 for(i=0; i<VL; i++) { 02732 cmpres = AR_compare((AR_DATA*)&V[J*VSZ+i], &ieee_float_64, 02733 (AR_DATA*)&V[K*VSZ+i], &ieee_float_64); 02734 switch(prefix) { 02735 case 05541: 02736 if (cmpres == AR_Compare_EQ) { 02737 if(i < 64) 02738 VM |= ((int64)1<<(63-i)); 02739 else 02740 VM1 |= ((int64)1<<(127-i)); 02741 } 02742 break; 02743 case 05542: 02744 if (cmpres != AR_Compare_EQ) { 02745 if(i < 64) 02746 VM |= ((int64)1<<(63-i)); 02747 else 02748 VM1 |= ((int64)1<<(127-i)); 02749 } 02750 break; 02751 case 05543: 02752 if (cmpres == AR_Compare_GT) { 02753 if(i < 64) 02754 VM |= ((int64)1<<(63-i)); 02755 else 02756 VM1 |= ((int64)1<<(127-i)); 02757 } 02758 break; 02759 case 05544: 02760 if (cmpres == AR_Compare_LT || cmpres == AR_Compare_EQ) { 02761 if(i < 64) 02762 VM |= ((int64)1<<(63-i)); 02763 else 02764 VM1 |= ((int64)1<<(127-i)); 02765 } 02766 break; 02767 case 05545: 02768 if (cmpres == AR_Compare_LT) { 02769 if(i < 64) 02770 VM |= ((int64)1<<(63-i)); 02771 else 02772 VM1 |= ((int64)1<<(127-i)); 02773 } 02774 break; 02775 case 05546: 02776 if (cmpres == AR_Compare_GT || cmpres == AR_Compare_EQ) { 02777 if(i < 64) 02778 VM |= ((int64)1<<(63-i)); 02779 else 02780 VM1 |= ((int64)1<<(127-i)); 02781 } 02782 break; 02783 case 05547: 02784 if (cmpres == AR_Compare_Unord) { 02785 if(i < 64) 02786 VM |= ((int64)1<<(63-i)); 02787 else 02788 VM1 |= ((int64)1<<(127-i)); 02789 } 02790 break; 02791 } 02792 } 02793 DISASM5("VM\tV%1o,%2.2s,V%1o\t0x%16.16llx,0x%16.16llx\n", 02794 J, "EQNEGTLELTGEUN"+(((prefix&07)-1)*2), K, VM, VM1); 02795 prefix = 0; 02796 } 02797 break; 02798 02799 case 0165: /* Vi Vj*[RLU]Vk */ 02800 prefix_check(prefix != 0 && prefix != 05400); 02801 if(ar_state_register.ar_float_format == AR_IEEE_FLOATING_POINT) { 02802 if (prefix == 0) { 02803 for(i=0; i<VL; i++) 02804 V[I*VSZ+i] = V[J*VSZ+i] * V[K*VSZ+i]; 02805 DISASM3("V%1o\tV%1o*LV%1o", I, J, K); 02806 } 02807 else { 02808 rr = &V[I*VSZ]; 02809 oj = &V[J*VSZ]; 02810 ok = &V[K*VSZ]; 02811 for(i=0; status==AR_STAT_OK && i<VL; i++) { 02812 status = ar_imul64u(rr, *oj, *ok); 02813 rr++; 02814 oj++; 02815 ok++; 02816 } 02817 DISASM3("V%1o\tV%1o*UV%1o\n", I, J, K); 02818 prefix = 0; 02819 } 02820 } 02821 else { /* Vi Vj*RVk */ 02822 rr = &V[I*VSZ]; 02823 oj = &V[J*VSZ]; 02824 ok = &V[K*VSZ]; 02825 for(i=0; i<VL && status==AR_STAT_OK; i++) { 02826 status = ar_cfmul64((AR_CRAY_64*)rr, 02827 (AR_CRAY_64*)oj, (AR_CRAY_64*)ok, 02828 AR_ROUNDED); 02829 status &= AR_ERROR_STATUS; 02830 rr++; 02831 oj++; 02832 ok++; 02833 } 02834 DISASM3("V%1o\tV%1o*RV%1o", I, J, K); 02835 } 02836 DISASMV(I, "\t\t"); 02837 break; 02838 02839 case 0166: /* Vi Sj*IVk */ 02840 prefix_check(prefix != 0 && prefix != 05400); 02841 if(J == 0) 02842 oj = &zero; 02843 else 02844 oj = &S[J]; 02845 rr = &V[I*VSZ]; 02846 ok = &V[K*VSZ]; 02847 if(ar_state_register.ar_float_format == AR_IEEE_FLOATING_POINT) { 02848 if (prefix == 0) { 02849 for(i=0; i<VL; i++) 02850 V[I*VSZ+i] = *oj * V[K*VSZ+i]; 02851 DISASM3("V%1o\tS%1o*LV%1o", I, J, K); 02852 } 02853 else { 02854 for(i=0; status==AR_STAT_OK && i<VL; i++) { 02855 status = ar_imul64u(rr, *oj, *ok); 02856 rr++; 02857 ok++; 02858 } 02859 DISASM3("V%1o\tS%1o*UV%1o\n", I, J, K); 02860 prefix = 0; 02861 } 02862 } 02863 else { 02864 for(i=0; i<VL && status==AR_STAT_OK; i++) { 02865 status = ar_cfmul64((AR_CRAY_64*)rr, 02866 (AR_CRAY_64*)oj, (AR_CRAY_64*)ok, 02867 AR_RECIPROCAL_ITERATION); 02868 status &= AR_ERROR_STATUS; 02869 rr++; 02870 ok++; 02871 } 02872 DISASM3("V%1o\tS%1o*IV%1o", I, J, K); 02873 } 02874 DISASMV(I, "\t\t"); 02875 break; 02876 02877 case 0167: /* Vi Vj*IVk */ 02878 prefix_check(prefix); 02879 rr = &V[I*VSZ]; 02880 oj = &V[J*VSZ]; 02881 if(ar_state_register.ar_float_format == AR_CRAY_FLOATING_POINT) { 02882 ok = &V[K*VSZ]; 02883 for(i=0; i<VL && status==AR_STAT_OK; i++) { 02884 status = ar_cfmul64((AR_CRAY_64*)rr, 02885 (AR_CRAY_64*)oj, (AR_CRAY_64*)ok, 02886 AR_RECIPROCAL_ITERATION); 02887 rr++; 02888 oj++; 02889 ok++; 02890 } 02891 DISASM3("V%1o\tV%1o*RV%1o", I, J, K); 02892 } 02893 else if(K <= 2) { 02894 for(i=0; i<VL && status==AR_STAT_OK; i++) { 02895 switch(K) { 02896 case 0: 02897 status = ar_ifix64((AR_INT_64*)rr, (const AR_IEEE_64*)oj, 02898 64, AR_ROUND_ZERO); 02899 break; 02900 case 1: 02901 status = ar_ifix64((AR_INT_64*)rr, (const AR_IEEE_64*)oj, 02902 64, AR_ROUND_NEAREST); 02903 break; 02904 case 2: 02905 status = ar_iflt64((AR_IEEE_64*)rr, (const AR_INT_64*)oj, 02906 0, AR_ROUND_ZERO); 02907 break; 02908 } 02909 if(IS_ERROR_STATUS(status)) 02910 status = ar_check_status(status, (AR_IEEE_64*)rr); 02911 status &= AR_ERROR_STATUS; 02912 rr++; 02913 oj++; 02914 } 02915 DISASM3("V%1o\t%s,V%1o", I, (K==0)?"INT":(K==1)?"RINT":"FLT", J); 02916 } 02917 else 02918 status = UNIMPL_INST; 02919 DISASMV(I, "\t\t"); 02920 break; 02921 02922 case 0170: /* Vi Sj+FVk */ 02923 prefix_check(prefix); 02924 if(J == 0) 02925 oj = &zero; 02926 else 02927 oj = &S[J]; 02928 rr = &V[I*VSZ]; 02929 ok = &V[K*VSZ]; 02930 for(i=0; i<VL && status==AR_STAT_OK; i++) { 02931 if(ar_state_register.ar_float_format == AR_CRAY_FLOATING_POINT) 02932 status = ar_cfadd64((AR_CRAY_64*)rr, 02933 (AR_CRAY_64*)oj, (AR_CRAY_64*)ok); 02934 else { 02935 status = ar_ifadd64((AR_IEEE_64*)rr, 02936 (AR_IEEE_64*)oj, (AR_IEEE_64*)ok, 02937 SR0&RMMASK); 02938 if(IS_ERROR_STATUS(status)) 02939 status = ar_check_status(status, (AR_IEEE_64*)rr); 02940 } 02941 status &= AR_ERROR_STATUS; 02942 rr++; 02943 ok++; 02944 } 02945 DISASM3("V%1o\tS%1o+FV%1o", I, J, K); 02946 DISASMV(I, "\t\t"); 02947 break; 02948 02949 case 0171: /* Vi Vj+FVk */ 02950 prefix_check(prefix); 02951 rr = &V[I*VSZ]; 02952 oj = &V[J*VSZ]; 02953 ok = &V[K*VSZ]; 02954 for(i=0; i<VL && status==AR_STAT_OK; i++) { 02955 if(ar_state_register.ar_float_format == AR_CRAY_FLOATING_POINT) 02956 status = ar_cfadd64((AR_CRAY_64*)rr, 02957 (AR_CRAY_64*)oj, (AR_CRAY_64*)ok); 02958 else { 02959 status = ar_ifadd64((AR_IEEE_64*)rr, 02960 (AR_IEEE_64*)oj, (AR_IEEE_64*)ok, 02961 SR0&RMMASK); 02962 if(IS_ERROR_STATUS(status)) 02963 status = ar_check_status(status, (AR_IEEE_64*)rr); 02964 } 02965 status &= AR_ERROR_STATUS; 02966 rr++; 02967 oj++; 02968 ok++; 02969 } 02970 DISASM3("V%1o\tV%1o+FV%1o", I, J, K); 02971 DISASMV(I, "\t\t"); 02972 break; 02973 02974 case 0172: /* Vi Sj-FVk */ 02975 prefix_check(prefix); 02976 if(J == 0) 02977 oj = &zero; 02978 else 02979 oj = &S[J]; 02980 rr = &V[I*VSZ]; 02981 ok = &V[K*VSZ]; 02982 for(i=0; i<VL && status==AR_STAT_OK; i++) { 02983 if(ar_state_register.ar_float_format == AR_CRAY_FLOATING_POINT) 02984 status = ar_cfsub64((AR_CRAY_64*)rr, 02985 (AR_CRAY_64*)oj, (AR_CRAY_64*)ok); 02986 else { 02987 status = ar_ifsub64((AR_IEEE_64*)rr, 02988 (AR_IEEE_64*)oj, (AR_IEEE_64*)ok, 02989 SR0&RMMASK); 02990 if(IS_ERROR_STATUS(status)) 02991 status = ar_check_status(status, (AR_IEEE_64*)rr); 02992 } 02993 status &= AR_ERROR_STATUS; 02994 rr++; 02995 ok++; 02996 } 02997 DISASM3("V%1o\tS%1o-FV%1o", I, J, K); 02998 DISASMV(I, "\t\t"); 02999 break; 03000 03001 case 0173: /* Vi Vj-FVk */ 03002 prefix_check(prefix); 03003 rr = &V[I*VSZ]; 03004 oj = &V[J*VSZ]; 03005 ok = &V[K*VSZ]; 03006 for(i=0; i<VL && status==AR_STAT_OK; i++) { 03007 if(ar_state_register.ar_float_format == AR_CRAY_FLOATING_POINT) 03008 status = ar_cfsub64((AR_CRAY_64*)rr, 03009 (AR_CRAY_64*)oj, (AR_CRAY_64*)ok); 03010 else { 03011 status = ar_ifsub64((AR_IEEE_64*)rr, 03012 (AR_IEEE_64*)oj, (AR_IEEE_64*)ok, 03013 SR0&RMMASK); 03014 if(IS_ERROR_STATUS(status)) 03015 status = ar_check_status(status, (AR_IEEE_64*)rr); 03016 } 03017 status &= AR_ERROR_STATUS; 03018 rr++; 03019 oj++; 03020 ok++; 03021 } 03022 DISASM3("V%1o\tV%1o-FV%1o", I, J, K); 03023 DISASMV(I, "\t\t"); 03024 break; 03025 03026 case 0174: 03027 prefix_check(prefix); 03028 if(K == 0) { /* Vi /HVj */ 03029 rr = &V[I*VSZ]; 03030 oj = &V[J*VSZ]; 03031 if(ar_state_register.ar_float_format == AR_CRAY_FLOATING_POINT) { 03032 for(i=0; i<VL && status==AR_STAT_OK; i++) { 03033 status = ar_c1frecip((AR_CRAY_64*)rr, (AR_CRAY_64*)oj); 03034 status &= AR_ERROR_STATUS; 03035 rr++; 03036 oj++; 03037 } 03038 DISASM2("V%1o\t/HV%1o", I, J); 03039 } 03040 else { 03041 for(i=0; i<VL && status==AR_STAT_OK; i++) { 03042 status = ar_sqrt((ar_data*)rr, &ieee_float_64, 03043 (ar_data*)oj, &ieee_float_64); 03044 if(IS_ERROR_STATUS(status)) 03045 status = ar_check_status(status, (AR_IEEE_64*)rr); 03046 status &= AR_ERROR_STATUS; 03047 rr++; 03048 oj++; 03049 } 03050 DISASM2("V%1o\tSQRT,V%1o", I, J); 03051 } 03052 DISASMV(I, "\t\t"); 03053 } 03054 else if(K <= 3) { /* Vi [PQZ]Vj */ 03055 for(i=0; i<VL; i++) { 03056 switch(K) { 03057 case 1: 03058 case 2: 03059 for(j=0,n=0; j<64; j++) 03060 if((V[J*VSZ+i]>>j)&1) 03061 n++; 03062 if(K == 2) 03063 n &= 1; 03064 break; 03065 case 3: 03066 for(n=0; n<64; n++) 03067 if(V[J*VSZ+i]>>(63-n)) break; 03068 break; 03069 } 03070 V[I*VSZ+i] = n; 03071 } 03072 DISASM3("V%1o\t%cV%1o", I, (K==1)?'P':(K==2)?'Q':'Z', J); 03073 DISASMV(I, "\t\t"); 03074 } 03075 else 03076 status = UNIMPL_INST; 03077 break; 03078 03079 case 0175: /* [Vi,]VM Vj,[ZNPM] */ 03080 prefix_check(prefix); 03081 VM = VM1 = 0; 03082 n = 0; 03083 if(K & 2) { /* [PM] */ 03084 for(i=0; i<VL; i++) { 03085 if((1-(V[J*VSZ+i]>>63)) ^ (K&1)) { 03086 if(i < 64) 03087 VM |= ((int64)1<<(63-i)); 03088 else 03089 VM1 |= ((int64)1<<(127-i)); 03090 if(K & 4) 03091 V[I*VSZ+n++] = i; 03092 } 03093 } 03094 } 03095 else { /* Else [ZN] */ 03096 for(i=0; i<VL; i++) { 03097 if(!V[J*VSZ+i] ^ (K&1)) { 03098 if(i < 64) 03099 VM |= ((int64)1<<(63-i)); 03100 else 03101 VM1 |= ((int64)1<<(127-i)); 03102 if(K & 4) 03103 V[I*VSZ+n++] = i; 03104 } 03105 } 03106 } 03107 if(K < 4) { 03108 DISASM3("VM\tV%1o,%1.1s\t\t0x%16.16llx", J, "ZNPM"+(K&03), VM); 03109 if(VL > 64) 03110 DISASM1(" %16.16llx\n", VM1); 03111 else 03112 DISASM0("\n"); 03113 } 03114 else { 03115 DISASM3("VM,V%1o\tV%1o,%1.1s", I, J, "ZNPM"+(K&03)); 03116 if(VL > 64) 03117 DISASM2("\t\t0x%16.16llx %16.16llx\n", VM, VM1); 03118 else 03119 DISASM1("\t\t0x%16.16llx\n", VM); 03120 DISASMV(I, "\t\t\t\t\t"); 03121 } 03122 break; 03123 03124 case 0176: 03125 prefix_check(prefix != 0 && prefix != 05400); 03126 if(prefix == 0 && J == 0) { 03127 if(K == 0) 03128 n = 1; 03129 else 03130 n = A[K]; 03131 for(i=0; i<VL; i++) 03132 V[I*VSZ+i] = load_pvp_word((long)A[0]+i*n); 03133 DISASM2("V%1o\t,A0,A%1o", I, K); 03134 } 03135 else if(prefix == 0) { 03136 for(i=0; i<VL; i++) 03137 V[I*VSZ+i] = load_pvp_word((long)(A[0]+V[K*VSZ+i])); 03138 DISASM2("V%1o\t,A0,V%1o", I, K); 03139 } 03140 else { 03141 for(i=0; i<VL; i++) { 03142 V[I*VSZ+i] = load_pvp_word((long)(A[0]+V[K*VSZ+i])); 03143 V[J*VSZ+i] = load_pvp_word((long)(A[K]+V[K*VSZ+i])); 03144 } 03145 DISASM4("V%1o:V%1o\t,A0:A%1o,V%1o", I, J, K, K); 03146 } 03147 DISASMV(I, "\t\t"); 03148 break; 03149 03150 case 0177: 03151 prefix_check(prefix); 03152 if(I == 0) { 03153 if(K == 0) 03154 n = 1; 03155 else 03156 n = A[K]; 03157 for(i=0; i<VL; i++) 03158 store_pvp_word((long)A[0]+i*n, V[J*VSZ+i]); 03159 DISASM2(",A0,A%1o\tV%1o\n", K, J); 03160 } 03161 else { 03162 for(i=0; i<VL; i++) 03163 store_pvp_word((long)(A[0]+V[K*VSZ+i]), V[J*VSZ+i]); 03164 DISASM2(",A0,V%1o\tV%1o\n", K, J); 03165 } 03166 break; 03167 } 03168 03169 } 03170 03171 ar_state_register.ar_truncate_bits = save_trunc_bits; 03172 03173 if(status == UNIMPL_INST) { 03174 DISASM1("%6.6o\n", p1); 03175 ar_internal_error(2013, __FILE__, __LINE__); 03176 status = AR_STAT_UNDEFINED; 03177 } 03178 else if(status == UNIMPL_PRFX) { 03179 DISASM2("%6.6o %6.6o\n", prefix, p1); 03180 ar_internal_error(2013, __FILE__, __LINE__); 03181 status = AR_STAT_UNDEFINED; 03182 } 03183 03184 return(status); 03185 } 03186 03187 typedef union { 03188 struct { 03189 unsigned int p1: 32; 03190 unsigned int p2: 32; 03191 } ui32; 03192 int64 ui64; 03193 } u; 03194 #define LO32(i) ((int64) (((u*)&(i))->ui32.p2)) 03195 #define HI32(i) ((int64) (((u*)&(i))->ui32.p1)) 03196 03197 static int 03198 ar_imul64u(int64* result, int64 opnd1, int64 opnd2) 03199 { 03200 int64 reg64, sum64, tmp64; 03201 03202 /* 03203 * Special case "Si Sj*USk". Eventually, with 128-bit ints, 03204 * we'll be able to support this directly. For now, we just 03205 * do it by hand in 32-bit chunks: 03206 * 03207 * a b 03208 * x c d 03209 * -------- 03210 * ad bd 03211 * ac bc 03212 * -------- 03213 * ac+ad+bd 03214 * +bc 03215 */ 03216 sum64 = LO32(opnd1) * LO32(opnd2); /* bd */ 03217 reg64 = HI32(opnd1) * LO32(opnd2); /* ad */ 03218 tmp64 = LO32(opnd1) * HI32(opnd2); /* bc */ 03219 03220 /* Sum from right propagating carry (in high 32 bits of sum64) */ 03221 sum64 = LO32(reg64) + LO32(tmp64) + HI32(sum64); 03222 sum64 = HI32(reg64) + HI32(tmp64) + HI32(sum64); 03223 reg64 = HI32(opnd1) * HI32(opnd2); /* ac */ 03224 *result = reg64 + sum64; 03225 03226 return AR_STAT_OK; 03227 } 03228 03229 #define CRAY_AHDR_SIZE 8 /* # words in cray a.out files */ 03230 03231 #define PAGESZ 256 /* # words in data space pages read in */ 03232 #define PAGESHFT 8 /* Shift to get page # */ 03233 03234 static int idf_fd; /* Intrinsic data file file descriptor */ 03235 static long idf_size; /* Intrinsic data file size (in bytes) */ 03236 static long text_size; /* Size of text space */ 03237 static long data_size; /* Size of data space */ 03238 static long data_offset; /* Offset to data space */ 03239 static int shared_text=0; /* =1 for a shared text data file */ 03240 static long data_address; /* Offset in data file to data section */ 03241 03242 static int64** data_page; /* Memory locations of data pages read in */ 03243 static int ndata_pages; /* Max # of data space pages */ 03244 03245 static void 03246 open_arith_file() 03247 { 03248 int fd; 03249 int i,v; 03250 int ieee; 03251 03252 int64 ahdr[CRAY_AHDR_SIZE]; 03253 char* craylibs; 03254 char* str; 03255 char* work; 03256 03257 /* Find and open intrinsic evaluation data file */ 03258 03259 stack=(int64*)malloc((STACK_SIZE+1+5*MAX_ARGS)*8); 03260 craylibs=(char*)getenv("CRAYLIBS"); 03261 work = (char*)stack; 03262 03263 /* Use the arith data file at the CRAYLIBS path if it is set */ 03264 03265 if(craylibs != NULL) { 03266 strcpy(work, craylibs); 03267 v=strlen(work); 03268 strcpy(&work[v],"/arith"); 03269 idf_fd=open(work, O_RDONLY); 03270 } 03271 03272 /* Check default locations for a (native-only) arith data file */ 03273 03274 #if _CRAY 03275 else { 03276 strcpy(work, "/opt/ctl/craylibs/craylibs/arith"); 03277 v = 27; 03278 idf_fd=open(work, O_RDONLY); 03279 if(idf_fd < 0) { 03280 strcpy(work, "/lib/arith"); 03281 v = 4; 03282 idf_fd=open(work, O_RDONLY); 03283 } 03284 } 03285 #endif 03286 if(idf_fd < 0) 03287 ar_internal_error(2009, __FILE__, __LINE__); 03288 03289 /* Load intrinsic evaluation data file into heap memory */ 03290 03291 idf_size=lseek(idf_fd, 0, SEEK_END); 03292 if(idf_size > 8*8) { 03293 lseek(idf_fd, 0, SEEK_SET); 03294 read(idf_fd, ahdr, CRAY_AHDR_SIZE*8); 03295 if((ahdr[0]>>32) == 0 && (ahdr[0]&0xffff) == 0407) { 03296 ar_mach_type = (ahdr[0]>>16)&0xff; 03297 ieee = (ahdr[0]>>29)&1; 03298 shared_text = (ahdr[0]>>31)&1; 03299 text_size = ahdr[1]; 03300 data_size = ahdr[2]; 03301 /* Check primary machine type */ 03302 if(ar_mach_type >= YMP && ar_mach_type <= T3E) { 03303 if(ar_mach_type != 9) 03304 code = (unsigned char*)malloc(text_size*8); 03305 if(code == NULL) 03306 idf_size = -3; /* Could not malloc text space */ 03307 } 03308 else 03309 idf_size = -2; 03310 } 03311 else 03312 idf_size = -1; /* Bad magic */ 03313 } 03314 else 03315 idf_size = 0; 03316 03317 /* Validate intrinsic evaluation data file contents and version info */ 03318 03319 if(idf_size > 0) { 03320 data_address = CRAY_AHDR_SIZE+text_size; 03321 data_offset = (1-shared_text)*text_size; 03322 read(idf_fd, code, text_size*8); 03323 str = (char*)strnstrn((char*)code, text_size*8, 03324 "@(#)PVP arith/libmv2_version ", 29); 03325 if(str != NULL) 03326 strcpy(AR_libmv2, str+14); 03327 else { 03328 lseek(idf_fd, idf_size-64, SEEK_SET); 03329 read(idf_fd, stack, 64); 03330 v=63; 03331 while(v > 0) { 03332 if(strncmp((char*)&stack[v], "libmv2_version", 14) == 0) { 03333 strcpy(AR_libmv2, (char*)&stack[v]); 03334 if(strncmp((char*)&stack[v-13], "PVP arith", 9)) 03335 idf_size=-1; 03336 break; 03337 } 03338 if(stack[v] == '\n') 03339 stack[v]='\0'; 03340 v--; 03341 } 03342 if(v <= 0) 03343 idf_size = -1; 03344 v = 0; 03345 } 03346 } 03347 03348 if(idf_size < 0) 03349 ar_internal_error(2010, __FILE__, __LINE__); 03350 03351 /* Validate probable libm.a version that will be used for loading */ 03352 03353 if(v > 0 && AR_libmv2[2] != 'x' && AR_libmv2[15+2] != 'x') { 03354 strcpy(&work[v], "/libm.a"); 03355 fd=open(work, O_RDONLY); 03356 if(fd < 0) { 03357 strcpy(&work[v], "/../libm.a"); 03358 fd=open(work, O_RDONLY); 03359 } 03360 if(fd >= 0) { 03361 read(fd, work, STACK_SIZE*8); 03362 close(fd); 03363 for(v=0; v<STACK_SIZE*8-27; v++) 03364 if(strncmp((char*)&work[v], "@(#)libmv2_version", 18) == 0) break; 03365 if(v < STACK_SIZE*8-27) { 03366 v+=19; 03367 for(i=0; i<8; i+=2) 03368 if(work[v+i]!='x' && AR_libmv2[15+i]!='x' && 03369 work[v+i]!=AR_libmv2[15+i]) 03370 fd=-2; 03371 } 03372 else 03373 fd=-3; 03374 } 03375 03376 /* If we are cross-compiling, libm.a need not exist */ 03377 03378 else { 03379 #if _CRAY 03380 #if _CRAYIEEE 03381 fd=-ieee; /* Ok if cross-compiling to Cray FP system */ 03382 #else 03383 fd=1-ieee; /* Ok if cross-compiling to IEEE FP system */ 03384 #endif 03385 #else 03386 fd=0; /* Ok since we are cross-compiling */ 03387 #endif 03388 } 03389 if(fd < 0) 03390 PRINTMSG(0, 2016, Logfile_Warning, 0, "YMP/C90", "0", "", ""); 03391 } 03392 03393 /* Define known numerical characteristics of each machine type */ 03394 03395 switch(ar_mach_type) { 03396 03397 case YMP: 03398 case C90: 03399 case T90: 03400 if(ar_mach_type == T90 && ieee) { 03401 ar_state_register.ar_float_format = AR_IEEE_FLOATING_POINT; 03402 ar_state_register.ar_rounding_mode = AR_ROUND_NEAREST; 03403 ar_state_register.ar_underflow_mode = AR_UNDERFLOW_TO_PLUS_ZERO; 03404 ar_state_register.ar_denorms_trap = 0; 03405 ar_state_register.ar_128bit_format = AR_128BIT_EXTENDED_DOUBLE; 03406 ar_rounding_modes = (1<<AR_ROUND_NEAREST) | 03407 (1<<AR_ROUND_ZERO) | 03408 (1<<AR_ROUND_PLUS_INFINITY) | 03409 (1<<AR_ROUND_MINUS_INFINITY); 03410 ar_underflow_modes = 1<<AR_UNDERFLOW_TO_PLUS_ZERO; 03411 } 03412 else { 03413 ar_state_register.ar_float_format = AR_CRAY_FLOATING_POINT; 03414 ar_state_register.ar_rounding_mode = AR_ROUNDED; 03415 ar_state_register.ar_underflow_mode = AR_UNDERFLOW_TO_PLUS_ZERO; 03416 ar_state_register.ar_denorms_trap = 0; 03417 ar_state_register.ar_128bit_format = AR_128BIT_DOUBLE_DOUBLE; 03418 ar_rounding_modes = (1<<AR_ROUNDED) | (1<<AR_UNROUNDED); 03419 ar_underflow_modes = 1<<AR_UNDERFLOW_TO_PLUS_ZERO; 03420 } 03421 AMASK = 0xffffffff; 03422 ASB = 0x80000000; 03423 set_a_size(32); 03424 if(ar_mach_type == YMP) { 03425 JSZP = 2; 03426 VSZ = 64; 03427 } 03428 else { 03429 JSZP = 3; 03430 VSZ = 128; 03431 if(ar_mach_type == T90) { 03432 AMASK |= (AMASK<<32); 03433 ASB <<= 32; 03434 set_a_size(64); 03435 } 03436 } 03437 break; 03438 03439 case T3D: 03440 ar_state_register.ar_float_format = AR_IEEE_FLOATING_POINT; 03441 ar_state_register.ar_rounding_mode = AR_ROUND_NEAREST; 03442 ar_state_register.ar_underflow_mode = AR_UNDERFLOW_TO_PLUS_ZERO; 03443 ar_state_register.ar_denorms_trap = 1; 03444 ar_state_register.ar_128bit_format = AR_128BIT_EXTENDED_DOUBLE; 03445 ar_rounding_modes = (1<<AR_ROUND_NEAREST); 03446 ar_underflow_modes = 1<<AR_UNDERFLOW_TO_PLUS_ZERO; 03447 JSZP = VSZ = 0; 03448 break; 03449 03450 case T3E: 03451 ar_state_register.ar_float_format = AR_IEEE_FLOATING_POINT; 03452 ar_state_register.ar_rounding_mode = AR_ROUND_NEAREST; 03453 ar_state_register.ar_underflow_mode = AR_UNDERFLOW_TO_PLUS_ZERO; 03454 ar_state_register.ar_denorms_trap = 1; 03455 ar_state_register.ar_128bit_format = AR_128BIT_EXTENDED_DOUBLE; 03456 ar_rounding_modes = (1<<AR_ROUND_NEAREST) | 03457 (1<<AR_ROUND_ZERO) | 03458 (1<<AR_ROUND_PLUS_INFINITY) | 03459 (1<<AR_ROUND_MINUS_INFINITY); 03460 ar_underflow_modes = 1<<AR_UNDERFLOW_TO_PLUS_ZERO; 03461 JSZP = VSZ = 0; 03462 break; 03463 } 03464 03465 if(JSZP == 3 && text_size > 0x3fff) { 03466 /* Current text segment sizes are less than 64K parcels. Therefore, 03467 * C90/T90 instructions 006..017 have a zero 3rd parcel which is skipped 03468 * in the instruction simulation in ar_sim. When/if the text segment 03469 * grows to more than 64K parcels, this test will cause a failure 03470 * and the branch instruction simulation will have to start using the 03471 * 3rd parcel. 03472 */ 03473 ar_internal_error(2012, __FILE__, __LINE__); 03474 } 03475 03476 /* Allocate data space page mapping array */ 03477 /* Note: 1 extra page for uninitialized data */ 03478 03479 ndata_pages = ((data_size+PAGESZ-1)>>PAGESHFT)+1; 03480 data_page = (int64**)malloc(ndata_pages*8); 03481 for(i=0; i<ndata_pages; i++) 03482 data_page[i] = NULL; 03483 03484 if(VSZ) 03485 V = (int64*)malloc(VSZ*8*8); /* Allocate V-register space */ 03486 } 03487 03488 static int64 03489 load_pvp_word(vaddr) 03490 long vaddr; 03491 { 03492 int p; 03493 int n; 03494 long disk_address; 03495 long offset = vaddr&0xffffff; 03496 int segment = (vaddr>>24)&0xff; 03497 03498 int64 result; 03499 03500 switch (segment) { 03501 03502 case DATA: 03503 offset -= data_offset; 03504 p = offset>>PAGESHFT; 03505 if(data_page[p] != NULL) 03506 return data_page[p][offset&(PAGESZ-1)]; 03507 03508 /* Check for load before store in uninitialized data space */ 03509 if(p >= (ndata_pages-1)) 03510 ar_internal_error(2012, __FILE__, __LINE__); 03511 03512 /* Always allocate a full page for possible stores into uninit'd data */ 03513 data_page[p] = (int64*)malloc(PAGESZ*8); 03514 03515 disk_address = (data_address+(offset&~(PAGESZ-1)))*8; 03516 n = PAGESZ*8; 03517 if(n > (idf_size-disk_address)) { 03518 n = idf_size-disk_address; 03519 memset((char*)(data_page[p])+n, 0xfe, PAGESZ*8-n); 03520 } 03521 if(data_page[p] == NULL) 03522 ar_internal_error(2010, __FILE__, __LINE__); 03523 lseek(idf_fd, disk_address, SEEK_SET); 03524 if(read(idf_fd, data_page[p], n) != n) 03525 ar_internal_error(2010, __FILE__, __LINE__); 03526 03527 return data_page[p][offset&(PAGESZ-1)]; 03528 03529 case STACK: 03530 if(offset < (STACK_SIZE+1+5*MAX_ARGS)) 03531 return stack[offset]; 03532 break; 03533 03534 default: 03535 if(segment < n_external_addresses && external_address[segment] != NULL) { 03536 if(external_length[segment] > offset) { 03537 memcpy(&result, external_address[segment]+offset*8, 8); 03538 return result; 03539 } 03540 /* Allow up to 64 words of unusable slop to be loaded */ 03541 /* See first vector load in memchr.s where this is needed */ 03542 if(external_length[segment] > (offset-64)) { 03543 result = 0xf0f1f2f3; 03544 return result; 03545 } 03546 } 03547 03548 } 03549 03550 ar_internal_error(2012, __FILE__, __LINE__); 03551 } 03552 03553 static void 03554 store_pvp_word(vaddr, result) 03555 long vaddr; 03556 int64 result; 03557 { 03558 int p; 03559 long offset = vaddr&0xffffff; 03560 int segment = (vaddr>>24)&0xff; 03561 03562 switch (segment) { 03563 03564 case DATA: 03565 offset -= data_offset; 03566 /* Allow store only beyond the end of initialized data space */ 03567 if(offset < data_size) 03568 ar_internal_error(2012, __FILE__, __LINE__); 03569 03570 p = offset>>PAGESHFT; 03571 /* If the last initialized data page hasn't been read, do dummy load */ 03572 if(data_page[p] == NULL && p == (ndata_pages-2)) 03573 load_pvp_word((DATA<<24) | (data_offset+(offset&~(PAGESZ-1)))); 03574 03575 if(data_page[p] != NULL) { 03576 data_page[p][offset&(PAGESZ-1)] = result; 03577 return; 03578 } 03579 03580 /* Allow store only into 1st full page of uninitialized data space */ 03581 if(p != (ndata_pages-1)) 03582 ar_internal_error(2012, __FILE__, __LINE__); 03583 03584 data_page[p] = (int64*)malloc(PAGESZ*8); 03585 memset((char*)data_page[p], 0xfe, PAGESZ*8); 03586 data_page[p][offset&(PAGESZ-1)] = result; 03587 return; 03588 03589 case STACK: 03590 if(offset < (STACK_SIZE+1+5*MAX_ARGS)) { 03591 stack[offset] = result; 03592 return; 03593 } 03594 break; 03595 03596 default: 03597 if(segment < n_external_addresses && external_address[segment] != NULL) { 03598 if(external_length[segment] > offset) { 03599 memcpy(external_address[segment]+offset*8, &result, 8); 03600 return; 03601 } 03602 /* Allow ORE (without actual store) iff value matches that 03603 * returned by load_pvp_word above. 03604 */ 03605 if(external_length[segment] > (offset-64) && result == 0xf0f1f2f3) 03606 return; 03607 } 03608 } 03609 03610 ar_internal_error(2012, __FILE__, __LINE__); 03611 } 03612 03613 #endif