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
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <fcntl.h>
00039 #include <errno.h>
00040 #include <sys/types.h>
00041 #include <unistd.h>
00042
00043 #include <ar.h>
00044 #if !defined(AR_HDR_SIZE)
00045
00046
00047
00048 # define AR_HDR_SIZE sizeof(struct ar_hdr)
00049 #endif
00050
00051
00052
00053
00054
00055 #include "arith.internal.h"
00056 #include "int64.h"
00057
00058 #if !defined(__mips)
00059
00060 int ar_rounding_modes = 1<<AR_ROUND_NEAREST;
00061 int ar_underflow_modes = 1<<AR_UNDERFLOW_TO_PLUS_ZERO;
00062
00063 extern char AR_libmv2[];
00064 extern char AR_version[];
00065
00066 #define IEEE_FLOAT_32 (UNROUNDED_TYPE(AR_Float_IEEE_NR_32))
00067 #define IEEE_FLOAT_64 (UNROUNDED_TYPE(AR_Float_IEEE_NR_64))
00068 #define IEEE_FLOAT_128 (UNROUNDED_TYPE(AR_Float_IEEE_NR_128))
00069 #define IEEE_COMPLEX_32 (UNROUNDED_TYPE(AR_Complex_IEEE_NR_32))
00070 #define IEEE_COMPLEX_64 (UNROUNDED_TYPE(AR_Complex_IEEE_NR_64))
00071 #define IEEE_COMPLEX_128 (UNROUNDED_TYPE(AR_Complex_IEEE_NR_128))
00072
00073 #define T3D 10
00074 #define T3E 12
00075
00076 static int ar_sim_version = 0;
00077 static int ar_mach_type = T3D;
00078
00079 static AR_TYPE integer_64 = AR_Int_64_S;
00080 static AR_TYPE ieee_float_32 = (AR_TYPE) IEEE_FLOAT_32;
00081 static AR_TYPE ieee_float_64 = (AR_TYPE) IEEE_FLOAT_64;
00082
00083 #define NOINTRIN 1
00084 #define ARITHERR 2
00085 #define EXTERROR 3
00086 #define SETERRNO 4
00087 #define IFACEERR 5
00088 #define HOSTEXT 6
00089 #define BADINSTR 7
00090
00091 #define MPP_STACK_SIZE 2048
00092 #define MPP_DSIB_SIZE 6
00093 #define MPP_MAX_ARGS 8
00094
00095 static unsigned char* mpp_intrin=NULL;
00096 static unsigned char* code=NULL;
00097 static unsigned char* data=NULL;
00098 static unsigned char* stack=NULL;
00099
00100 static int D_roundmode = -1;
00101
00102 static AR_TYPE D_float_32;
00103 static AR_TYPE D_float_64;
00104 static AR_TYPE D_float_128;
00105 static AR_TYPE D_complex_64;
00106 static AR_TYPE D_complex_128;
00107
00108
00109
00110 static AR_INT_64 R[32];
00111 static AR_INT_64 F[32];
00112
00113 #ifdef DEBUG
00114
00115
00116
00117 int ar_disasm = 0;
00118
00119 static char RN[32][5] = {
00120 "v0",
00121 "t0",
00122 "t1",
00123 "t2",
00124 "t3",
00125 "t4",
00126 "t5",
00127 "t6",
00128 "t7",
00129 "s0",
00130 "s1",
00131 "s2",
00132 "s3",
00133 "s4",
00134 "s5",
00135 "fp",
00136 "a0",
00137 "a1",
00138 "a2",
00139 "a3",
00140 "a4",
00141 "a5",
00142 "t8",
00143 "t9",
00144 "t10",
00145 "ci",
00146 "ra",
00147 "t11",
00148 "t12",
00149 "t13",
00150 "sp",
00151 "R31"
00152 };
00153
00154 static char FN[32][6] = {
00155 "fv0",
00156 "fv1",
00157 "fs0",
00158 "fs1",
00159 "fs2",
00160 "fs3",
00161 "fs4",
00162 "fs5",
00163 "fs6",
00164 "fs7",
00165 "ft0",
00166 "ft1",
00167 "ft2",
00168 "ft3",
00169 "ft4",
00170 "ft5",
00171 "fa0",
00172 "fa1",
00173 "fa2",
00174 "fa3",
00175 "fa4",
00176 "fa5",
00177 "ft6",
00178 "ft7",
00179 "ft8",
00180 "ft9",
00181 "ft10",
00182 "ft11",
00183 "ft12",
00184 "ft13",
00185 "ft14",
00186 "F31"
00187 };
00188
00189 #define DISASM0(fmt) if(ar_disasm) fprintf(stderr,fmt)
00190 #define DISASM1(fmt,x) if(ar_disasm) fprintf(stderr,fmt,x)
00191 #define DISASM2(fmt,x,y) if(ar_disasm) fprintf(stderr,fmt,x,y)
00192 #define DISASM3(fmt,x,y,z) if(ar_disasm) fprintf(stderr,fmt,x,y,z)
00193 #define DISASM4(fmt,x,y,z,v) if(ar_disasm) fprintf(stderr,fmt,x,y,z,v)
00194 #define DISASM5(fmt,x,y,z,v,w) if(ar_disasm) fprintf(stderr,fmt,x,y,z,v,w)
00195
00196 #else
00197
00198 #define DISASM0(fmt)
00199 #define DISASM1(fmt,x)
00200 #define DISASM2(fmt,x,y)
00201 #define DISASM3(fmt,x,y,z)
00202 #define DISASM4(fmt,x,y,z,v)
00203 #define DISASM5(fmt,x,y,z,v,w)
00204
00205 #endif
00206
00207
00208
00209 #define v0 0
00210 #define t1 2
00211 #define s0 9
00212 #define fp 15
00213 #define a0 16
00214 #define a1 17
00215 #define a2 18
00216 #define a3 19
00217 #define a4 20
00218 #define a5 21
00219 #define ci 25
00220 #define ret 26
00221 #define sp 30
00222 #define zero 31
00223
00224 #define fv0 0
00225 #define fv1 1
00226 #define fa0 16
00227 #define fzero 31
00228
00229 #define MAX_EXT_ADDRS 16
00230
00231 static AR_HOST_SINT64 numargs = 0;
00232
00233 static int n_external_addresses = 1;
00234
00235
00236
00237
00238 static unsigned code_segment_id;
00239 static unsigned data_segment_id;
00240 static unsigned stack_segment_id;
00241
00242
00243
00244
00245 typedef enum {
00246 SEGT_DATA = 0,
00247 SEGT_TEXT = 1,
00248 SEGT_REGISTERS = 2,
00249 SEGT_STACK = 3,
00250 SEGT_EREGISTERS = 4,
00251 SEGT_BESUS = 5
00252 } SegTypes;
00253
00254 static char* external_address[MAX_EXT_ADDRS];
00255 static long external_length[MAX_EXT_ADDRS];
00256
00257 typedef union {
00258 AR_INT_64 ari64;
00259 long l64;
00260 } i64_union;
00261
00262
00263
00264
00265
00266 static int call_host_external(char* func);
00267 static void open_intrinsics_file(void);
00268 static void load_mpp_word(AR_INT_64 *result, long segment, long offset);
00269 static void store_mpp_word(long segment, long offset, AR_INT_64 *result);
00270
00271
00272 int
00273 ar_clear_sim_state(AR_TYPE resulttype)
00274 {
00275
00276 #ifdef DEBUG
00277 if (getenv("AR_DISASM") != NULL) {
00278 ar_disasm = 1;
00279 }
00280 #endif
00281
00282 if(mpp_intrin == NULL)
00283 open_intrinsics_file();
00284
00285 if(AR_CLASS(resulttype) == AR_CLASS_FLOAT &&
00286 AR_FLOAT_FORMAT(resulttype) == AR_FLOAT_CRAY)
00287 ar_internal_error(2018, __FILE__, __LINE__);
00288
00289 numargs = 0;
00290 ZERO64(R[ci]);
00291 n_external_addresses = 1;
00292
00293 D_roundmode = ar_float_ieee_round_nearest;
00294 D_float_32 = (AR_TYPE) IEEE_FLOAT_32;
00295 D_float_64 = (AR_TYPE) IEEE_FLOAT_64;
00296 D_float_128 = (AR_TYPE) IEEE_FLOAT_128;
00297 D_complex_64 = (AR_TYPE) IEEE_COMPLEX_64;
00298 D_complex_128 = (AR_TYPE) IEEE_COMPLEX_128;
00299
00300 return AR_STAT_OK;
00301 }
00302
00303 int
00304 ar_ext_address(AR_INT_64* intaddr, const char* extaddr, int length)
00305 {
00306 if(n_external_addresses == code_segment_id)
00307 external_address[n_external_addresses++] = NULL;
00308
00309 if(n_external_addresses == data_segment_id)
00310 external_address[n_external_addresses++] = NULL;
00311
00312 if(n_external_addresses == stack_segment_id)
00313 external_address[n_external_addresses++] = NULL;
00314
00315 intaddr[0].part1 = intaddr[0].part3 = intaddr[0].part4 = 0;
00316 intaddr[0].part2 = n_external_addresses;
00317
00318 if(n_external_addresses >= MAX_EXT_ADDRS)
00319 return AR_STAT_UNDEFINED;
00320
00321 external_address[n_external_addresses] = (char*)extaddr;
00322 external_length[n_external_addresses++] = length;
00323
00324 return AR_STAT_OK;
00325 }
00326
00327 int
00328 ar_pass_arg_address(const ar_data* arg, const AR_TYPE* argtype)
00329 {
00330 int iarg;
00331 int arg_offset;
00332 int arg_value_offset;
00333
00334 numargs++;
00335 iarg = R[ci].part4>>8;
00336 R[ci].part4 += (1<<8);
00337
00338 if(iarg >= MPP_MAX_ARGS)
00339 ar_internal_error(2014, __FILE__, __LINE__);
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356 if(arg == NULL)
00357 ZERO64(R[s0]);
00358 else {
00359 arg_value_offset = (MPP_STACK_SIZE + MPP_MAX_ARGS + (iarg * 4)) * 8;
00360 R[s0].part1 = 0;
00361 R[s0].part2 = stack_segment_id;
00362 R[s0].part3 = (arg_value_offset>>16);
00363 R[s0].part4 = arg_value_offset&0xffff;
00364 }
00365
00366
00367
00368
00369
00370
00371 if(iarg < 6) {
00372 memcpy(&R[a0+iarg], &R[s0], 8);
00373 R[ci].part4++;
00374 }
00375 else {
00376 arg_offset = MPP_STACK_SIZE + iarg;
00377 store_mpp_word(stack_segment_id, arg_offset, &R[s0]);
00378 }
00379
00380
00381
00382 if(AR_CLASS(*argtype) == AR_CLASS_FLOAT) {
00383 D_roundmode = ROUND_MODE(*argtype);
00384 D_float_32 = (AR_TYPE) (IEEE_FLOAT_32 | (D_roundmode<<3));
00385 D_float_64 = (AR_TYPE) (IEEE_FLOAT_64 | (D_roundmode<<3));
00386 D_float_128 = (AR_TYPE) (IEEE_FLOAT_128 | (D_roundmode<<3));
00387 D_complex_64 = (AR_TYPE) (IEEE_COMPLEX_64 | (D_roundmode<<3));
00388 D_complex_128 = (AR_TYPE) (IEEE_COMPLEX_128 | (D_roundmode<<3));
00389 }
00390
00391 if(arg == NULL)
00392 return AR_STAT_OK;
00393
00394
00395
00396 switch (UNROUNDED_TYPE(*argtype)) {
00397
00398 case IEEE_FLOAT_32:
00399 memcpy(&stack[arg_value_offset], (char*)(arg)+4, 4);
00400 break;
00401
00402 case IEEE_FLOAT_64:
00403 case IEEE_COMPLEX_32:
00404 memcpy(&stack[arg_value_offset], (char*)(arg), 8);
00405 break;
00406
00407 case IEEE_FLOAT_128:
00408 case IEEE_COMPLEX_64:
00409 memcpy(&stack[arg_value_offset], (char*)(arg), 16);
00410 break;
00411
00412
00413 case AR_Int_32_S:
00414 memcpy(&stack[arg_value_offset], (char*)(arg)+4, 4);
00415 break;
00416
00417 case IEEE_COMPLEX_128:
00418 memcpy(&stack[arg_value_offset], (char*)(arg), 32);
00419 break;
00420
00421 default:
00422 switch (*argtype) {
00423
00424 case AR_Int_32_S:
00425 memcpy(&stack[arg_value_offset], (char*)(arg)+4, 4);
00426 break;
00427
00428 case AR_Logical:
00429 if(arg->ar_i64.part1 || arg->ar_i64.part2 ||
00430 arg->ar_i64.part3 || arg->ar_i64.part4)
00431 memcpy(&stack[arg_value_offset], (char*)&AR_const_true, 8);
00432 else
00433 memcpy(&stack[arg_value_offset], (char*)&AR_const_false, 8);
00434 break;
00435
00436 case AR_Int_46_S:
00437 case AR_Int_64_S:
00438 memcpy(&stack[arg_value_offset], (char*)(arg), 8);
00439 break;
00440
00441 default:
00442 return AR_STAT_INVALID_TYPE;
00443 }
00444 }
00445
00446 return AR_STAT_OK;
00447 }
00448
00449 int
00450 ar_pass_ext_address(AR_INT_64 *extdesc, const char *addr, int nwords)
00451 {
00452 int iarg;
00453 int arg_offset;
00454 int arg_value_offset;
00455
00456 int status;
00457
00458 numargs++;
00459 iarg = R[ci].part4>>8;
00460 R[ci].part4 += (1<<8);
00461
00462 if(iarg >= MPP_MAX_ARGS)
00463 ar_internal_error(2014, __FILE__, __LINE__);
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475 if(addr == NULL)
00476 ZERO64(R[s0]);
00477 else {
00478 status = ar_ext_address(&R[s0], addr, nwords);
00479 if(IS_ERROR_STATUS(status))
00480 return status;
00481 }
00482
00483
00484
00485
00486
00487
00488 if(iarg < 6) {
00489 memcpy(&R[a0+iarg], &R[s0], 8);
00490 R[ci].part4++;
00491 }
00492 else {
00493 arg_offset = MPP_STACK_SIZE + iarg;
00494 store_mpp_word(stack_segment_id, arg_offset, &R[s0]);
00495 }
00496
00497 if(extdesc != NULL) {
00498 R[s0].part4 = 3;
00499 memcpy(extdesc, &R[s0], 8);
00500 }
00501
00502 return AR_STAT_OK;
00503 }
00504
00505 int
00506 ar_pass_fcd_address(const char* str, long lenstr)
00507 {
00508 int iarg;
00509 int arg_offset;
00510 int arg_value_offset;
00511
00512 int status;
00513
00514 long nbits;
00515
00516 numargs++;
00517 iarg = R[ci].part4>>8;
00518 R[ci].part4 += (2<<8);
00519
00520 if(iarg >= MPP_MAX_ARGS)
00521 ar_internal_error(2014, __FILE__, __LINE__);
00522
00523 if(str == NULL)
00524 return AR_STAT_UNDEFINED;
00525
00526
00527 nbits = lenstr<<3;
00528 status = ar_ext_address(&R[s0], str, (nbits+63)>>6);
00529 if(IS_ERROR_STATUS(status))
00530 return status;
00531
00532
00533
00534
00535
00536 if(iarg < 6) {
00537 memcpy(&R[a0+iarg], &R[s0], 8);
00538 R[ci].part4++;
00539 }
00540 else {
00541 arg_offset = MPP_STACK_SIZE + iarg;
00542 store_mpp_word(stack_segment_id, arg_offset, &R[s0]);
00543 }
00544
00545
00546 R[s0].part1 = R[s0].part2 = 0;
00547 if(ar_mach_type == T3D) {
00548 R[s0].part3 = nbits>>16;
00549 R[s0].part4 = nbits&0xffff;
00550 }
00551 else {
00552 R[s0].part3 = lenstr>>16;
00553 R[s0].part4 = lenstr&0xffff;
00554 }
00555
00556
00557
00558
00559
00560 if((iarg+1) < 6) {
00561 memcpy(&R[a0+(iarg+1)], &R[s0], 8);
00562 R[ci].part4++;
00563 }
00564 else {
00565 arg_offset = MPP_STACK_SIZE + (iarg + 1);
00566 store_mpp_word(stack_segment_id, arg_offset, &R[s0]);
00567 }
00568
00569 return AR_STAT_OK;
00570 }
00571
00572 int
00573 ar_pass_arg_value(const ar_data* arg, const AR_TYPE* argtype)
00574 {
00575 int i;
00576 int iarg;
00577 int arg_offset;
00578 AR_IEEE_32 i32;
00579 int status;
00580
00581 numargs++;
00582 iarg = R[ci].part4>>8;
00583 R[ci].part4 += (1<<8);
00584
00585 if(iarg >= MPP_MAX_ARGS)
00586 ar_internal_error(2014, __FILE__, __LINE__);
00587
00588
00589
00590
00591
00592
00593
00594
00595 if(AR_CLASS(*argtype) == AR_CLASS_FLOAT) {
00596 D_roundmode = ROUND_MODE(*argtype);
00597 D_float_32 = (AR_TYPE) (IEEE_FLOAT_32 | (D_roundmode<<3));
00598 D_float_64 = (AR_TYPE) (IEEE_FLOAT_64 | (D_roundmode<<3));
00599 D_float_128 = (AR_TYPE) (IEEE_FLOAT_128 | (D_roundmode<<3));
00600 D_complex_64 = (AR_TYPE) (IEEE_COMPLEX_64 | (D_roundmode<<3));
00601 D_complex_128 = (AR_TYPE) (IEEE_COMPLEX_128 | (D_roundmode<<3));
00602 }
00603
00604 if(arg == NULL)
00605 return AR_STAT_UNDEFINED;
00606
00607
00608
00609
00610
00611
00612 switch (UNROUNDED_TYPE(*argtype)) {
00613
00614 case IEEE_FLOAT_32:
00615 if(iarg >= 6) {
00616 arg_offset = (MPP_STACK_SIZE + iarg) * 8;
00617 return ar_convert_to_float((ar_data*)&stack[arg_offset],
00618 &ieee_float_64,
00619 arg, &ieee_float_32);
00620 }
00621 if(iarg == 5)
00622 R[ci].part4 |= 7;
00623 else
00624 R[ci].part4 = (R[ci].part4|(1<<(7-iarg))) + 1;
00625 return ar_convert_to_float((ar_data*)&F[fa0+iarg],
00626 &ieee_float_64,
00627 arg, &ieee_float_32);
00628
00629 case IEEE_FLOAT_64:
00630 if(iarg >= 6) {
00631 arg_offset = (MPP_STACK_SIZE + iarg) * 8;
00632 memcpy(&stack[arg_offset], arg, 8);
00633 return AR_STAT_OK;
00634 }
00635 if(iarg == 5)
00636 R[ci].part4 |= 7;
00637 else
00638 R[ci].part4 = (R[ci].part4|(1<<(7-iarg))) + 1;
00639 memcpy(&F[fa0+iarg], arg, 8);
00640 return AR_STAT_OK;
00641
00642 case IEEE_FLOAT_128:
00643 case IEEE_COMPLEX_64:
00644 R[ci].part4 += (1<<8);
00645 for(i=0; i<2; i++) {
00646 if((iarg+i) >= 6) {
00647 if((iarg+i) >= MPP_MAX_ARGS)
00648 ar_internal_error(2014, __FILE__, __LINE__);
00649 arg_offset = (MPP_STACK_SIZE + (iarg + i)) * 8;
00650 memcpy(&stack[arg_offset], (AR_INT_64*)arg+i, 8);
00651 }
00652 else {
00653 if((iarg+i) == 5)
00654 R[ci].part4 |= 7;
00655 else
00656 R[ci].part4 = (R[ci].part4|(1<<(7-(iarg+i)))) + 1;
00657 memcpy(&F[fa0+(iarg+i)], (AR_INT_64*)arg+i, 8);
00658 }
00659 }
00660 return AR_STAT_OK;
00661
00662 case IEEE_COMPLEX_32:
00663 R[ci].part4 += (1<<8);
00664 status = AR_STAT_OK;
00665 if(iarg >= (MPP_MAX_ARGS - 1))
00666 ar_internal_error(2014, __FILE__, __LINE__);
00667
00668 i32.sign = arg->ar_cplx_ieee32.rsign;
00669 i32.expo = arg->ar_cplx_ieee32.rexpo;
00670 i32.coeff0 = arg->ar_cplx_ieee32.rcoeff0;
00671 i32.coeff1 = arg->ar_cplx_ieee32.rcoeff1;
00672 if(iarg >= 6) {
00673 arg_offset = (MPP_STACK_SIZE + iarg) * 8;
00674 status |= ar_convert_to_float((ar_data*)&stack[arg_offset],
00675 &ieee_float_64,
00676 &i32, &ieee_float_32);
00677 }
00678 else {
00679 if(iarg == 5)
00680 R[ci].part4 |= 7;
00681 else
00682 R[ci].part4 = (R[ci].part4|(1<<(7-iarg))) + 1;
00683 status |= ar_convert_to_float((ar_data*)&F[fa0+iarg],
00684 &ieee_float_64,
00685 &i32, &ieee_float_32);
00686 }
00687
00688 i32.sign = arg->ar_cplx_ieee32.isign;
00689 i32.expo = arg->ar_cplx_ieee32.iexpo;
00690 i32.coeff0 = arg->ar_cplx_ieee32.icoeff0;
00691 i32.coeff1 = arg->ar_cplx_ieee32.icoeff1;
00692 iarg++;
00693 if(iarg >= 6) {
00694 if(iarg >= MPP_MAX_ARGS)
00695 ar_internal_error(2014, __FILE__, __LINE__);
00696 arg_offset = (MPP_STACK_SIZE + iarg) * 8;
00697 status |= ar_convert_to_float((ar_data*)&stack[arg_offset],
00698 &ieee_float_64,
00699 &i32, &ieee_float_32);
00700 }
00701 else {
00702 if(iarg == 5)
00703 R[ci].part4 |= 7;
00704 else
00705 R[ci].part4 = (R[ci].part4|(1<<(7-iarg))) + 1;
00706 status |= ar_convert_to_float((ar_data*)&F[fa0+iarg],
00707 &ieee_float_64,
00708 &i32, &ieee_float_32);
00709 }
00710
00711 return status;
00712
00713 case IEEE_COMPLEX_128:
00714 R[ci].part4 += (1<<8);
00715 for(i=0; i<4; i++) {
00716 if((iarg+i) >= 6) {
00717 if((iarg+i) >= MPP_MAX_ARGS)
00718 ar_internal_error(2014, __FILE__, __LINE__);
00719 arg_offset = (MPP_STACK_SIZE + (iarg + i)) * 8;
00720 memcpy(&stack[arg_offset], (AR_INT_64*)arg+i, 8);
00721 }
00722 else {
00723 if((iarg+i) == 5)
00724 R[ci].part4 |= 7;
00725 else
00726 R[ci].part4 = (R[ci].part4|(1<<(7-(iarg+i)))) + 1;
00727 memcpy(&F[fa0+(iarg+i)], (AR_INT_64*)arg+i, 8);
00728 }
00729 }
00730 return AR_STAT_OK;
00731
00732 default:
00733 switch (*argtype) {
00734
00735 case AR_Int_32_S:
00736 case AR_Int_46_S:
00737 case AR_Int_64_S:
00738
00739 if(iarg >= 6) {
00740 arg_offset = (MPP_STACK_SIZE + iarg) * 8;
00741 return ar_convert_to_integral((ar_data*)&stack[arg_offset],
00742 &integer_64,
00743 arg, argtype);
00744 }
00745 R[ci].part4++;
00746 return ar_convert_to_integral((ar_data*)&R[a0+iarg],
00747 &integer_64,
00748 arg, argtype);
00749
00750 case AR_Logical:
00751 if(arg->ar_i64.part1 || arg->ar_i64.part2 ||
00752 arg->ar_i64.part3 || arg->ar_i64.part4)
00753 if(iarg >= 6) {
00754 arg_offset = (MPP_STACK_SIZE + iarg) * 8;
00755 memcpy(&stack[arg_offset],
00756 (char*)&AR_const_true, 8);
00757 }
00758 else {
00759 R[ci].part4++;
00760 memcpy(&R[a0+iarg],
00761 (char*)&AR_const_true, 8);
00762 }
00763 else
00764 if(iarg >= 6) {
00765 arg_offset = (MPP_STACK_SIZE + iarg) * 8;
00766 memcpy(&stack[arg_offset],
00767 (char*)&AR_const_false, 8);
00768 }
00769 else {
00770 R[ci].part4++;
00771 memcpy(&R[a0+iarg],
00772 (char*)&AR_const_false, 8);
00773 }
00774 break;
00775
00776 default:
00777 return AR_STAT_INVALID_TYPE;
00778 }
00779 }
00780 }
00781
00782
00783 int
00784 ar_put_real_address(AR_INT_64* extdesc)
00785 {
00786 int segment = extdesc->part2 & 0xff;
00787
00788 if(segment >= n_external_addresses)
00789 return AR_STAT_UNDEFINED;
00790
00791 #if _CRAY
00792 extdesc->part1 = (((long long)external_address[segment]) >> 48) & 0xffff;
00793 extdesc->part2 = (((long long)external_address[segment]) >> 32) & 0xffff;
00794 extdesc->part3 = (((long long)external_address[segment]) >> 16) & 0xffff;
00795 extdesc->part4 = ((long long)external_address[segment]) & 0xffff;
00796 #else
00797 extdesc->part1 = 0;
00798 extdesc->part2 = 0;
00799 extdesc->part3 = (((long)external_address[segment]) >> 16) & 0xffff;
00800 extdesc->part4 = ((long)external_address[segment]) & 0xffff;
00801 #endif
00802
00803 return AR_STAT_OK;
00804 }
00805
00806
00807 int
00808 ar_get_function_value(ar_data *result, AR_TYPE *resulttype)
00809 {
00810 int status;
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824 switch (AR_CLASS(*resulttype)) {
00825
00826 case AR_CLASS_INT:
00827
00828 status = ar_convert_to_integral(result, resulttype,
00829 (ar_data*)&R[v0], &integer_64);
00830 break;
00831
00832 case AR_CLASS_FLOAT:
00833
00834 switch(UNROUNDED_TYPE(*resulttype)) {
00835
00836 case IEEE_FLOAT_32:
00837 case IEEE_FLOAT_64:
00838 status = ar_convert_to_float(result, resulttype,
00839 (ar_data*)&F[fv0], &D_float_64);
00840 break;
00841
00842 case IEEE_FLOAT_128:
00843 status = ar_convert_to_float(result, resulttype,
00844 (ar_data*)&F[fv0], &D_float_128);
00845 break;
00846
00847 case IEEE_COMPLEX_32:
00848 case IEEE_COMPLEX_64:
00849 status = ar_convert_to_complex(result, resulttype,
00850 (ar_data*)&F[fv0], &D_complex_64);
00851 break;
00852
00853 case IEEE_COMPLEX_128:
00854 status = ar_convert_to_complex(result, resulttype,
00855 (ar_data*)&F[fv0], &D_complex_128);
00856 break;
00857
00858 default:
00859 return AR_STAT_INVALID_TYPE;
00860 }
00861 break;
00862
00863 default:
00864 return AR_STAT_INVALID_TYPE;
00865 }
00866 return status &~ AR_ERROR_STATUS;
00867 }
00868
00869 static int
00870 call_host_external(char* func)
00871 {
00872 int status = AR_STAT_UNDEFINED;
00873
00874 if (strncmp(func, "malloc", 6) == 0) {
00875 long length;
00876 char *ptr1;
00877
00878 length = (R[a0].part3<<16) | R[a0].part4;
00879 ptr1 = malloc(length);
00880 status = ar_ext_address(&R[v0], (const char*)ptr1, (length+7)>>3);
00881 }
00882
00883 return status;
00884 }
00885
00886 int
00887 ar_sim(char* intrinsic)
00888 {
00889 char* name;
00890 char* str;
00891
00892 int i,n;
00893 int disp;
00894 int sign;
00895
00896 long pc;
00897 unsigned long p1,p2;
00898 int op;
00899 int ra,rb,rc;
00900 int func;
00901 long rtc, rtcpc;
00902 i64_union iu64;
00903
00904 long offset;
00905 long value;
00906 int status;
00907
00908 AR_INT_64 int64;
00909 AR_INT_64 reg64;
00910
00911 AR_IEEE_64 *rr, *oa, *ob;
00912
00913 AR_TYPE ar_type;
00914
00915 static AR_HOST_UINT64 SSIB[7] = {
00916
00917 (((AR_HOST_UINT64) 0x00000002) << 32) |
00918 ((AR_HOST_UINT64) 0x00080528),
00919
00920 0,
00921 0,
00922 0,
00923 0,
00924
00925 (((AR_HOST_UINT64) 0x41524954) << 32) |
00926 ((AR_HOST_UINT64) 0x48000000),
00927 0
00928 };
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939 if(R[ci].part4 == 0)
00940 ar_internal_error(2014, __FILE__, __LINE__);
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953 R[sp].part1 = R[fp].part1 = 0;
00954 R[sp].part2 = R[fp].part2 = stack_segment_id;
00955
00956 R[sp].part3 = (MPP_STACK_SIZE*8)>>16;
00957 R[sp].part4 = (MPP_STACK_SIZE*8)&0xffff;
00958
00959 if(ar_mach_type == T3D) {
00960 R[fp].part3 = (MPP_STACK_SIZE*8)>>16;
00961 R[fp].part4 = (MPP_STACK_SIZE*8)&0xffff;
00962 }
00963 else {
00964 AR_INT_64 SSIB_ia;
00965
00966 # define T3E_DSIB_LOC (MPP_STACK_SIZE + (MPP_MAX_ARGS * 5))
00967
00968 R[fp].part3 = ((T3E_DSIB_LOC + MPP_DSIB_SIZE) * 8) >> 16;
00969 R[fp].part4 = ((T3E_DSIB_LOC + MPP_DSIB_SIZE) * 8) & 0xffff;
00970
00971 SSIB[6] = (numargs << 52) |
00972 (((AR_HOST_UINT64) (R[ci].part4 >> 8)) << 32) |
00973 (R[ci].part4 & 0xff);
00974
00975 R[ci].part1 = R[ci].part2 = R[ci].part3 = 0;
00976 R[ci].part4 = 6;
00977
00978 if (ar_ext_address(&SSIB_ia, (char*) &SSIB, (sizeof(SSIB) >> 3)) !=
00979 AR_STAT_OK) {
00980 ar_internal_error(2012, __FILE__, __LINE__);
00981 }
00982 store_mpp_word(stack_segment_id, (T3E_DSIB_LOC + 2), &SSIB_ia);
00983
00984 # undef T3E_DSIB_LOC
00985 }
00986
00987 ZERO64(R[ret]);
00988
00989 ZERO64(R[zero]);
00990 ZERO64(F[fzero]);
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006 R[s0].part1 = R[s0].part2 = R[s0].part3 = 0;
01007 R[s0].part4 = ar_sim_version;
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020 name = (char*)&R[v0];
01021 for(i=0; i<8 && isalnum(intrinsic[i]); i++)
01022 name[i] = toupper(intrinsic[i]);
01023 while(i < 8)
01024 name[i++] = 0;
01025
01026 pc = 0;
01027 rtcpc = 0;
01028 status = AR_STAT_OK;
01029 while(status == AR_STAT_OK) {
01030
01031 DISASM1("0x%6.6x\t", pc);
01032 if(pc&4) {
01033 #if _CRAY
01034 p1 = *(((unsigned long*)code)+(pc>>3)) >> 48;
01035 p2 = (*(((unsigned long*)code)+(pc>>3)) >> 32) & 0xffff;
01036 #else
01037 p1 = (code[pc-4]<<8) | code[pc-3];
01038 p2 = (code[pc-2]<<8) | code[pc-1];
01039 #endif
01040 }
01041 else {
01042 #if _CRAY
01043 p1 = (*(((unsigned long*)code)+(pc>>3)) >> 16) & 0xffff;
01044 p2 = *(((unsigned long*)code)+(pc>>3)) & 0xffff;
01045 #else
01046 p1 = (code[pc+4]<<8) | code[pc+5];
01047 p2 = (code[pc+6]<<8) | code[pc+7];
01048 #endif
01049 }
01050 pc += 4;
01051 op = p1>>10;
01052 ra = (p1>>5)&037;
01053 rb = p1&037;
01054 func = (p2>>5)&03777;
01055 rc = p2&037;
01056
01057 switch(op) {
01058
01059 case 0x00:
01060 status = R[v0].part1 | R[v0].part2 | R[v0].part3 | R[v0].part4;
01061 DISASM2("CALL_PAL(0x%7.7x)\t0x%4.4x\n", p1<<16 | p2, status);
01062 switch (status) {
01063 case IFACEERR:
01064 ar_internal_error(2014, __FILE__, __LINE__);
01065 status = AR_STAT_UNDEFINED;
01066 break;
01067 case NOINTRIN:
01068 str=(char*)&R[v0];
01069 PRINTMSG(0, 2015, Internal, 0, __FILE__, __LINE__, intrinsic, "");
01070 status = AR_STAT_UNDEFINED;
01071 break;
01072 case EXTERROR:
01073 ar_internal_error(2012, __FILE__, __LINE__);
01074 case ARITHERR:
01075 status = AR_STAT_UNDEFINED;
01076 break;
01077 case SETERRNO:
01078 errno = ERANGE;
01079 status = AR_STAT_OVERFLOW;
01080 pc = 0;
01081 break;
01082 case HOSTEXT:
01083 status = call_host_external((char*)&R[t1]);
01084 pc = ((R[ret].part3<<16)|R[ret].part4) &~ 3;
01085 break;
01086 default:
01087 status = BADINSTR;
01088 }
01089 break;
01090
01091 case 0x19:
01092 case 0x1b:
01093 case 0x1d:
01094 case 0x1e:
01095 case 0x1f:
01096 status = BADINSTR;
01097 DISASM2("CALL_PAL(0x%7.7x)\t0x%4.4x\n", p1<<16 | p2, status);
01098 break;
01099
01100 case 0x01:
01101 case 0x02:
01102 case 0x03:
01103 case 0x04:
01104 case 0x05:
01105 case 0x06:
01106 case 0x07:
01107 case 0x0a:
01108 case 0x0c:
01109 case 0x0d:
01110 case 0x0e:
01111 case 0x14:
01112 case 0x1c:
01113 status = BADINSTR;
01114 DISASM5("%x.%x.%x.%x.%x\n", op, ra, rb, func, rc);
01115 break;
01116
01117 case 0x08:
01118 if(ra != zero) {
01119 reg64.part4 = p2;
01120 if(p2>>15)
01121 reg64.part1 = reg64.part2 = reg64.part3 = 0xffff;
01122 else
01123 reg64.part1 = reg64.part2 = reg64.part3 = 0;
01124 ADD64(R[ra], reg64, R[rb]);
01125 }
01126 DISASM5("LDA\t%s,0x%4.4x(%s)\t0x%8.8x %8.8x\n",
01127 RN[ra], p2, RN[rb],
01128 (R[ra].part1<<16) | R[ra].part2,
01129 (R[ra].part3<<16) | R[ra].part4);
01130 break;
01131
01132 case 0x09:
01133 if(ra != zero) {
01134 reg64.part3 = p2;
01135 reg64.part4 = 0;
01136 if(p2>>15)
01137 reg64.part1 = reg64.part2 = 0xffff;
01138 else
01139 reg64.part1 = reg64.part2 = 0;
01140 ADD64(R[ra], reg64, R[rb]);
01141 }
01142 DISASM5("LDAH\t%s,0x%4.4x(%s)\t0x%8.8x %8.8x\n",
01143 RN[ra], p2, RN[rb],
01144 (R[ra].part1<<16) | R[ra].part2,
01145 (R[ra].part3<<16) | R[ra].part4);
01146 break;
01147
01148 case 0x0b:
01149 if(ra != zero) {
01150 reg64.part4 = p2;
01151 if(p2>>15)
01152 reg64.part1 = reg64.part2 = reg64.part3 = 0xffff;
01153 else
01154 reg64.part1 = reg64.part2 = reg64.part3 = 0;
01155 ADD64(reg64, reg64, R[rb]);
01156 offset = ((reg64.part3<<16) | reg64.part4) >> 3;
01157 load_mpp_word(&R[ra], reg64.part2&0xff, offset);
01158 }
01159 DISASM5("LDQ_U\t%s,0x%4.4x(%s)\t0x%8.8x %8.8x\n",
01160 RN[ra], p2, RN[rb],
01161 (R[ra].part1<<16) | R[ra].part2,
01162 (R[ra].part3<<16) | R[ra].part4);
01163 break;
01164
01165 case 0x0f:
01166 reg64.part4 = p2;
01167 if(p2>>15)
01168 reg64.part1 = reg64.part2 = reg64.part3 = 0xffff;
01169 else
01170 reg64.part1 = reg64.part2 = reg64.part3 = 0;
01171 ADD64(reg64, reg64, R[rb]);
01172 offset = ((reg64.part3<<16) | reg64.part4) >> 3;
01173 store_mpp_word(reg64.part2&0xff, offset, &R[ra]);
01174 DISASM3("STQ_U\t%s,0x%4.4x(%s)\n", RN[ra], p2, RN[rb]);
01175 break;
01176
01177 case 0x10:
01178 if(func&0x80) {
01179 reg64.part1 = reg64.part2 = reg64.part3 = 0;
01180 reg64.part4 = (rb<<3)|(func>>8);
01181 }
01182 else
01183 COPY64(reg64, R[rb]);
01184 switch(func&0x7f) {
01185 case 0x00:
01186 DISASM0("ADDL\t");
01187 ADD64(R[rc], R[ra], reg64);
01188 if(R[rc].part3>>15)
01189 R[rc].part1 = R[rc].part2 = 0xffff;
01190 else
01191 R[rc].part1 = R[rc].part2 = 0;
01192 break;
01193 case 0x02:
01194 DISASM0("S4ADDL\t");
01195 COPY64(int64, R[ra]);
01196 SHLEFT64N(int64, 2);
01197 ADD64(R[rc], int64, reg64);
01198 if(R[rc].part3>>15)
01199 R[rc].part1 = R[rc].part2 = 0xffff;
01200 else
01201 R[rc].part1 = R[rc].part2 = 0;
01202 break;
01203 case 0x09:
01204 DISASM0("SUBL\t");
01205 NEG64(reg64);
01206 ADD64(R[rc], R[ra], reg64);
01207 if(R[rc].part3>>15)
01208 R[rc].part1 = R[rc].part2 = 0xffff;
01209 else
01210 R[rc].part1 = R[rc].part2 = 0;
01211 break;
01212 case 0x0b:
01213 DISASM0("S4SUBL\t");
01214 COPY64(int64, R[ra]);
01215 SHLEFT64N(int64, 2);
01216 NEG64(reg64);
01217 ADD64(R[rc], int64, reg64);
01218 if(R[rc].part3>>15)
01219 R[rc].part1 = R[rc].part2 = 0xffff;
01220 else
01221 R[rc].part1 = R[rc].part2 = 0;
01222 break;
01223 case 0x0f:
01224 DISASM0("CMPBGE\t");
01225 value = 0;
01226 if((R[ra].part1>>8) >= (reg64.part1>>8))
01227 value |= 1<<7;
01228 if((R[ra].part1&0xff) >= (reg64.part1&0xff))
01229 value |= 1<<6;
01230 if((R[ra].part2>>8) >= (reg64.part2>>8))
01231 value |= 1<<5;
01232 if((R[ra].part2&0xff) >= (reg64.part2&0xff))
01233 value |= 1<<4;
01234 if((R[ra].part3>>8) >= (reg64.part3>>8))
01235 value |= 1<<3;
01236 if((R[ra].part3&0xff) >= (reg64.part3&0xff))
01237 value |= 1<<2;
01238 if((R[ra].part4>>8) >= (reg64.part4>>8))
01239 value |= 1<<1;
01240 if((R[ra].part4&0xff) >= (reg64.part4&0xff))
01241 value |= 1;
01242 R[rc].part1 = R[rc].part2 = R[rc].part3 = 0;
01243 R[rc].part4 = value;
01244 break;
01245 case 0x12:
01246 DISASM0("S8ADDL\t");
01247 COPY64(int64, R[ra]);
01248 SHLEFT64N(int64, 3);
01249 ADD64(R[rc], int64, reg64);
01250 if(R[rc].part3>>15)
01251 R[rc].part1 = R[rc].part2 = 0xffff;
01252 else
01253 R[rc].part1 = R[rc].part2 = 0;
01254 break;
01255 case 0x1b:
01256 DISASM0("S8SUBL\t");
01257 COPY64(int64, R[ra]);
01258 SHLEFT64N(int64, 3);
01259 NEG64(reg64);
01260 ADD64(R[rc], int64, reg64);
01261 if(R[rc].part3>>15)
01262 R[rc].part1 = R[rc].part2 = 0xffff;
01263 else
01264 R[rc].part1 = R[rc].part2 = 0;
01265 break;
01266 case 0x1d:
01267 DISASM0("CMPULT\t");
01268 value = 0;
01269 if(R[ra].part1 < reg64.part1)
01270 value = 1;
01271 else if(R[ra].part1 == reg64.part1)
01272 if(R[ra].part2 < reg64.part2)
01273 value = 1;
01274 else if(R[ra].part2 == reg64.part2)
01275 if(R[ra].part3 < reg64.part3)
01276 value = 1;
01277 else if(R[ra].part3 == reg64.part3)
01278 if(R[ra].part4 < reg64.part4)
01279 value = 1;
01280 R[rc].part1 = R[rc].part2 = R[rc].part3 = 0;
01281 R[rc].part4 = value;
01282 break;
01283 case 0x20:
01284 DISASM0("ADDQ\t");
01285 ADD64(R[rc], R[ra], reg64);
01286 break;
01287 case 0x22:
01288 DISASM0("S4ADDQ\t");
01289 COPY64(int64, R[ra]);
01290 SHLEFT64N(int64, 2);
01291 ADD64(R[rc], int64, reg64);
01292 break;
01293 case 0x29:
01294 DISASM0("SUBQ\t");
01295 NEG64(reg64);
01296 ADD64(R[rc], R[ra], reg64);
01297 break;
01298 case 0x2b:
01299 DISASM0("S4SUBQ\t");
01300 COPY64(int64, R[ra]);
01301 SHLEFT64N(int64, 2);
01302 NEG64(reg64);
01303 ADD64(R[rc], int64, reg64);
01304 break;
01305 case 0x2d:
01306 DISASM0("CMPEQ\t");
01307 value = 0;
01308 if(R[ra].part1 == reg64.part1)
01309 if(R[ra].part2 == reg64.part2)
01310 if(R[ra].part3 == reg64.part3)
01311 if(R[ra].part4 == reg64.part4)
01312 value = 1;
01313 R[rc].part1 = R[rc].part2 = R[rc].part3 = 0;
01314 R[rc].part4 = value;
01315 break;
01316 case 0x32:
01317 DISASM0("S8ADDQ\t");
01318 COPY64(int64, R[ra]);
01319 SHLEFT64N(int64, 3);
01320 ADD64(R[rc], int64, reg64);
01321 break;
01322 case 0x3b:
01323 DISASM0("S8SUBQ\t");
01324 COPY64(int64, R[ra]);
01325 SHLEFT64N(int64, 3);
01326 NEG64(reg64);
01327 ADD64(R[rc], int64, reg64);
01328 break;
01329 case 0x3d:
01330 DISASM0("CMPULE\t");
01331 value = 0;
01332 if(R[ra].part1 < reg64.part1)
01333 value = 1;
01334 else if(R[ra].part1 == reg64.part1)
01335 if(R[ra].part2 < reg64.part2)
01336 value = 1;
01337 else if(R[ra].part2 == reg64.part2)
01338 if(R[ra].part3 < reg64.part3)
01339 value = 1;
01340 else if(R[ra].part3 == reg64.part3)
01341 if(R[ra].part4 <= reg64.part4)
01342 value = 1;
01343 R[rc].part1 = R[rc].part2 = R[rc].part3 = 0;
01344 R[rc].part4 = value;
01345 break;
01346 case 0x4d:
01347 DISASM0("CMPLT\t");
01348 NEG64(reg64);
01349 ADD64(reg64, R[ra], reg64);
01350 R[rc].part1 = R[rc].part2 = R[rc].part3 = 0;
01351 R[rc].part4 = reg64.part1>>15;
01352 break;
01353 case 0x6d:
01354 DISASM0("CMPLE\t");
01355 NEG64(reg64);
01356 ADD64(reg64, R[ra], reg64);
01357 R[rc].part1 = R[rc].part2 = R[rc].part3 = 0;
01358 R[rc].part4 = reg64.part1>>15;
01359 if(R[rc].part4 == 0)
01360 if((reg64.part1|reg64.part2|reg64.part3|reg64.part4) == 0)
01361 R[rc].part4 = 1;
01362 break;
01363 default:
01364 status = BADINSTR;
01365 DISASM5("%x.%x.%x.%x.%x\n", op, ra, rb, func, rc);
01366 }
01367 if(func&0x80) {
01368 DISASM5("%s,0x%2.2x,%s\t0x%8.8x %8.8x\n",
01369 RN[ra], (rb<<3)|(func>>8), RN[rc],
01370 (R[rc].part1<<16) | R[rc].part2,
01371 (R[rc].part3<<16) | R[rc].part4);
01372 }
01373 else {
01374 DISASM5("%s,%s,%s\t0x%8.8x %8.8x\n",
01375 RN[ra], RN[rb], RN[rc],
01376 (R[rc].part1<<16) | R[rc].part2,
01377 (R[rc].part3<<16) | R[rc].part4);
01378 }
01379 break;
01380
01381 case 0x11:
01382 if(func&0x80) {
01383 reg64.part1 = reg64.part2 = reg64.part3 = 0;
01384 reg64.part4 = (rb<<3)|(func>>8);
01385 }
01386 else
01387 COPY64(reg64, R[rb]);
01388 switch(func&0x7f) {
01389 case 0x00:
01390 DISASM0("AND\t");
01391 R[rc].part1 = R[ra].part1®64.part1;
01392 R[rc].part2 = R[ra].part2®64.part2;
01393 R[rc].part3 = R[ra].part3®64.part3;
01394 R[rc].part4 = R[ra].part4®64.part4;
01395 break;
01396 case 0x08:
01397 DISASM0("BIC\t");
01398 R[rc].part1 = R[ra].part1&~reg64.part1;
01399 R[rc].part2 = R[ra].part2&~reg64.part2;
01400 R[rc].part3 = R[ra].part3&~reg64.part3;
01401 R[rc].part4 = R[ra].part4&~reg64.part4;
01402 break;
01403 case 0x20:
01404 DISASM0("BIS\t");
01405 R[rc].part1 = R[ra].part1|reg64.part1;
01406 R[rc].part2 = R[ra].part2|reg64.part2;
01407 R[rc].part3 = R[ra].part3|reg64.part3;
01408 R[rc].part4 = R[ra].part4|reg64.part4;
01409 break;
01410 case 0x14:
01411 DISASM0("CMOVLBS\t");
01412 if(R[ra].part4&1)
01413 COPY64(R[rc], reg64);
01414 break;
01415 case 0x16:
01416 DISASM0("CMOVLBC\t");
01417 if((R[ra].part4&1) == 0)
01418 COPY64(R[rc], reg64);
01419 break;
01420 case 0x24:
01421 DISASM0("CMOVEQ\t");
01422 if((R[ra].part1|R[ra].part2|R[ra].part3|R[ra].part4) == 0)
01423 COPY64(R[rc], reg64);
01424 break;
01425 case 0x26:
01426 DISASM0("CMOVNE\t");
01427 if((R[ra].part1|R[ra].part2|R[ra].part3|R[ra].part4) != 0)
01428 COPY64(R[rc], reg64);
01429 break;
01430 case 0x28:
01431 DISASM0("ORNOT\t");
01432 R[rc].part1 = R[ra].part1|~reg64.part1;
01433 R[rc].part2 = R[ra].part2|~reg64.part2;
01434 R[rc].part3 = R[ra].part3|~reg64.part3;
01435 R[rc].part4 = R[ra].part4|~reg64.part4;
01436 break;
01437 case 0x40:
01438 DISASM0("XOR\t");
01439 R[rc].part1 = R[ra].part1^reg64.part1;
01440 R[rc].part2 = R[ra].part2^reg64.part2;
01441 R[rc].part3 = R[ra].part3^reg64.part3;
01442 R[rc].part4 = R[ra].part4^reg64.part4;
01443 break;
01444 case 0x44:
01445 DISASM0("CMOVLT\t");
01446 if(R[ra].part1>>15)
01447 COPY64(R[rc], reg64);
01448 break;
01449 case 0x46:
01450 DISASM0("CMOVGE\t");
01451 if((R[ra].part1>>15) == 0)
01452 COPY64(R[rc], reg64);
01453 break;
01454 case 0x48:
01455 DISASM0("EQV\t");
01456 R[rc].part1 = R[ra].part1^~reg64.part1;
01457 R[rc].part2 = R[ra].part2^~reg64.part2;
01458 R[rc].part3 = R[ra].part3^~reg64.part3;
01459 R[rc].part4 = R[ra].part4^~reg64.part4;
01460 break;
01461 case 0x64:
01462 DISASM0("CMOVLE\t");
01463 if(R[ra].part1>>15)
01464 COPY64(R[rc], reg64);
01465 else if((R[ra].part1|R[ra].part2|R[ra].part3|R[ra].part4) == 0)
01466 COPY64(R[rc], reg64);
01467 break;
01468 case 0x66:
01469 DISASM0("CMOVGT\t");
01470 if((R[ra].part1>>15) == 0)
01471 if((R[ra].part1|R[ra].part2|R[ra].part3|R[ra].part4) != 0)
01472 COPY64(R[rc], reg64);
01473 break;
01474 default:
01475 status = BADINSTR;
01476 DISASM5("%x.%x.%x.%x.%x\n", op, ra, rb, func, rc);
01477 }
01478 if(rc == zero)
01479 ZERO64(R[zero]);
01480 if(func&0x80) {
01481 DISASM5("%s,0x%2.2x,%s\t0x%8.8x %8.8x\n",
01482 RN[ra], (rb<<3)|(func>>8), RN[rc],
01483 (R[rc].part1<<16) | R[rc].part2,
01484 (R[rc].part3<<16) | R[rc].part4);
01485 }
01486 else {
01487 DISASM5("%s,%s,%s\t0x%8.8x %8.8x\n",
01488 RN[ra], RN[rb], RN[rc],
01489 (R[rc].part1<<16) | R[rc].part2,
01490 (R[rc].part3<<16) | R[rc].part4);
01491 }
01492 break;
01493
01494 case 0x12:
01495 value = (func&0x80) ? ((rb<<3)|(func>>8)) : R[rb].part4;
01496 switch(func&0x7f) {
01497 case 0x02:
01498 DISASM0("MSKBL\t");
01499 value = (ar_mach_type == T3D) ? (value&0x7) : ((value&0x7)^0x7);
01500 reg64.part1 = reg64.part2 = reg64.part3 = 0;
01501 reg64.part4 = 0xff;
01502 SHLEFT64N(reg64, value<<3);
01503 R[rc].part1 = R[ra].part1 &~ reg64.part1;
01504 R[rc].part2 = R[ra].part2 &~ reg64.part2;
01505 R[rc].part3 = R[ra].part3 &~ reg64.part3;
01506 R[rc].part4 = R[ra].part4 &~ reg64.part4;
01507 break;
01508 case 0x06:
01509 DISASM0("EXTBL\t");
01510 value = (ar_mach_type == T3D) ? (value&0x7) : ((value&0x7)^0x7);
01511 if(ra != rc)
01512 COPY64(R[rc], R[ra]);
01513 SHRIGHT64N(R[rc], value<<3);
01514 R[rc].part1 = R[rc].part2 = R[rc].part3 = 0;
01515 R[rc].part4 &= 0xff;
01516 break;
01517 case 0x0b:
01518 DISASM0("INSBL\t");
01519 value = (ar_mach_type == T3D) ? (value&0x7) : ((value&0x7)^0x7);
01520 if(ra != rc)
01521 COPY64(R[rc], R[ra]);
01522 R[rc].part1 = R[rc].part2 = R[rc].part3 = 0;
01523 R[rc].part4 &= 0xff;
01524 SHLEFT64N(R[rc], value<<3);
01525 break;
01526 case 0x12:
01527 DISASM0("MSKWL\t");
01528 value = (ar_mach_type == T3D) ? (value&0x7) : ((value&0x7)^0x7);
01529 reg64.part1 = reg64.part2 = reg64.part3 = 0;
01530 reg64.part4 = 0xffff;
01531 SHLEFT64N(reg64, value<<3);
01532 R[rc].part1 = R[ra].part1 &~ reg64.part1;
01533 R[rc].part2 = R[ra].part2 &~ reg64.part2;
01534 R[rc].part3 = R[ra].part3 &~ reg64.part3;
01535 R[rc].part4 = R[ra].part4 &~ reg64.part4;
01536 break;
01537 case 0x16:
01538 DISASM0("EXTWL\t");
01539 value = (ar_mach_type == T3D) ? (value&0x7) : ((value&0x7)^0x7);
01540 if(ra != rc)
01541 COPY64(R[rc], R[ra]);
01542 SHRIGHT64N(R[rc], value<<3);
01543 R[rc].part1 = R[rc].part2 = R[rc].part3 = 0;
01544 break;
01545 case 0x1b:
01546 DISASM0("INSWL\t");
01547 value = (ar_mach_type == T3D) ? (value&0x7) : ((value&0x7)^0x7);
01548 if(ra != rc)
01549 COPY64(R[rc], R[ra]);
01550 R[rc].part1 = R[rc].part2 = R[rc].part3 = 0;
01551 SHLEFT64N(R[rc], value<<3);
01552 break;
01553 case 0x22:
01554 DISASM0("MSKHL\t");
01555 value = (ar_mach_type == T3D) ? (value&0x7) : ((value&0x7)^0x7);
01556 reg64.part1 = reg64.part2 = 0;
01557 reg64.part3 = reg64.part4 = 0xffff;
01558 SHLEFT64N(reg64, value<<3);
01559 R[rc].part1 = R[ra].part1 &~ reg64.part1;
01560 R[rc].part2 = R[ra].part2 &~ reg64.part2;
01561 R[rc].part3 = R[ra].part3 &~ reg64.part3;
01562 R[rc].part4 = R[ra].part4 &~ reg64.part4;
01563 break;
01564 case 0x26:
01565 DISASM0("EXTLL\t");
01566 value = (ar_mach_type == T3D) ? (value&0x7) : ((value&0x7)^0x7);
01567 if(ra != rc)
01568 COPY64(R[rc], R[ra]);
01569 SHRIGHT64N(R[rc], value<<3);
01570 R[rc].part1 = R[rc].part2 = 0;
01571 break;
01572 case 0x2b:
01573 DISASM0("INSLL\t");
01574 value = (ar_mach_type == T3D) ? (value&0x7) : ((value&0x7)^0x7);
01575 if(ra != rc)
01576 COPY64(R[rc], R[ra]);
01577 R[rc].part1 = R[rc].part2 = 0;
01578 SHLEFT64N(R[rc], value<<3);
01579 break;
01580 case 0x30:
01581 DISASM0("ZAP\t");
01582 COPY64(R[rc], R[ra]);
01583 for(i=0; i<=7; i++)
01584 if(value&(1<<i))
01585 memset((char*)(&R[rc])+7-i, 0, 1);
01586 break;
01587 case 0x31:
01588 DISASM0("ZAPNOT\t");
01589 COPY64(R[rc], R[ra]);
01590 for(i=0; i<=7; i++)
01591 if(!(value&(1<<i)))
01592 memset((char*)(&R[rc])+7-i, 0, 1);
01593 break;
01594 case 0x32:
01595 DISASM0("MSKQL\t");
01596 value = (ar_mach_type == T3D) ? (value&0x7) : ((value&0x7)^0x7);
01597 reg64.part1 = reg64.part2 = reg64.part3 = reg64.part4 = 0xffff;
01598 SHLEFT64N(reg64, value<<3);
01599 R[rc].part1 = R[ra].part1 &~ reg64.part1;
01600 R[rc].part2 = R[ra].part2 &~ reg64.part2;
01601 R[rc].part3 = R[ra].part3 &~ reg64.part3;
01602 R[rc].part4 = R[ra].part4 &~ reg64.part4;
01603 break;
01604 case 0x34:
01605 DISASM0("SRL\t");
01606 if(ra != rc)
01607 COPY64(R[rc], R[ra]);
01608 SHRIGHT64N(R[rc], value&077);
01609 break;
01610 case 0x36:
01611 DISASM0("EXTQL\t");
01612 value = (ar_mach_type == T3D) ? (value&0x7) : ((value&0x7)^0x7);
01613 if(ra != rc)
01614 COPY64(R[rc], R[ra]);
01615 SHRIGHT64N(R[rc], value<<3);
01616 break;
01617 case 0x39:
01618 DISASM0("SLL\t");
01619 if(ra != rc)
01620 COPY64(R[rc], R[ra]);
01621 SHLEFT64N(R[rc], value&077);
01622 break;
01623 case 0x3b:
01624 DISASM0("INSQL\t");
01625 value = (ar_mach_type == T3D) ? (value&0x7) : ((value&0x7)^0x7);
01626 if(ra != rc)
01627 COPY64(R[rc], R[ra]);
01628 SHLEFT64N(R[rc], value<<3);
01629 break;
01630 case 0x3c:
01631 DISASM0("SRA\t");
01632 if(ra != rc)
01633 COPY64(R[rc], R[ra]);
01634 if(R[rc].part1>>15) {
01635 NOT64(R[rc]);
01636 SHRIGHT64N(R[rc], value&077);
01637 NOT64(R[rc]);
01638 }
01639 else
01640 SHRIGHT64N(R[rc], value&077);
01641 break;
01642 case 0x52:
01643 DISASM0("MSKWH\t");
01644 value = (ar_mach_type == T3D) ? (value&0x7) : ((value&0x7)^0x7);
01645 reg64.part1 = reg64.part2 = reg64.part3 = 0;
01646 reg64.part4 = 0xffff;
01647 SHRIGHT64N(reg64, 64-(value<<3));
01648 R[rc].part1 = R[ra].part1 &~ reg64.part1;
01649 R[rc].part2 = R[ra].part2 &~ reg64.part2;
01650 R[rc].part3 = R[ra].part3 &~ reg64.part3;
01651 R[rc].part4 = R[ra].part4 &~ reg64.part4;
01652 break;
01653 case 0x57:
01654 DISASM0("INSWH\t");
01655 value = (ar_mach_type == T3D) ? (value&0x7) : ((value&0x7)^0x7);
01656 if(ra != rc)
01657 COPY64(R[rc], R[ra]);
01658 R[rc].part1 = R[rc].part2 = R[rc].part3 = 0;
01659 SHRIGHT64N(R[rc], 64-(value<<3));
01660 break;
01661 case 0x5a:
01662 DISASM0("EXTWH\t");
01663 value = (ar_mach_type == T3D) ? (value&0x7) : ((value&0x7)^0x7);
01664 if(ra != rc)
01665 COPY64(R[rc], R[ra]);
01666 SHLEFT64N(R[rc], (64-(value<<3))&077);
01667 R[rc].part2 = R[rc].part3 = R[rc].part4 = 0;
01668 break;
01669 case 0x62:
01670 DISASM0("MSKLH\t");
01671 value = (ar_mach_type == T3D) ? (value&0x7) : ((value&0x7)^0x7);
01672 reg64.part1 = reg64.part2 = 0;
01673 reg64.part3 = reg64.part4 = 0xffff;
01674 SHRIGHT64N(reg64, 64-(value<<3));
01675 R[rc].part1 = R[ra].part1 &~ reg64.part1;
01676 R[rc].part2 = R[ra].part2 &~ reg64.part2;
01677 R[rc].part3 = R[ra].part3 &~ reg64.part3;
01678 R[rc].part4 = R[ra].part4 &~ reg64.part4;
01679 break;
01680 case 0x67:
01681 DISASM0("INSLH\t");
01682 value = (ar_mach_type == T3D) ? (value&0x7) : ((value&0x7)^0x7);
01683 if(ra != rc)
01684 COPY64(R[rc], R[ra]);
01685 R[rc].part1 = R[rc].part2 = 0;
01686 SHRIGHT64N(R[rc], 64-(value<<3));
01687 break;
01688 case 0x6a:
01689 DISASM0("EXTLH\t");
01690 value = (ar_mach_type == T3D) ? (value&0x7) : ((value&0x7)^0x7);
01691 if(ra != rc)
01692 COPY64(R[rc], R[ra]);
01693 SHLEFT64N(R[rc], (64-(value<<3))&077);
01694 R[rc].part3 = R[rc].part4 = 0;
01695 break;
01696 case 0x72:
01697 DISASM0("MSKQH\t");
01698 value = (ar_mach_type == T3D) ? (value&0x7) : ((value&0x7)^0x7);
01699 reg64.part1 = reg64.part2 = reg64.part3 = reg64.part4 = 0xffff;
01700 SHRIGHT64N(reg64, 64-(value<<3));
01701 R[rc].part1 = R[ra].part1 &~ reg64.part1;
01702 R[rc].part2 = R[ra].part2 &~ reg64.part2;
01703 R[rc].part3 = R[ra].part3 &~ reg64.part3;
01704 R[rc].part4 = R[ra].part4 &~ reg64.part4;
01705 break;
01706 case 0x77:
01707 DISASM0("INSQH\t");
01708 value = (ar_mach_type == T3D) ? (value&0x7) : ((value&0x7)^0x7);
01709 if(ra != rc)
01710 COPY64(R[rc], R[ra]);
01711 SHRIGHT64N(R[rc], 64-(value<<3));
01712 break;
01713 case 0x7a:
01714 DISASM0("EXTQH\t");
01715 value = (ar_mach_type == T3D) ? (value&0x7) : ((value&0x7)^0x7);
01716 if(ra != rc)
01717 COPY64(R[rc], R[ra]);
01718 SHLEFT64N(R[rc], (64-(value<<3))&077);
01719 break;
01720 default:
01721 status = BADINSTR;
01722 DISASM5("%x.%x.%x.%x.%x\n", op, ra, rb, func, rc);
01723 }
01724 if(rc == zero)
01725 ZERO64(R[zero]);
01726 if(func&0x80) {
01727 DISASM5("%s,0x%2.2x,%s\t0x%8.8x %8.8x\n",
01728 RN[ra], (rb<<3)|(func>>8), RN[rc],
01729 (R[rc].part1<<16) | R[rc].part2,
01730 (R[rc].part3<<16) | R[rc].part4);
01731 }
01732 else {
01733 DISASM5("%s,%s,%s\t0x%8.8x %8.8x\n",
01734 RN[ra], RN[rb], RN[rc],
01735 (R[rc].part1<<16) | R[rc].part2,
01736 (R[rc].part3<<16) | R[rc].part4);
01737 }
01738 break;
01739
01740 case 0x13:
01741 if(func&0x80) {
01742 reg64.part1 = reg64.part2 = reg64.part3 = 0;
01743 reg64.part4 = (rb<<3)|(func>>8);
01744 sign = 0;
01745 }
01746 else
01747 COPY64(reg64, R[rb]);
01748 COPY64(int64, R[ra]);
01749 ZERO64(R[rc]);
01750 switch(func&0x7f) {
01751 case 0x00:
01752 DISASM0("MULL\t");
01753 if(reg64.part1>>15) {
01754 NEG64(reg64);
01755 sign = 1;
01756 }
01757 else
01758 sign = 0;
01759 if(int64.part1>>15) {
01760 NEG64(int64);
01761 sign ^= 1;
01762 }
01763 reg64.part1 = reg64.part2 = 0;
01764 int64.part1 = int64.part2 = 0;
01765 while(reg64.part3|reg64.part4) {
01766 if(reg64.part4&1)
01767 ADD64(R[rc],R[rc],int64);
01768 SHLEFT64(int64);
01769 SHRIGHT64(reg64);
01770 }
01771 R[rc].part1 = R[rc].part2 = 0;
01772 if(sign)
01773 NEG64(R[rc]);
01774 break;
01775 case 0x20:
01776 DISASM0("MULQ\t");
01777 if(reg64.part1>>15) {
01778 NEG64(reg64);
01779 sign = 1;
01780 }
01781 else
01782 sign = 0;
01783 if(int64.part1>>15) {
01784 NEG64(int64);
01785 sign ^= 1;
01786 }
01787 while(reg64.part1|reg64.part2|reg64.part3|reg64.part4) {
01788 if(reg64.part4&1)
01789 ADD64(R[rc],R[rc],int64);
01790 SHLEFT64(int64);
01791 SHRIGHT64(reg64);
01792 }
01793 if(sign)
01794 NEG64(R[rc]);
01795 break;
01796 case 0x30:
01797 DISASM0("UMULH\t");
01798 n = 64;
01799 while(reg64.part1|reg64.part2|reg64.part3|reg64.part4) {
01800 if(reg64.part4&1)
01801 ADD64(R[rc],R[rc],int64);
01802 SHRIGHT64(R[rc]);
01803 SHRIGHT64(reg64);
01804 n--;
01805 }
01806 SHRIGHT64N(R[rc], n);
01807 break;
01808 default:
01809 status = BADINSTR;
01810 DISASM5("%x.%x.%x.%x.%x\n", op, ra, rb, func, rc);
01811 }
01812 if(rc == zero)
01813 ZERO64(R[zero]);
01814 if(func&0x80) {
01815 DISASM5("%s,0x%2.2x,%s\t0x%8.8x %8.8x\n",
01816 RN[ra], (rb<<3)|(func>>8), RN[rc],
01817 (R[rc].part1<<16) | R[rc].part2,
01818 (R[rc].part3<<16) | R[rc].part4);
01819 }
01820 else {
01821 DISASM5("%s,%s,%s\t0x%8.8x %8.8x\n",
01822 RN[ra], RN[rb], RN[rc],
01823 (R[rc].part1<<16) | R[rc].part2,
01824 (R[rc].part3<<16) | R[rc].part4);
01825 }
01826 break;
01827
01828 case 0x15:
01829 case 0x16:
01830 rr = (AR_IEEE_64*)&F[rc];
01831 oa = (AR_IEEE_64*)&F[ra];
01832 ob = (AR_IEEE_64*)&F[rb];
01833 switch(func) {
01834 case 0x00:
01835 DISASM0("ADDS/C\t");
01836 ar_type = AR_Float_IEEE_ZE_32;
01837 status = ar_ifadd64(rr, oa, ob, AR_ROUND_ZERO);
01838 status |= ar_convert_to_float((ar_data*)®64, &ar_type,
01839 (ar_data*)&F[rc], &ieee_float_64);
01840 status |= ar_convert_to_float((ar_data*)&F[rc], &ieee_float_64,
01841 (ar_data*)®64, &ieee_float_32);
01842 status &= AR_ERROR_STATUS;
01843 break;
01844 case 0x01:
01845 DISASM0("SUBS/C\t");
01846 ar_type = AR_Float_IEEE_ZE_32;
01847 status = ar_ifsub64(rr, oa, ob, AR_ROUND_ZERO);
01848 status |= ar_convert_to_float((ar_data*)®64, &ar_type,
01849 (ar_data*)&F[rc], &ieee_float_64);
01850 status |= ar_convert_to_float((ar_data*)&F[rc], &ieee_float_64,
01851 (ar_data*)®64, &ieee_float_32);
01852 status &= AR_ERROR_STATUS;
01853 break;
01854 case 0x02:
01855 DISASM0("MULS/C\t");
01856 ar_type = AR_Float_IEEE_ZE_32;
01857 status = ar_ifmul64(rr, oa, ob, AR_ROUND_ZERO);
01858 status |= ar_convert_to_float((ar_data*)®64, &ar_type,
01859 (ar_data*)&F[rc], &ieee_float_64);
01860 status |= ar_convert_to_float((ar_data*)&F[rc], &ieee_float_64,
01861 (ar_data*)®64, &ieee_float_32);
01862 status &= AR_ERROR_STATUS;
01863 break;
01864 case 0x03:
01865 DISASM0("DIVS/C\t");
01866 ar_type = AR_Float_IEEE_ZE_32;
01867 status = ar_ifdiv64(rr, oa, ob, AR_ROUND_ZERO);
01868 status |= ar_convert_to_float((ar_data*)®64, &ar_type,
01869 (ar_data*)&F[rc], &ieee_float_64);
01870 status |= ar_convert_to_float((ar_data*)&F[rc], &ieee_float_64,
01871 (ar_data*)®64, &ieee_float_32);
01872 status &= AR_ERROR_STATUS;
01873 break;
01874 case 0x20:
01875 DISASM0("ADDT/C\t");
01876 status = ar_ifadd64(rr, oa, ob, AR_ROUND_ZERO)&AR_ERROR_STATUS;
01877 break;
01878 case 0x21:
01879 DISASM0("SUBT/C\t");
01880 status = ar_ifsub64(rr, oa, ob, AR_ROUND_ZERO)&AR_ERROR_STATUS;
01881 break;
01882 case 0x22:
01883 DISASM0("MULT/C\t");
01884 status = ar_ifmul64(rr, oa, ob, AR_ROUND_ZERO)&AR_ERROR_STATUS;
01885 break;
01886 case 0x23:
01887 DISASM0("DIVT/C\t");
01888 status = ar_ifdiv64(rr, oa, ob, AR_ROUND_ZERO)&AR_ERROR_STATUS;
01889 break;
01890 case 0x2c:
01891 DISASM0("CVTTS/C\t");
01892 ar_type = AR_Float_IEEE_ZE_32;
01893 status = ar_convert_to_float((ar_data*)®64, &ar_type,
01894 (ar_data*)&F[rb], &ieee_float_64);
01895 status |= ar_convert_to_float((ar_data*)&F[rc], &ieee_float_64,
01896 (ar_data*)®64, &ieee_float_32);
01897 status &= AR_ERROR_STATUS;
01898 break;
01899 case 0x2f:
01900 DISASM0("CVTTQ/C\t");
01901 status = ar_ifix64((AR_INT_64*)rr, ob, 64, AR_ROUND_ZERO)&AR_ERROR_STATUS;
01902 break;
01903 case 0x3c:
01904 DISASM0("CVTQS/C\t");
01905 ar_type = AR_Float_IEEE_ZE_32;
01906 status = ar_iflt64(rr, (AR_INT_64*)ob, 0, AR_ROUND_ZERO);
01907 status |= ar_convert_to_float((ar_data*)®64, &ar_type,
01908 (ar_data*)&F[rc], &ieee_float_64);
01909 status |= ar_convert_to_float((ar_data*)&F[rc], &ieee_float_64,
01910 (ar_data*)®64, &ieee_float_32);
01911 status &= AR_ERROR_STATUS;
01912 break;
01913 case 0x3e:
01914 DISASM0("CVTQT/C\t");
01915 status = ar_iflt64(rr, (AR_INT_64*)ob, 0, AR_ROUND_ZERO)&AR_ERROR_STATUS;
01916 break;
01917 case 0x80:
01918 DISASM0("ADDS\t");
01919 ar_type = AR_Float_IEEE_NR_32;
01920 status = ar_ifadd64(rr, oa, ob, AR_ROUND_NEAREST);
01921 status |= ar_convert_to_float((ar_data*)®64, &ar_type,
01922 (ar_data*)&F[rc], &ieee_float_64);
01923 status |= ar_convert_to_float((ar_data*)&F[rc], &ieee_float_64,
01924 (ar_data*)®64, &ieee_float_32);
01925 status &= AR_ERROR_STATUS;
01926 break;
01927 case 0x81:
01928 DISASM0("SUBS\t");
01929 ar_type = AR_Float_IEEE_NR_32;
01930 status = ar_ifsub64(rr, oa, ob, AR_ROUND_NEAREST);
01931 status |= ar_convert_to_float((ar_data*)®64, &ar_type,
01932 (ar_data*)&F[rc], &ieee_float_64);
01933 status |= ar_convert_to_float((ar_data*)&F[rc], &ieee_float_64,
01934 (ar_data*)®64, &ieee_float_32);
01935 status &= AR_ERROR_STATUS;
01936 break;
01937 case 0x82:
01938 DISASM0("MULS\t");
01939 ar_type = AR_Float_IEEE_NR_32;
01940 status = ar_ifmul64(rr, oa, ob, AR_ROUND_NEAREST);
01941 status |= ar_convert_to_float((ar_data*)®64, &ar_type,
01942 (ar_data*)&F[rc], &ieee_float_64);
01943 status |= ar_convert_to_float((ar_data*)&F[rc], &ieee_float_64,
01944 (ar_data*)®64, &ieee_float_32);
01945 status &= AR_ERROR_STATUS;
01946 break;
01947 case 0x83:
01948 DISASM0("DIVS\t");
01949 ar_type = AR_Float_IEEE_NR_32;
01950 status = ar_ifdiv64(rr, oa, ob, AR_ROUND_NEAREST);
01951 status |= ar_convert_to_float((ar_data*)®64, &ar_type,
01952 (ar_data*)&F[rc], &ieee_float_64);
01953 status |= ar_convert_to_float((ar_data*)&F[rc], &ieee_float_64,
01954 (ar_data*)®64, &ieee_float_32);
01955 status &= AR_ERROR_STATUS;
01956 break;
01957 case 0xa0:
01958 DISASM0("ADDT\t");
01959 status = ar_ifadd64(rr, oa, ob, AR_ROUND_NEAREST)&AR_ERROR_STATUS;
01960 break;
01961 case 0xa1:
01962 DISASM0("SUBT\t");
01963 status = ar_ifsub64(rr, oa, ob, AR_ROUND_NEAREST)&AR_ERROR_STATUS;
01964 break;
01965 case 0xa2:
01966 DISASM0("MULT\t");
01967 status = ar_ifmul64(rr, oa, ob, AR_ROUND_NEAREST)&AR_ERROR_STATUS;
01968 break;
01969 case 0xa3:
01970 DISASM0("DIVT\t");
01971 status = ar_ifdiv64(rr, oa, ob, AR_ROUND_NEAREST)&AR_ERROR_STATUS;
01972 break;
01973 case 0xa5:
01974 DISASM0("CMPTEQ\t");
01975 status = ar_ifcmp64((const AR_IEEE_64*)oa, (const AR_IEEE_64*)ob);
01976 F[rc].part2 = F[rc].part3 = F[rc].part4 = 0;
01977 if(status & AR_STAT_ZERO)
01978 F[rc].part1 = 0x4000;
01979 else
01980 F[rc].part1 = 0;
01981 status = AR_STAT_OK;
01982 break;
01983 case 0xa6:
01984 DISASM0("CMPTLT\t");
01985 status = ar_ifcmp64((const AR_IEEE_64*)oa, (const AR_IEEE_64*)ob);
01986 F[rc].part2 = F[rc].part3 = F[rc].part4 = 0;
01987 if(status & AR_STAT_NEGATIVE)
01988 F[rc].part1 = 0x4000;
01989 else
01990 F[rc].part1 = 0;
01991 status = AR_STAT_OK;
01992 break;
01993 case 0xa7:
01994 DISASM0("CMPTLE\t");
01995 status = ar_ifcmp64((const AR_IEEE_64*)oa, (const AR_IEEE_64*)ob);
01996 F[rc].part2 = F[rc].part3 = F[rc].part4 = 0;
01997 if(status & (AR_STAT_NEGATIVE|AR_STAT_ZERO))
01998 F[rc].part1 = 0x4000;
01999 else
02000 F[rc].part1 = 0;
02001 status = AR_STAT_OK;
02002 break;
02003 case 0xac:
02004 DISASM0("CVTTS\t");
02005 ar_type = AR_Float_IEEE_NR_32;
02006 status = ar_convert_to_float((ar_data*)®64, &ar_type,
02007 (ar_data*)&F[rb], &ieee_float_64);
02008 status |= ar_convert_to_float((ar_data*)&F[rc], &ieee_float_64,
02009 (ar_data*)®64, &ieee_float_32);
02010 status &= AR_ERROR_STATUS;
02011 break;
02012 case 0xaf:
02013 DISASM0("CVTTQ\t");
02014 status = ar_ifix64((AR_INT_64*)rr, ob, 64, AR_ROUND_NEAREST)&AR_ERROR_STATUS;
02015 break;
02016 case 0xbc:
02017 DISASM0("CVTQS\t");
02018 ar_type = AR_Float_IEEE_NR_32;
02019 status = ar_iflt64(rr, (AR_INT_64*)ob, 0, AR_ROUND_NEAREST);
02020 status |= ar_convert_to_float((ar_data*)®64, &ar_type,
02021 (ar_data*)&F[rc], &ieee_float_64);
02022 status |= ar_convert_to_float((ar_data*)&F[rc], &ieee_float_64,
02023 (ar_data*)®64, &ieee_float_32);
02024 status &= AR_ERROR_STATUS;
02025 break;
02026 case 0xbe:
02027 DISASM0("CVTQT\t");
02028 status = ar_iflt64(rr, (AR_INT_64*)ob, 0, AR_ROUND_NEAREST)&AR_ERROR_STATUS;
02029 break;
02030 case 0xc0:
02031 DISASM0("ADDS/D\t");
02032 status = ar_ifadd64(rr, oa, ob, D_roundmode);
02033 status |= ar_convert_to_float((ar_data*)®64, &D_float_32,
02034 (ar_data*)&F[rc], &ieee_float_64);
02035 status |= ar_convert_to_float((ar_data*)&F[rc], &ieee_float_64,
02036 (ar_data*)®64, &ieee_float_32);
02037 status &= AR_ERROR_STATUS;
02038 break;
02039 case 0xc1:
02040 DISASM0("SUBS/D\t");
02041 status = ar_ifsub64(rr, oa, ob, D_roundmode);
02042 status |= ar_convert_to_float((ar_data*)®64, &D_float_32,
02043 (ar_data*)&F[rc], &ieee_float_64);
02044 status |= ar_convert_to_float((ar_data*)&F[rc], &ieee_float_64,
02045 (ar_data*)®64, &ieee_float_32);
02046 status &= AR_ERROR_STATUS;
02047 break;
02048 case 0xc2:
02049 DISASM0("MULS/D\t");
02050 status = ar_ifmul64(rr, oa, ob, D_roundmode);
02051 status |= ar_convert_to_float((ar_data*)®64, &D_float_32,
02052 (ar_data*)&F[rc], &ieee_float_64);
02053 status |= ar_convert_to_float((ar_data*)&F[rc], &ieee_float_64,
02054 (ar_data*)®64, &ieee_float_32);
02055 status &= AR_ERROR_STATUS;
02056 break;
02057 case 0xc3:
02058 DISASM0("DIVS/D\t");
02059 status = ar_ifdiv64(rr, oa, ob, D_roundmode);
02060 status |= ar_convert_to_float((ar_data*)®64, &D_float_32,
02061 (ar_data*)&F[rc], &ieee_float_64);
02062 status |= ar_convert_to_float((ar_data*)&F[rc], &ieee_float_64,
02063 (ar_data*)®64, &ieee_float_32);
02064 status &= AR_ERROR_STATUS;
02065 break;
02066 case 0xe0:
02067 DISASM0("ADDT/D\t");
02068 status = ar_ifadd64(rr, oa, ob, D_roundmode)&AR_ERROR_STATUS;
02069 break;
02070 case 0xe1:
02071 DISASM0("SUBT/D\t");
02072 status = ar_ifsub64(rr, oa, ob, D_roundmode)&AR_ERROR_STATUS;
02073 break;
02074 case 0xe2:
02075 DISASM0("MULT/D\t");
02076 status = ar_ifmul64(rr, oa, ob, D_roundmode)&AR_ERROR_STATUS;
02077 break;
02078 case 0xe3:
02079 DISASM0("DIVT/D\t");
02080 status = ar_ifdiv64(rr, oa, ob, D_roundmode)&AR_ERROR_STATUS;
02081 break;
02082 case 0xec:
02083 DISASM0("CVTTS/D\t");
02084 status = ar_convert_to_float((ar_data*)®64, &D_float_32,
02085 (ar_data*)&F[rb], &ieee_float_64);
02086 status |= ar_convert_to_float((ar_data*)&F[rc], &ieee_float_64,
02087 (ar_data*)®64, &ieee_float_32);
02088 status &= AR_ERROR_STATUS;
02089 break;
02090 case 0xef:
02091 DISASM0("CVTTQ/D\t");
02092 status = ar_ifix64((AR_INT_64*)rr, ob, 64, D_roundmode)&AR_ERROR_STATUS;
02093 break;
02094 case 0xfc:
02095 DISASM0("CVTQS/D\t");
02096 status = ar_iflt64(rr, (AR_INT_64*)ob, 0, D_roundmode);
02097 status |= ar_convert_to_float((ar_data*)®64, &D_float_32,
02098 (ar_data*)&F[rc], &ieee_float_64);
02099 status |= ar_convert_to_float((ar_data*)&F[rc], &ieee_float_64,
02100 (ar_data*)®64, &ieee_float_32);
02101 status &= AR_ERROR_STATUS;
02102 break;
02103 case 0xfe:
02104 DISASM0("CVTQT/D\t");
02105 status = ar_iflt64(rr, (AR_INT_64*)ob, 0, D_roundmode)&AR_ERROR_STATUS;
02106 break;
02107 default:
02108 status = BADINSTR;
02109 DISASM5("%x.%x.%x.%x.%x", op, ra, rb, func, rc);
02110 }
02111 if(rc == fzero)
02112 ZERO64(F[fzero]);
02113 DISASM5("%s,%s,%s\t0x%8.8x %8.8x\n",
02114 FN[ra], FN[rb], FN[rc],
02115 (F[rc].part1<<16) | F[rc].part2,
02116 (F[rc].part3<<16) | F[rc].part4);
02117 break;
02118
02119 case 0x17:
02120 switch(func) {
02121 case 0x10:
02122 DISASM0("CVTLQ\t");
02123 F[rc].part3 = (F[rb].part1&0xc000) |
02124 ((F[rb].part1&0x7ff) << 3) |
02125 (F[rb].part2 >> 13);
02126 F[rc].part4 = (F[rb].part2 << 3) |
02127 (F[rb].part3 >> 13);
02128 if(F[rc].part3>>15)
02129 F[rc].part1 = F[rc].part2 = 0xffff;
02130 else
02131 F[rc].part1 = F[rc].part2 = 0;
02132 break;
02133 case 0x20:
02134 DISASM0("CPYS\t");
02135 sign = F[ra].part1&0x8000;
02136 COPY64(F[rc], F[rb]);
02137 if(ra != rb)
02138 F[rc].part1 = (F[rc].part1&0x7fff) | sign;
02139 break;
02140 case 0x21:
02141 DISASM0("CPYSN\t");
02142 sign = 0x8000-(F[ra].part1&0x8000);
02143 COPY64(F[rc], F[rb]);
02144 F[rc].part1 = (F[rc].part1&0x7fff) | sign;
02145 break;
02146 case 0x22:
02147 DISASM0("CPYSE\t");
02148 sign = F[ra].part1&0xfff0;
02149 COPY64(F[rc], F[rb]);
02150 if(ra != rb)
02151 F[rc].part1 = (F[rc].part1&0x000f) | sign;
02152 break;
02153 case 0x2a:
02154 DISASM0("FCMOVEQ\t");
02155 if(((F[ra].part1&0x7fff)|F[ra].part2|F[ra].part3|F[ra].part4) == 0)
02156 COPY64(F[rc], F[rb]);
02157 break;
02158 case 0x2b:
02159 DISASM0("FCMOVNE\t");
02160 if(((F[ra].part1&0x7fff)|F[ra].part2|F[ra].part3|F[ra].part4) != 0)
02161 COPY64(F[rc], F[rb]);
02162 break;
02163 case 0x2c:
02164 DISASM0("FCMOVLT\t");
02165 if(F[ra].part1&0x8000)
02166 COPY64(F[rc], F[rb]);
02167 break;
02168 case 0x2d:
02169 DISASM0("FCMOVGE\t");
02170 if((F[ra].part1&0x8000) == 0)
02171 COPY64(F[rc], F[rb]);
02172 break;
02173 case 0x2e:
02174 DISASM0("FCMOVLE\t");
02175 if((F[ra].part1&0x8000) ||
02176 ((F[ra].part1&0x7fff)|F[ra].part2|F[ra].part3|F[ra].part4) == 0)
02177 COPY64(F[rc], F[rb]);
02178 break;
02179 case 0x2f:
02180 DISASM0("FCMOVGT\t");
02181 if((F[ra].part1&0x8000) == 0 &&
02182 ((F[ra].part1&0x7fff)|F[ra].part2|F[ra].part3|F[ra].part4) != 0)
02183 COPY64(F[rc], F[rb]);
02184 break;
02185 case 0x30:
02186 DISASM0("CVTQL\t");
02187 F[rc].part1 = (F[rb].part3 & 0xc000) |
02188 ((F[rb].part3 & 0x3fff) >> 3);
02189 F[rc].part2 = (F[rb].part3 << 13) |
02190 (F[rb].part4 >> 3);
02191 F[rc].part3 = (F[rb].part4 << 13);
02192 F[rc].part4 = 0;
02193 break;
02194 default:
02195 status = BADINSTR;
02196 DISASM5("%x.%x.%x.%x.%x", op, ra, rb, func, rc);
02197 }
02198 if(rc == fzero)
02199 ZERO64(F[fzero]);
02200 DISASM5("%s,%s,%s\t0x%8.8x %8.8x\n",
02201 FN[ra], FN[rb], FN[rc],
02202 (F[rc].part1<<16) | F[rc].part2,
02203 (F[rc].part3<<16) | F[rc].part4);
02204 break;
02205
02206 case 0x18:
02207 switch(p2) {
02208 case 0x0:
02209 DISASM0("TRAPB\n");
02210 break;
02211 case 0x4:
02212 DISASM0("MB\n");
02213 break;
02214 case 0x8:
02215 DISASM2("FETCH\t%s,%s\n", RN[ra],RN[rb]);
02216 break;
02217 case 0xa:
02218 DISASM2("FETCH_M\t%s,%s\n", RN[ra],RN[rb]);
02219 break;
02220 case 0xc:
02221 if(rtcpc < pc)
02222 rtc += (pc-rtcpc);
02223 else
02224 rtc += (rtcpc-pc);
02225 rtcpc = pc;
02226 iu64.l64 = rtc;
02227 COPY64(R[ra], iu64.ari64);
02228 DISASM2("RPCC\t%s\t0x%16x\n", RN[ra], rtc);
02229 break;
02230 case 0xe:
02231 DISASM2("RC\t%s,%s\n", RN[ra], RN[rb]);
02232 break;
02233 case 0xf:
02234 DISASM2("RS\t%s,%s\n", RN[ra], RN[rb]);
02235 break;
02236 }
02237 break;
02238
02239 case 0x1a:
02240 switch(func>>9) {
02241 case 0:
02242 DISASM2("JMP\t%s,%s\n",RN[ra],RN[rb]);
02243 break;
02244 case 1:
02245 DISASM2("JSR\t%s,%s\n",RN[ra],RN[rb]);
02246 break;
02247 case 2:
02248 DISASM2("RET\t%s,%s\n",RN[ra],RN[rb]);
02249 break;
02250 case 3:
02251 DISASM2("JSR_C\t,%s\n",RN[ra],RN[rb]);
02252 break;
02253 }
02254 if(ra != zero) {
02255 R[ra].part1 = R[ra].part2 = 0;
02256 R[ra].part3 = pc>>16;
02257 R[ra].part4 = pc&0xffff;
02258 }
02259 pc = ((R[rb].part3<<16)|R[rb].part4) &~ 3;
02260 if(pc == 0)
02261 return(status);
02262 break;
02263
02264 case 0x20:
02265 status = BADINSTR;
02266 DISASM3("LDF\t%s,0x%4.4x(%s)\n", RN[ra], p2, RN[rb]);
02267 break;
02268
02269 case 0x21:
02270 status = BADINSTR;
02271 DISASM3("LDG\t%s,0x%4.4x(%s)\n", RN[ra], p2, RN[rb]);
02272 break;
02273
02274 case 0x22:
02275 if(ra != fzero) {
02276 reg64.part4 = p2;
02277 if(p2>>15)
02278 reg64.part1 = reg64.part2 = reg64.part3 = 0xffff;
02279 else
02280 reg64.part1 = reg64.part2 = reg64.part3 = 0;
02281 ADD64(reg64, reg64, R[rb]);
02282 offset = (reg64.part3<<16) | reg64.part4;
02283 if(offset & 3)
02284 status = BADINSTR;
02285 else {
02286 load_mpp_word(®64, reg64.part2&0xff, offset>>3);
02287 if(offset & 4) {
02288 int64.part3 = reg64.part3;
02289 int64.part4 = reg64.part4;
02290 }
02291 else {
02292 int64.part3 = reg64.part1;
02293 int64.part4 = reg64.part2;
02294 }
02295 }
02296 ar_convert_to_float((ar_data*)&F[ra], &ieee_float_64,
02297 (ar_data*)&int64, &ieee_float_32);
02298 }
02299 DISASM5("LDS\t%s,0x%4.4x(%s)\t0x%8.8x %8.8x\n",
02300 FN[ra], p2, RN[rb],
02301 (F[ra].part1<<16) | F[ra].part2,
02302 (F[ra].part3<<16) | F[ra].part4);
02303 break;
02304
02305 case 0x23:
02306 if(ra != fzero) {
02307 reg64.part4 = p2;
02308 if(p2>>15)
02309 reg64.part1 = reg64.part2 = reg64.part3 = 0xffff;
02310 else
02311 reg64.part1 = reg64.part2 = reg64.part3 = 0;
02312 ADD64(reg64, reg64, R[rb]);
02313 offset = (reg64.part3<<16) | reg64.part4;
02314 if(offset & 7)
02315 status = BADINSTR;
02316 else
02317 load_mpp_word(&F[ra], reg64.part2&0xff, offset>>3);
02318 }
02319 DISASM5("LDT\t%s,0x%4.4x(%s)\t0x%8.8x %8.8x\n",
02320 FN[ra], p2, RN[rb],
02321 (F[ra].part1<<16) | F[ra].part2,
02322 (F[ra].part3<<16) | F[ra].part4);
02323 break;
02324
02325 case 0x24:
02326 status = BADINSTR;
02327 DISASM3("STF\t%s,0x%4.4x(%s)\n", FN[ra], p2, RN[rb]);
02328 break;
02329
02330 case 0x25:
02331 status = BADINSTR;
02332 DISASM3("STG\t%s,0x%4.4x(%s)\n", FN[ra], p2, RN[rb]);
02333 break;
02334
02335 case 0x26:
02336 reg64.part4 = p2;
02337 if(p2>>15)
02338 reg64.part1 = reg64.part2 = reg64.part3 = 0xffff;
02339 else
02340 reg64.part1 = reg64.part2 = reg64.part3 = 0;
02341 ADD64(reg64, reg64, R[rb]);
02342 offset = (reg64.part3<<16) | reg64.part4;
02343 if(offset & 3)
02344 status = BADINSTR;
02345 else {
02346 n = reg64.part2&0xff;
02347 load_mpp_word(®64, n, offset>>3);
02348 ar_convert_to_float((ar_data*)&int64, &ieee_float_32,
02349 (ar_data*)&F[ra], &ieee_float_64);
02350 if(offset & 4) {
02351 reg64.part3 = int64.part3;
02352 reg64.part4 = int64.part4;
02353 }
02354 else {
02355 reg64.part1 = int64.part3;
02356 reg64.part2 = int64.part4;
02357 }
02358 store_mpp_word(n, offset>>3, ®64);
02359 }
02360 DISASM3("STS\t%s,0x%4.4x(%s)\n", FN[ra], p2, RN[rb]);
02361 break;
02362
02363 case 0x27:
02364 reg64.part4 = p2;
02365 if(p2>>15)
02366 reg64.part1 = reg64.part2 = reg64.part3 = 0xffff;
02367 else
02368 reg64.part1 = reg64.part2 = reg64.part3 = 0;
02369 ADD64(reg64, reg64, R[rb]);
02370 offset = (reg64.part3<<16) | reg64.part4;
02371 if(offset & 7)
02372 status = BADINSTR;
02373 else {
02374 store_mpp_word(reg64.part2&0xff, offset>>3, &F[ra]);
02375 }
02376 DISASM3("STT\t%s,0x%4.4x(%s)\n", FN[ra], p2, RN[rb]);
02377 break;
02378
02379 case 0x28:
02380 if(ra != zero) {
02381 reg64.part4 = p2;
02382 if(p2>>15)
02383 reg64.part1 = reg64.part2 = reg64.part3 = 0xffff;
02384 else
02385 reg64.part1 = reg64.part2 = reg64.part3 = 0;
02386 ADD64(reg64, reg64, R[rb]);
02387 offset = (reg64.part3<<16) | reg64.part4;
02388 if(offset & 3)
02389 status = BADINSTR;
02390 else {
02391 load_mpp_word(®64, reg64.part2&0xff, offset>>3);
02392 if(offset & 4) {
02393 R[ra].part3 = reg64.part3;
02394 R[ra].part4 = reg64.part4;
02395 }
02396 else {
02397 R[ra].part3 = reg64.part1;
02398 R[ra].part4 = reg64.part2;
02399 }
02400 }
02401 if(R[ra].part3>>15)
02402 R[ra].part1 = R[ra].part2 = 0xffff;
02403 else
02404 R[ra].part1 = R[ra].part2 = 0;
02405 }
02406 DISASM5("LDL\t%s,0x%4.4x(%s)\t0x%8.8x %8.8x\n",
02407 RN[ra], p2, RN[rb],
02408 (R[ra].part1<<16) | R[ra].part2,
02409 (R[ra].part3<<16) | R[ra].part4);
02410 break;
02411
02412 case 0x29:
02413 if(ra != zero) {
02414 reg64.part4 = p2;
02415 if(p2>>15)
02416 reg64.part1 = reg64.part2 = reg64.part3 = 0xffff;
02417 else
02418 reg64.part1 = reg64.part2 = reg64.part3 = 0;
02419 ADD64(reg64, reg64, R[rb]);
02420 offset = (reg64.part3<<16) | reg64.part4;
02421 if(offset & 7)
02422 status = BADINSTR;
02423 else
02424 load_mpp_word(&R[ra], reg64.part2&0xff, offset>>3);
02425 }
02426 DISASM5("LDQ\t%s,0x%4.4x(%s)\t0x%8.8x %8.8x\n",
02427 RN[ra], p2, RN[rb],
02428 (R[ra].part1<<16) | R[ra].part2,
02429 (R[ra].part3<<16) | R[ra].part4);
02430 break;
02431
02432 case 0x2a:
02433 status = BADINSTR;
02434 DISASM3("LDL_L\t%s,0x%4.4x(%s)\n", RN[ra], p2, RN[rb]);
02435 break;
02436
02437 case 0x2b:
02438 status = BADINSTR;
02439 DISASM3("LDQ_L\t%s,0x%4.4x(%s)\n", RN[ra], p2, RN[rb]);
02440 break;
02441
02442 case 0x2c:
02443 reg64.part4 = p2;
02444 if(p2>>15)
02445 reg64.part1 = reg64.part2 = reg64.part3 = 0xffff;
02446 else
02447 reg64.part1 = reg64.part2 = reg64.part3 = 0;
02448 ADD64(reg64, reg64, R[rb]);
02449 offset = (reg64.part3<<16) | reg64.part4;
02450 if(offset & 3)
02451 status = BADINSTR;
02452 else {
02453 n = reg64.part2&0xff;
02454 load_mpp_word(®64, n, offset>>3);
02455 if(offset & 4) {
02456 reg64.part3 = R[ra].part3;
02457 reg64.part4 = R[ra].part4;
02458 }
02459 else {
02460 reg64.part1 = R[ra].part3;
02461 reg64.part2 = R[ra].part4;
02462 }
02463 store_mpp_word(n, offset>>3, ®64);
02464 }
02465 DISASM3("STL\t%s,0x%4.4x(%s)\n", RN[ra], p2, RN[rb]);
02466 break;
02467
02468 case 0x2d:
02469 reg64.part4 = p2;
02470 if(p2>>15)
02471 reg64.part1 = reg64.part2 = reg64.part3 = 0xffff;
02472 else
02473 reg64.part1 = reg64.part2 = reg64.part3 = 0;
02474 ADD64(reg64, reg64, R[rb]);
02475 offset = (reg64.part3<<16) | reg64.part4;
02476 if(offset & 7)
02477 status = BADINSTR;
02478 else {
02479 store_mpp_word(reg64.part2&0xff, offset>>3, &R[ra]);
02480 }
02481 DISASM3("STQ\t%s,0x%4.4x(%s)\n", RN[ra], p2, RN[rb]);
02482 break;
02483
02484 case 0x2e:
02485 status = BADINSTR;
02486 DISASM3("STL_C\t%s,0x%4.4x(%s)\n", RN[ra], p2, RN[rb]);
02487 break;
02488
02489 case 0x2f:
02490 status = BADINSTR;
02491 DISASM3("STQ_C\t%s,0x%4.4x(%s)\n", RN[ra], p2, RN[rb]);
02492 break;
02493
02494 case 0x30:
02495 case 0x34:
02496 disp = ((rb<<16)|p2)<<2;
02497 if(disp>>22)
02498 disp |= (-1<<23);
02499 if(ra != zero) {
02500 R[ra].part1 = R[ra].part2 = 0;
02501 R[ra].part3 = pc>>16;
02502 R[ra].part4 = pc&0xffff;
02503 }
02504 pc += disp;
02505 if(op == 0x30) {
02506 DISASM2("BR\t%s,0x%6.6x\n", RN[ra], (rb<<16)|p2);
02507 }
02508 else {
02509 DISASM2("BSR\t%s,0x%6.6x\n", RN[ra], (rb<<16)|p2);
02510 }
02511 if(pc == 0)
02512 return(status);
02513 break;
02514
02515 case 0x31:
02516 if(!((F[ra].part1&0x7fff)|F[ra].part2|F[ra].part3|F[ra].part4)) {
02517 disp = ((rb<<16)|p2)<<2;
02518 if(disp>>22)
02519 disp |= (-1<<23);
02520 pc += disp;
02521 }
02522 DISASM2("FBEQ\t%s,0x%6.6x\n", FN[ra], (rb<<16)|p2);
02523 break;
02524
02525 case 0x32:
02526 if(F[ra].part1>>15) {
02527 disp = ((rb<<16)|p2)<<2;
02528 if(disp>>22)
02529 disp |= (-1<<23);
02530 pc += disp;
02531 }
02532 DISASM2("FBLT\t%s,0x%6.6x\n", FN[ra], (rb<<16)|p2);
02533 break;
02534
02535 case 0x33:
02536 if((F[ra].part1>>15) ||
02537 (F[ra].part1|F[ra].part2|F[ra].part3|F[ra].part4)==0) {
02538 disp = ((rb<<16)|p2)<<2;
02539 if(disp>>22)
02540 disp |= (-1<<23);
02541 pc += disp;
02542 }
02543 DISASM2("FBLE\t%s,0x%6.6x\n", FN[ra], (rb<<16)|p2);
02544 break;
02545
02546 case 0x35:
02547 if((F[ra].part1&0x7fff)|F[ra].part2|F[ra].part3|F[ra].part4) {
02548 disp = ((rb<<16)|p2)<<2;
02549 if(disp>>22)
02550 disp |= (-1<<23);
02551 pc += disp;
02552 }
02553 DISASM2("FBNE\t%s,0x%6.6x\n", FN[ra], (rb<<16)|p2);
02554 break;
02555
02556 case 0x36:
02557 if((F[ra].part1>>15) == 0) {
02558 disp = ((rb<<16)|p2)<<2;
02559 if(disp>>22)
02560 disp |= (-1<<23);
02561 pc += disp;
02562 }
02563 DISASM2("FBGE\t%s,0x%6.6x\n", FN[ra], (rb<<16)|p2);
02564 break;
02565
02566 case 0x37:
02567 if((F[ra].part1>>15)==0 &&
02568 (F[ra].part1|F[ra].part2|F[ra].part3|F[ra].part4)!=0) {
02569 disp = ((rb<<16)|p2)<<2;
02570 if(disp>>22)
02571 disp |= (-1<<23);
02572 pc += disp;
02573 }
02574 DISASM2("FBGT\t%s,0x%6.6x\n", FN[ra], (rb<<16)|p2);
02575 break;
02576
02577 case 0x38:
02578 if((R[ra].part4&1) == 0) {
02579 disp = ((rb<<16)|p2)<<2;
02580 if(disp>>22)
02581 disp |= (-1<<23);
02582 pc += disp;
02583 }
02584 DISASM2("BLBC\t%s,0x%6.6x\n", RN[ra], (rb<<16)|p2);
02585 break;
02586
02587 case 0x39:
02588 if((R[ra].part1|R[ra].part2|R[ra].part3|R[ra].part4) == 0) {
02589 disp = ((rb<<16)|p2)<<2;
02590 if(disp>>22)
02591 disp |= (-1<<23);
02592 pc += disp;
02593 }
02594 DISASM2("BEQ\t%s,0x%6.6x\n", RN[ra], (rb<<16)|p2);
02595 break;
02596
02597 case 0x3a:
02598 if(R[ra].part1>>15) {
02599 disp = ((rb<<16)|p2)<<2;
02600 if(disp>>22)
02601 disp |= (-1<<23);
02602 pc += disp;
02603 }
02604 DISASM2("BLT\t%s,0x%6.6x\n", RN[ra], (rb<<16)|p2);
02605 break;
02606
02607 case 0x3b:
02608 if((R[ra].part1>>15) ||
02609 (R[ra].part1|R[ra].part2|R[ra].part3|R[ra].part4)==0) {
02610 disp = ((rb<<16)|p2)<<2;
02611 if(disp>>22)
02612 disp |= (-1<<23);
02613 pc += disp;
02614 }
02615 DISASM2("BLE\t%s,0x%6.6x\n", RN[ra], (rb<<16)|p2);
02616 break;
02617
02618 case 0x3c:
02619 if(R[ra].part4&1) {
02620 disp = ((rb<<16)|p2)<<2;
02621 if(disp>>22)
02622 disp |= (-1<<23);
02623 pc += disp;
02624 }
02625 DISASM2("BLBS\t%s,0x%6.6x\n", RN[ra], (rb<<16)|p2);
02626 break;
02627
02628 case 0x3d:
02629 if((R[ra].part1|R[ra].part2|R[ra].part3|R[ra].part4) != 0) {
02630 disp = ((rb<<16)|p2)<<2;
02631 if(disp>>22)
02632 disp |= (-1<<23);
02633 pc += disp;
02634 }
02635 DISASM2("BNE\t%s,0x%6.6x\n", RN[ra], (rb<<16)|p2);
02636 break;
02637
02638 case 0x3e:
02639 if((R[ra].part1>>15) == 0) {
02640 disp = ((rb<<16)|p2)<<2;
02641 if(disp>>22)
02642 disp |= (-1<<23);
02643 pc += disp;
02644 }
02645 DISASM2("BGE\t%s,0x%6.6x\n", RN[ra], (rb<<16)|p2);
02646 break;
02647
02648 case 0x3f:
02649 if((R[ra].part1>>15)==0 &&
02650 (R[ra].part1|R[ra].part2|R[ra].part3|R[ra].part4)!=0) {
02651 disp = ((rb<<16)|p2)<<2;
02652 if(disp>>22)
02653 disp |= (-1<<23);
02654 pc += disp;
02655 }
02656 DISASM2("BGT\t%s,0x%6.6x\n", RN[ra], (rb<<16)|p2);
02657 break;
02658
02659 default:
02660 status = BADINSTR;
02661 break;
02662 }
02663
02664 }
02665
02666 if(status == BADINSTR)
02667 ar_internal_error(2013, __FILE__, __LINE__);
02668
02669 return status;
02670 }
02671
02672 #define T3D_AHDR_SIZE 174*8
02673 #define CLD_T3E_AHDR_SIZE 512*8
02674
02675 #if T3D_AHDR_SIZE < 5*MPP_MAX_ARGS*8
02676 #error Insufficient space for T3D arguments
02677 #elif CLD_T3E_AHDR_SIZE < 5*MPP_MAX_ARGS*8
02678 #error Insufficient space for T3E arguments
02679 #endif
02680
02681 static int idf_fd;
02682 static long idf_size;
02683 static long text_size;
02684 static long data_offset;
02685
02686 static void
02687 open_intrinsics_file(void)
02688 {
02689 char fname[FILENAME_MAX + 1];
02690
02691 int i;
02692 int fd;
02693 int hdrsz;
02694 int v;
02695
02696 long offset;
02697
02698 char* str;
02699
02700
02701
02702
02703
02704 str=(char*)getenv("CRAYLIBS");
02705 if(str != NULL) {
02706 strcpy(fname,str);
02707 v=strlen(fname);
02708 strcpy(&fname[v],"/arith");
02709 idf_fd=open(fname, O_RDONLY);
02710 }
02711
02712
02713
02714 else {
02715 #if _CRAY
02716 strcpy(fname,"/opt/ctl/craylibs_m/craylibs_m/arith");
02717 v = 29;
02718 idf_fd=open(fname, O_RDONLY);
02719 if(idf_fd < 0) {
02720 strcpy(fname,"/mpp/lib/arith");
02721 v = 8;
02722 idf_fd=open(fname, O_RDONLY);
02723 }
02724 #else
02725 idf_fd = -1;
02726 #endif
02727 }
02728 if(idf_fd < 0)
02729 ar_internal_error(2009, __FILE__, __LINE__);
02730
02731
02732
02733 idf_size=lseek(idf_fd,0,SEEK_END);
02734 if(idf_size > 0) {
02735
02736
02737
02738
02739
02740
02741
02742
02743 mpp_intrin=(unsigned char*)malloc(idf_size +
02744 MPP_STACK_SIZE*8 +
02745 6*8 +
02746 MPP_MAX_ARGS*5*8);
02747 if(mpp_intrin == NULL)
02748 idf_size = -1;
02749 else {
02750 lseek(idf_fd,0,SEEK_SET);
02751 read(idf_fd,mpp_intrin,idf_size);
02752
02753
02754 i = (strcmp(mpp_intrin,"#!/mpp/bin/mppexec\n") == 0)? 32 : 0;
02755 if (i == 0) {
02756
02757
02758
02759
02760
02761
02762
02763
02764
02765 hdrsz = CLD_T3E_AHDR_SIZE;
02766 }
02767 else {
02768 hdrsz = T3D_AHDR_SIZE;
02769 }
02770
02771
02772 ar_mach_type = mpp_intrin[i+5];
02773
02774
02775
02776
02777
02778 if ((ar_mach_type == T3D || ar_mach_type == T3E) &&
02779 mpp_intrin[i+6] == 1 && mpp_intrin[i+7] == 07) {
02780
02781 if(ar_mach_type == T3D) {
02782 ar_sim_version = 0;
02783 }
02784 else {
02785 ar_sim_version = 1;
02786 }
02787 i += 64;
02788 while(i < hdrsz) {
02789 offset = (mpp_intrin[i+36]<<24) | (mpp_intrin[i+37]<<16) |
02790 (mpp_intrin[i+38]<<8) | (mpp_intrin[i+39]);
02791
02792
02793
02794
02795 switch (mpp_intrin[i+16] >> 4) {
02796 case SEGT_TEXT:
02797 if (code == NULL && mpp_intrin[i+3]) {
02798 code_segment_id = mpp_intrin[i+3];
02799 if (mpp_intrin[i+16] == 0x15 && offset==hdrsz)
02800 code = mpp_intrin;
02801 else
02802 hdrsz = 0;
02803 }
02804 break;
02805
02806 case SEGT_STACK:
02807 if (stack == NULL && mpp_intrin[i+3]) {
02808 stack_segment_id = mpp_intrin[i+3];
02809 text_size = idf_size-hdrsz;
02810 stack = mpp_intrin + (((text_size+7)>>3)<<3);
02811 }
02812 break;
02813
02814 case SEGT_DATA:
02815 if (data == NULL && mpp_intrin[i+3]) {
02816 data_segment_id = mpp_intrin[i+3];
02817 if (mpp_intrin[i+16] == 0x06)
02818 data = mpp_intrin+offset-hdrsz;
02819 else
02820 hdrsz = 0;
02821 }
02822 break;
02823 }
02824
02825
02826 i += 10*8;
02827 }
02828
02829
02830 if (stack != NULL) {
02831 memcpy(mpp_intrin, mpp_intrin+hdrsz, text_size);
02832 }
02833 }
02834 }
02835 }
02836
02837 close(idf_fd);
02838
02839
02840
02841 if (code==NULL || data==NULL || stack==NULL)
02842 ar_internal_error(2010, __FILE__, __LINE__);
02843
02844 i=text_size-1;
02845 str = (char*)strnstrn(mpp_intrin, text_size,
02846 "@(#)MPP arith/libm_version ", 27);
02847 if(str != NULL)
02848 strcpy(AR_libmv2, str+14);
02849 else {
02850 while(idf_size>0 && (text_size-i)<32) {
02851 if(strncmp(&mpp_intrin[i], "libm_version", 12) == 0) {
02852 strncpy(AR_libmv2, &mpp_intrin[i], text_size-i);
02853 AR_libmv2[text_size-i] = '\0';
02854 if(strncmp(&mpp_intrin[i-13], "MPP arith", 9))
02855 idf_size=-1;
02856 break;
02857 }
02858 if(mpp_intrin[i] == '\n')
02859 mpp_intrin[i]='\0';
02860 i--;
02861 }
02862 }
02863 if(idf_size<0 || (text_size-i)>=32)
02864 ar_internal_error(2010, __FILE__, __LINE__);
02865
02866
02867
02868
02869
02870
02871
02872
02873
02874
02875 if (AR_libmv2[2] != 'x' && AR_libmv2[13+2] != 'x') {
02876 int matched;
02877 char buf
02878 [FILENAME_MAX];
02879 struct ar_hdr arh;
02880 off_t fd_off;
02881 off_t fd_fsize;
02882 off_t fd_namelen;
02883 char *name_ptr;
02884
02885
02886
02887
02888 strcpy(&fname[v], "/libm.a");
02889 fd = open(fname, O_RDONLY);
02890 if (fd < 0) {
02891 strcpy(&fname[v], "/../libm.a");
02892 fd = open(fname, O_RDONLY);
02893 }
02894
02895
02896
02897
02898
02899 if (fd >= 0 &&
02900 read(fd, buf, SARMAG) == SARMAG &&
02901 strncmp(buf, ARMAG, SARMAG) == 0) {
02902
02903 matched = 1;
02904 fd_off = SARMAG;
02905
02906 while (1) {
02907
02908
02909
02910 if (read(fd, &arh, AR_HDR_SIZE) != AR_HDR_SIZE) {
02911 fd_off = 0;
02912 break;
02913 }
02914
02915
02916
02917
02918
02919
02920 if (strncmp(arh.ar_name, "#1/", 3) != 0) {
02921 name_ptr = arh.ar_name;
02922 }
02923 else {
02924 if (sscanf(&arh.ar_name[3], "%d", &fd_namelen) != 1 ||
02925 read(fd, buf, fd_namelen) != fd_namelen) {
02926 fd_off = 0;
02927 break;
02928 }
02929 name_ptr = buf;
02930 }
02931
02932 if (strncmp(name_ptr, "libm_version.o", 14) == 0) {
02933 break;
02934 }
02935
02936 if (sscanf(arh.ar_size, "%d", &fd_fsize) != 1) {
02937 fd_off = 0;
02938 break;
02939 }
02940
02941 fd_off = (fd_off + AR_HDR_SIZE + fd_fsize + 1) & (~1);
02942 if (lseek(idf_fd, fd_off, SEEK_SET) != fd_off) {
02943 fd_off = 0;
02944 break;
02945 }
02946 }
02947
02948
02949
02950
02951
02952
02953 if (fd_off != 0) {
02954 if (sscanf(arh.ar_size, "%d", &fd_fsize) != 1) {
02955 fd_off = 0;
02956 }
02957 }
02958
02959 if (fd_off != 0) {
02960 if (strncmp(arh.ar_name, "#1/", 3) == 0) {
02961 fd_fsize -= fd_namelen;
02962 }
02963
02964 if (fd_fsize > sizeof(buf)) {
02965 fd_fsize = sizeof(buf);
02966 }
02967
02968 if (read(fd, buf, fd_fsize) == fd_fsize) {
02969 str = (char*)strnstrn(buf, (fd_fsize - 9),
02970 "@(#)libm_version", 16);
02971 if (str != NULL) {
02972 str += 17;
02973 for (i = 0; matched && i < 8; i += 2)
02974 if (str[i] != 'x' &&
02975 AR_libmv2[13 + i] != 'x' &&
02976 str[i] != AR_libmv2[13 + i])
02977 matched = 0;
02978
02979 }
02980 }
02981 }
02982
02983 if (!matched) {
02984 PRINTMSG(0, 2016, Warning, 0, "MPP", "0", "", "");
02985 }
02986 }
02987 }
02988
02989 ar_state_register.ar_float_format = AR_IEEE_FLOATING_POINT;
02990 ar_state_register.ar_128bit_format = AR_128BIT_EXTENDED_DOUBLE;
02991 ar_state_register.ar_rounding_mode = AR_ROUND_NEAREST;
02992 ar_state_register.ar_underflow_mode = AR_UNDERFLOW_TO_PLUS_ZERO;
02993 }
02994
02995 static void
02996 load_mpp_word(result, segment, offset)
02997 AR_INT_64* result;
02998 long segment;
02999 long offset;
03000 {
03001
03002 if (segment == data_segment_id) {
03003 memcpy(result, data+offset*8, 8);
03004 return;
03005 }
03006
03007 else if (segment == stack_segment_id) {
03008 if(offset < (MPP_STACK_SIZE+MPP_MAX_ARGS*5+6)) {
03009 memcpy(result, stack+offset*8, 8);
03010 return;
03011 }
03012 }
03013
03014 else {
03015 if(segment>=0 && segment < n_external_addresses &&
03016 external_address[segment] != NULL) {
03017 if(external_length[segment] > offset) {
03018 memcpy(result, external_address[segment]+offset*8, 8);
03019 return;
03020 }
03021
03022
03023 if(external_length[segment] > (offset-8)) {
03024 result->part1 = result->part2 = 0xf0f0;
03025 result->part3 = result->part4 = 0xf0f0;
03026 return;
03027 }
03028 }
03029 }
03030
03031 ar_internal_error(2012, __FILE__, __LINE__);
03032 }
03033
03034 static void
03035 store_mpp_word(segment, offset, result)
03036 long segment;
03037 long offset;
03038 AR_INT_64* result;
03039 {
03040
03041 if (segment == data_segment_id) {
03042 memcpy(data+offset*8, result, 8);
03043 return;
03044 }
03045
03046 else if (segment == stack_segment_id) {
03047 if(offset < (MPP_STACK_SIZE+MPP_MAX_ARGS*5+6)) {
03048 memcpy(stack+offset*8, result, 8);
03049 return;
03050 }
03051 }
03052
03053 else {
03054 if(segment < n_external_addresses &&
03055 external_address[segment] != NULL) {
03056 if(external_length[segment] >= offset) {
03057 memcpy(external_address[segment]+offset*8, result, 8);
03058 return;
03059 }
03060
03061
03062
03063 if(external_length[segment] > (offset-8) &&
03064 result->part1==0xf0f0 && result->part2==0xf0f0 &&
03065 result->part3==0xf0f0 && result->part4==0xf0f0) {
03066 return;
03067 }
03068 }
03069 }
03070
03071 ar_internal_error(2012, __FILE__, __LINE__);
03072 }
03073
03074 #endif
03075
03076 static char USMID [] = "\n%Z%%M% %I% %G% %U%\n";
03077 static char rcsid [] = "$Id: mpp_sim.c,v 1.1.1.1 2002-05-22 20:06:19 dsystem Exp $";