00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
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
00047
00048
00049
00050
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;
00102
00103 #define DATA 0
00104 #define STACK 1
00105
00106 #define STACK_SIZE 20480
00107
00108 #define MAX_ARGS 8
00109 #define MAX_EXT_ADDRS 16
00110
00111 static unsigned char* code=NULL;
00112 static int64* stack=NULL;
00113
00114
00115
00116 static int JSZP;
00117 static int VSZ;
00118
00119 static int64 AMASK;
00120 static int64 ASB;
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;
00129
00130 static int VL;
00131 static int64 VM;
00132 static int64 VM1;
00133 static int64* V;
00134
00135
00136
00137 static int numargs;
00138 static int numargwds;
00139 static int n_external_addresses;
00140 static char* external_address[MAX_EXT_ADDRS];
00141 static long external_length[MAX_EXT_ADDRS];
00142
00143
00144
00145 #define RMMASK 6
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
00155
00156 #ifdef DEBUG
00157 int ar_disasm = 0;
00158 int ar_disasm_BT = 0;
00159 int ar_disasm_V = 0;
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
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 int
00236 ar_clear_sim_state(AR_TYPE resulttype)
00237 {
00238
00239 #ifdef DEBUG
00240 if (getenv("AR_DISASM") != NULL) {
00241 ar_disasm = 1;
00242 }
00243 if (getenv("AR_DISASM_BT") != NULL) {
00244 ar_disasm_BT = 1;
00245 }
00246 if (getenv("AR_DISASM_V") != NULL) {
00247 ar_disasm_V = 1;
00248 }
00249 #endif
00250
00251
00252
00253 if(code == NULL)
00254 open_arith_file();
00255
00256 if(AR_CLASS(resulttype) == AR_CLASS_FLOAT) {
00257 if((AR_FLOAT_FORMAT(resulttype) == AR_FLOAT_CRAY &&
00258 ar_state_register.ar_float_format != AR_CRAY_FLOATING_POINT) ||
00259 (AR_FLOAT_FORMAT(resulttype) == AR_FLOAT_IEEE &&
00260 ar_state_register.ar_float_format != AR_IEEE_FLOATING_POINT))
00261 ar_internal_error(2018, __FILE__, __LINE__);
00262 }
00263
00264 numargwds = numargs = 0;
00265 n_external_addresses = 1;
00266 return AR_STAT_OK;
00267 }
00268
00269 int
00270 ar_ext_address(int64* intaddr, const char* extaddr, int length)
00271 {
00272 #if MAX_EXT_ADDRS >= DATA
00273 if(n_external_addresses == DATA)
00274 external_address[n_external_addresses++] = NULL;
00275 #if MAX_EXT_ADDRS >= STACK
00276 if(n_external_addresses == STACK)
00277 external_address[n_external_addresses++] = NULL;
00278 #endif
00279 #endif
00280 *intaddr = n_external_addresses<<24;
00281
00282 if(n_external_addresses >= MAX_EXT_ADDRS)
00283 return AR_STAT_UNDEFINED;
00284
00285 external_address[n_external_addresses] = (char*)extaddr;
00286 external_length[n_external_addresses++] = length;
00287
00288 return AR_STAT_OK;
00289 }
00290
00291 int
00292 ar_pass_arg_address(const ar_data* arg, const AR_TYPE* argtype)
00293 {
00294 int iarg;
00295 int nbytes;
00296 int arg_offset;
00297 int arg_value_offset;
00298
00299 iarg = numargwds;
00300 numargs++;
00301 numargwds++;
00302
00303 if(iarg >= MAX_ARGS)
00304 ar_internal_error(2014, __FILE__, __LINE__);
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321 if(arg == NULL)
00322 S[0] = 0;
00323 else {
00324 arg_value_offset = (STACK_SIZE+1+MAX_ARGS+iarg*4);
00325 S[0] = (STACK<<24) | arg_value_offset;
00326 }
00327
00328
00329
00330
00331
00332 arg_offset = (STACK<<24) | (STACK_SIZE+1+iarg);
00333 store_pvp_word(arg_offset, S[0]);
00334
00335 if(arg == NULL)
00336 return AR_STAT_OK;
00337
00338
00339
00340 switch (UNROUNDED_TYPE(*argtype)) {
00341
00342 case CRAY_FLOAT_64:
00343 case IEEE_FLOAT_64:
00344 nbytes = 8;
00345 break;
00346
00347 case CRAY_FLOAT_128:
00348 case CRAY_COMPLEX_64:
00349 case IEEE_FLOAT_128:
00350 case IEEE_COMPLEX_64:
00351 nbytes = 16;
00352 break;
00353
00354 case CRAY_COMPLEX_128:
00355 case IEEE_COMPLEX_128:
00356 nbytes = 32;
00357 break;
00358
00359 default:
00360 switch (*argtype) {
00361
00362 case AR_Int_46_S:
00363 case AR_Int_64_S:
00364 case AR_Logical:
00365 nbytes = 8;
00366 break;
00367
00368 default:
00369 return AR_STAT_INVALID_TYPE;
00370 }
00371 }
00372
00373 memcpy((char*)&stack[arg_value_offset], (char*)(arg), nbytes);
00374 return AR_STAT_OK;
00375 }
00376
00377 int
00378 ar_pass_ext_address(int64 *extdesc, const char *addr, int nwords)
00379 {
00380 int iarg;
00381 int arg_offset;
00382 int arg_value_offset;
00383
00384 int status;
00385
00386 iarg = numargwds;
00387 numargs++;
00388 numargwds++;
00389
00390 if(iarg >= MAX_ARGS)
00391 ar_internal_error(2014, __FILE__, __LINE__);
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403 if(addr == NULL)
00404 S[0] = 0;
00405 else {
00406 status = ar_ext_address(&S[0], addr, nwords);
00407 if(IS_ERROR_STATUS(status))
00408 return status;
00409 }
00410
00411 if(extdesc != NULL)
00412 *extdesc = S[0];
00413
00414
00415
00416
00417
00418 arg_offset = (STACK<<24) | (STACK_SIZE+1+iarg);
00419 store_pvp_word(arg_offset, S[0]);
00420
00421 return AR_STAT_OK;
00422 }
00423
00424 int
00425 ar_pass_fcd_address(const char* str, long lenstr)
00426 {
00427 int iarg;
00428 int arg_offset;
00429 int arg_value_offset;
00430
00431 int status;
00432
00433 long nbits;
00434
00435 iarg = numargwds;
00436 numargs++;
00437 numargwds++;
00438
00439 if(iarg >= MAX_ARGS)
00440 ar_internal_error(2014, __FILE__, __LINE__);
00441
00442 if(str == NULL)
00443 return AR_STAT_UNDEFINED;
00444
00445
00446 nbits = lenstr<<3;
00447 status = ar_ext_address(&S[0], str, (lenstr+7)>>3);
00448 if(IS_ERROR_STATUS(status))
00449 return status;
00450
00451
00452
00453
00454
00455 arg_offset = (STACK<<24) | (STACK_SIZE+1+iarg);
00456 if(ar_mach_type == T90) {
00457
00458 store_pvp_word(arg_offset, S[0]);
00459 S[0] = nbits;
00460 numargwds++;
00461 store_pvp_word(arg_offset+1, S[0]);
00462 }
00463 else {
00464
00465 S[0] |= (int64)nbits<<32;
00466 store_pvp_word(arg_offset, S[0]);
00467 }
00468
00469 return AR_STAT_OK;
00470 }
00471
00472 int
00473 ar_pass_arg_value(const ar_data* arg, const AR_TYPE* argtype)
00474 {
00475 int iarg;
00476 int nbytes;
00477 int arg_offset;
00478 int status;
00479
00480 iarg = numargwds;
00481 numargs++;
00482 numargwds++;
00483
00484 if(iarg >= MAX_ARGS)
00485 ar_internal_error(2014, __FILE__, __LINE__);
00486
00487
00488
00489
00490
00491 if(arg == NULL)
00492 return AR_STAT_UNDEFINED;
00493
00494 switch (UNROUNDED_TYPE(*argtype)) {
00495
00496 case CRAY_FLOAT_64:
00497 case IEEE_FLOAT_64:
00498 nbytes = 8;
00499 break;
00500
00501 case CRAY_FLOAT_128:
00502 case CRAY_COMPLEX_64:
00503 case IEEE_FLOAT_128:
00504 case IEEE_COMPLEX_64:
00505 numargwds++;
00506 nbytes = 16;
00507 break;
00508
00509 case CRAY_COMPLEX_128:
00510 case IEEE_COMPLEX_128:
00511 numargwds += 3;
00512 nbytes = 32;
00513 break;
00514
00515 default:
00516 switch (*argtype) {
00517
00518 case AR_Int_46_S:
00519 case AR_Int_64_S:
00520 case AR_Logical:
00521 nbytes = 8;
00522 break;
00523
00524 default:
00525 return AR_STAT_INVALID_TYPE;
00526 }
00527 }
00528
00529 memcpy(&S[1+iarg], (char*)arg, nbytes);
00530 return AR_STAT_OK;
00531 }
00532
00533
00534 int
00535 ar_put_real_address(AR_INT_64* extdesc)
00536 {
00537 int segment = extdesc->part3>>8;
00538
00539 if(segment >= n_external_addresses)
00540 return AR_STAT_UNDEFINED;
00541
00542 extdesc->part3 = ((long)external_address[segment]) >> 16;
00543 extdesc->part4 = ((long)external_address[segment]) & 0xffff;
00544
00545 return AR_STAT_OK;
00546 }
00547
00548
00549 int
00550 ar_get_function_value(ar_data *result, AR_TYPE *resulttype)
00551 {
00552 int status;
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566 switch (AR_CLASS(*resulttype)) {
00567
00568 case AR_CLASS_INT:
00569
00570 status = ar_convert_to_integral(result, resulttype,
00571 (ar_data*)&S[1], resulttype);
00572 break;
00573
00574 case AR_CLASS_FLOAT:
00575
00576 switch(UNROUNDED_TYPE(*resulttype)) {
00577
00578 case CRAY_FLOAT_64:
00579 status = ar_convert_to_float(result, resulttype,
00580 (ar_data*)&S[1], &cray_float_64);
00581 break;
00582
00583 case CRAY_FLOAT_128:
00584 status = ar_convert_to_float(result, resulttype,
00585 (ar_data*)&S[1], &cray_float_128);
00586 break;
00587
00588 case CRAY_COMPLEX_64:
00589 status = ar_convert_to_complex(result, resulttype,
00590 (ar_data*)&S[1], &cray_complex_64);
00591 break;
00592
00593 case CRAY_COMPLEX_128:
00594 status = ar_convert_to_complex(result, resulttype,
00595 (ar_data*)&S[1], &cray_complex_128);
00596 break;
00597
00598 case IEEE_FLOAT_64:
00599 status = ar_convert_to_float(result, resulttype,
00600 (ar_data*)&S[1], &ieee_float_64);
00601 break;
00602
00603 case IEEE_FLOAT_128:
00604 status = ar_convert_to_float(result, resulttype,
00605 (ar_data*)&S[1], &ieee_float_128);
00606 break;
00607
00608 case IEEE_COMPLEX_64:
00609 status = ar_convert_to_complex(result, resulttype,
00610 (ar_data*)&S[1], &ieee_complex_64);
00611 break;
00612
00613 case IEEE_COMPLEX_128:
00614 status = ar_convert_to_complex(result, resulttype,
00615 (ar_data*)&S[1], &ieee_complex_128);
00616 break;
00617
00618 default:
00619 return AR_STAT_INVALID_TYPE;
00620 }
00621 break;
00622
00623 default:
00624 return AR_STAT_INVALID_TYPE;
00625 }
00626 return status &~ AR_ERROR_STATUS;
00627 }
00628
00629 static int
00630 call_host_external(char* func)
00631 {
00632 char* ptr1, ptr2;
00633
00634 int status;
00635
00636 long length;
00637
00638 if(strncmp(func, "malloc", 6) == 0) {
00639 length = S[1];
00640 ptr1 = malloc(length);
00641 status = ar_ext_address(&S[1], (const char*)ptr1, (length+7)>>3);
00642 return status;
00643 }
00644
00645 return AR_STAT_UNDEFINED;
00646 }
00647
00648 #define NOINTRIN 1
00649 #define ARITHERR 2
00650 #define EXTERROR 3
00651 #define SETERRNO 4
00652 #define IFACEERR 5
00653 #define HOSTEXT 6
00654 #define UNIMPL_INST 7
00655 #define UNIMPL_PRFX 8
00656
00657
00658 #if _CRAY
00659 #define getp1(pc) ( (*(((long*)code)+((pc)>>2))>>(48-(((pc)&3)<<4)) & 0xffff) )
00660 #else
00661 #define getp1(pc) ( (((int) code[(pc)*2])<<8) | code[(pc)*2+1] )
00662 #endif
00663
00664 #define prefix_check(p) if (p) { status = UNIMPL_PRFX; break; } else
00665
00666 static int
00667 ar_check_status(int status, AR_IEEE_64* rr)
00668 {
00669 if(!IS_ERROR_STATUS(status))
00670 return AR_STAT_OK;
00671
00672 if((status & AR_STAT_OVERFLOW) && (SR0 & (INTERRUPT_OVF|INTERRUPT_DIV)))
00673 return status;
00674
00675 if((status & AR_STAT_UNDEFINED) && (SR0 & INTERRUPT_INV))
00676 if(rr->expo > AR_IEEE64_MAX_EXPO &&
00677 (rr->coeff0 | rr->coeff1 | rr->coeff2 | rr->coeff3))
00678 return status;
00679
00680 return AR_STAT_OK;
00681 }
00682
00683 int
00684 ar_sim(char* intrinsic)
00685 {
00686 char* name;
00687 char* str;
00688
00689 int i,j,n;
00690 int status;
00691
00692 int p1;
00693 int op;
00694 int I,J,K;
00695 int JK;
00696 int prefix;
00697
00698 unsigned long pc, inst_pc;
00699 AR_HOST_UINT64 wa;
00700 AR_HOST_UINT64 rtc, rtcpc;
00701
00702 int64 zero;
00703 int64 one;
00704 int64 ones;
00705 int64 sb;
00706 int64 reg64;
00707
00708 int64 *rr, *oj, *ok;
00709
00710 int save_trunc_bits;
00711
00712 AR_COMPARE_TYPE cmpres;
00713
00714 static int ar_imul64u();
00715
00716
00717
00718
00719
00720
00721
00722
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;
00730 store_pvp_word((long)A[6], S[0]);
00731
00732 VL = 0;
00733 B[000] = 0;
00734 B[066] = (STACK<<24) | 0;
00735 B[067] = B[066]+STACK_SIZE;
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751 B[065] = ar_sim_version;
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
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
00771
00772 save_trunc_bits = ar_state_register.ar_truncate_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
00781
00782
00783
00784
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
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:
00810 ar_internal_error(2014, __FILE__, __LINE__);
00811 status = AR_STAT_UNDEFINED;
00812 break;
00813 case NOINTRIN:
00814 PRINTMSG(0, 2015, Internal, 0, __FILE__, __LINE__, intrinsic, "");
00815 status = AR_STAT_UNDEFINED;
00816 break;
00817 case EXTERROR:
00818 if(status == EXTERROR)
00819 ar_internal_error(2012, __FILE__, __LINE__);
00820 case ARITHERR:
00821 status = AR_STAT_UNDEFINED;
00822 break;
00823 case SETERRNO:
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) {
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
00900 DISASM1("%6.6o\n", p1);
00901 break;
00902
00903 case 003:
00904 prefix_check(prefix);
00905 if(I == 0) {
00906 if(K < 4) {
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);
00931 DISASM1("R%1.1sM\n", "NUZD"+(K&3));
00932 }
00933 }
00934 else
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) {
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
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:
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);
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);
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);
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
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
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
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
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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 {
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:
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:
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:
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:
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:
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:
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) {
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) {
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:
03080 prefix_check(prefix);
03081 VM = VM1 = 0;
03082 n = 0;
03083 if(K & 2) {
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 {
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
03204
03205
03206
03207
03208
03209
03210
03211
03212
03213
03214
03215
03216 sum64 = LO32(opnd1) * LO32(opnd2);
03217 reg64 = HI32(opnd1) * LO32(opnd2);
03218 tmp64 = LO32(opnd1) * HI32(opnd2);
03219
03220
03221 sum64 = LO32(reg64) + LO32(tmp64) + HI32(sum64);
03222 sum64 = HI32(reg64) + HI32(tmp64) + HI32(sum64);
03223 reg64 = HI32(opnd1) * HI32(opnd2);
03224 *result = reg64 + sum64;
03225
03226 return AR_STAT_OK;
03227 }
03228
03229 #define CRAY_AHDR_SIZE 8
03230
03231 #define PAGESZ 256
03232 #define PAGESHFT 8
03233
03234 static int idf_fd;
03235 static long idf_size;
03236 static long text_size;
03237 static long data_size;
03238 static long data_offset;
03239 static int shared_text=0;
03240 static long data_address;
03241
03242 static int64** data_page;
03243 static int ndata_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
03258
03259 stack=(int64*)malloc((STACK_SIZE+1+5*MAX_ARGS)*8);
03260 craylibs=(char*)getenv("CRAYLIBS");
03261 work = (char*)stack;
03262
03263
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
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
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
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;
03307 }
03308 else
03309 idf_size = -2;
03310 }
03311 else
03312 idf_size = -1;
03313 }
03314 else
03315 idf_size = 0;
03316
03317
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
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
03377
03378 else {
03379 #if _CRAY
03380 #if _CRAYIEEE
03381 fd=-ieee;
03382 #else
03383 fd=1-ieee;
03384 #endif
03385 #else
03386 fd=0;
03387 #endif
03388 }
03389 if(fd < 0)
03390 PRINTMSG(0, 2016, Logfile_Warning, 0, "YMP/C90", "0", "", "");
03391 }
03392
03393
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
03467
03468
03469
03470
03471
03472
03473 ar_internal_error(2012, __FILE__, __LINE__);
03474 }
03475
03476
03477
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);
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
03509 if(p >= (ndata_pages-1))
03510 ar_internal_error(2012, __FILE__, __LINE__);
03511
03512
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
03541
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
03567 if(offset < data_size)
03568 ar_internal_error(2012, __FILE__, __LINE__);
03569
03570 p = offset>>PAGESHFT;
03571
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
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
03603
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