00249 {
00250
00251
EM_uint64_t BundleHigh;
00252
EM_uint64_t BundleLow;
00253
EM_uint_t ISRlow;
00254
EM_uint_t ei;
00255
EM_uint64_t OpCode;
00256
00257
EM_uint_t fault_ISR_code;
00258
EM_uint_t trap_ISR_code;
00259
00260
EM_uint64_t FPSR;
00261
EM_uint64_t FPSR1;
00262
EM_uint64_t CFM;
00263
00264
00265
EM_opcode_sf_type sf;
00266
EM_pred_reg_specifier qp;
00267
EM_fp_reg_specifier f1;
00268
EM_fp_reg_specifier f2;
00269
EM_fp_reg_specifier f3;
00270
EM_fp_reg_specifier f4;
00271
EM_pred_reg_specifier p1;
00272
EM_pred_reg_specifier p2;
00273
00274
EM_opcode_pc_type opcode_pc;
00275
EM_sf_pc_type pc;
00276
EM_sf_rc_type rc;
00277
EM_uint_t wre;
00278
00279
int significand_size;
00280
00281
EM_uint_t fpa, fpa_lo, fpa_hi;
00282
EM_uint_t I_exc, I_exc_lo, I_exc_hi;
00283
EM_uint_t U_exc, U_exc_lo, U_exc_hi;
00284
EM_uint_t O_exc, O_exc_lo, O_exc_hi;
00285
EM_uint_t sign, sign_lo, sign_hi;
00286
EM_uint_t exponent, exponent_lo, exponent_hi;
00287
EM_uint64_t significand;
00288
EM_uint_t significand_lo, significand_hi;
00289
EM_uint64_t low_half;
00290
EM_uint64_t high_half;
00291
EM_uint_t lsb, lsb_lo, lsb_hi;
00292
EM_uint_t round, round_lo, round_hi;
00293
EM_uint_t sticky, sticky_lo, sticky_hi;
00294
EM_uint_t I_dis, U_dis, O_dis;
00295
EM_uint_t Z_dis, D_dis, V_dis;
00296
00297
EM_fp_reg_type tmp_fp;
00298
00299
EM_int_t true_bexp, true_bexp_lo, true_bexp_hi;
00300
EM_int_t shift_cnt, shift_cnt_lo, shift_cnt_hi;
00301
EM_int_t emin;
00302
EM_int_t decr_exp, decr_exp_lo, decr_exp_hi;
00303
int ind;
00304
00305
EM_uint_t EmulationExceptionCode;
00306
00307
EM_state_type proc_state, *ps;
00308
00309
EM_uint_t SIMD_instruction;
00310
00311
00312
00313
00314
EM_uint_t sign_a;
00315
EM_int_t exponent_a;
00316
EM_uint64_t significand_a;
00317
EM_uint_t sign_b;
00318
EM_int_t exponent_b;
00319
EM_uint64_t significand_b;
00320
EM_int_t sign_c;
00321
EM_int_t exponent_c;
00322
EM_uint64_t significand_c;
00323
00324
FLOAT128_TYPE a_float128;
00325
FLOAT128_TYPE b_float128;
00326
FLOAT128_TYPE c_float128;
00327
FLOAT128_TYPE c1_float128;
00328
FLOAT128_TYPE d_float128;
00329
FLOAT128_TYPE s_float128;
00330
int I_flag;
00331
int ftz;
00332
int unnormal;
00333
int new_trap_type;
00334
00335
00336
int lf1 = 5;
00337
int lf2 = 2;
00338
int lf3 = 3;
00339
int lf4 = 4;
00340
00341
unsigned int rrbpr;
00342
unsigned int rrbfr;
00343
00344
00345
#ifdef DEBUG_UNIX
00346
printf (
"**** DEBUG: ENTERING fp_emulate () ****\n");
00347
#endif
00348
00349 ps = &proc_state;
00350
EM_initialize_state (ps);
00351
00352
#ifndef unix
00353
f1 = 127;
00354
#endif
00355
SIMD_instruction = 2;
00356 ei = (
EM_uint_t)0;
00357 OpCode = (
EM_uint64_t)0;
00358
00359 BundleLow = pbundle->
BundleLow;
00360 BundleHigh = pbundle->
BundleHigh;
00361
#ifdef DEBUG_UNIX
00362
printf (
"fp_emulate DEBUG: Bundle High/Low = %Lx %Lx\n",
00363 BundleHigh, BundleLow);
00364
#endif
00365
00366 ISRlow = (
EM_uint_t)(*pisr);
00367
00368
00369
FPSR = *pfpsr;
00370 CFM = *pifs &
CONST_FORMAT(0x03fffffffff);
00371 rrbpr = (
unsigned int)((CFM >> 32) & 0x3f);
00372 rrbfr = (
unsigned int)((CFM >> 25) & 0x7f);
00373
#ifdef DEBUG_UNIX
00374
printf (
"fp_emulate DEBUG: FPSR = %Lx\n", FPSR);
00375 printf (
"fp_emulate DEBUG: CFM = %Lx\n", CFM);
00376 printf (
"fp_emulate DEBUG: rrbpr = %x rrbfr = %x\n", rrbpr, rrbfr);
00377 printf (
"fp_emulate DEBUG: PREDS = %Lx\n", *ppreds);
00378 printf (
"fp_emulate DEBUG: ISRlow = %x\n", ISRlow);
00379
#endif
00380
00381
00382 ps->
state_AR[0].
uint_value =
FPSR;
00383
00384
#ifdef DEBUG_UNIX
00385
OpCode = (BundleLow >> 5) &
CONST_FORMAT(0x01ffffffffff);
00386 printf (
"DEBUG: OpCode0 = %Lx\n", OpCode);
00387 OpCode = ((BundleHigh &
CONST_FORMAT(0x07fffff)) << 18) |
00388 ((BundleLow >> 46) &
CONST_FORMAT(0x03ffff));
00389 printf (
"DEBUG: OpCode1 = %Lx\n", OpCode);
00390 OpCode = (BundleHigh >> 23) &
CONST_FORMAT(0x01ffffffffff);
00391 printf (
"DEBUG: OpCode2 = %Lx\n", OpCode);
00392
#endif
00393
00394
00395 ei = (
EM_uint_t)(((*pisr) >> 41) & 0x03);
00396
00397
if (ei == 0) {
00398
00399
#ifndef unix
00400
# if DBG
00401
DbgPrint (
"fp_emulate () Internal Error: template FXX\n");
00402
# endif
00403
#else
00404
FP_EMULATION_ERROR0 (
"fp_emulate () Internal Error: template FXX\n");
00405
return (
FP_EMUL_ERROR);
00406
#endif
00407
}
else if (ei == 1) {
00408 OpCode = ((BundleHigh &
CONST_FORMAT(0x07fffff)) << 18) |
00409 ((BundleLow >> 46) &
CONST_FORMAT(0x03ffff));
00410
#ifdef DEBUG_UNIX
00411
printf (
"DEBUG: ei = 1 OpCode = %Lx\n", OpCode);
00412
#endif
00413
}
else if (ei == 2) {
00414 OpCode = (BundleHigh >> 23) &
CONST_FORMAT(0x01ffffffffff);
00415
#ifdef DEBUG_UNIX
00416
printf (
"DEBUG: ei = 2 OpCode = %Lx\n", OpCode);
00417
#endif
00418
}
else {
00419
#ifndef unix
00420
# if DBG
00421
DbgPrint (
"fp_emulate () Internal Error: instruction slot 3 is invalid\n");
00422
# endif
00423
#else
00424
FP_EMULATION_ERROR0 (
"fp_emulate () Internal Error: \
00425
instruction slot 3 is not valid\n");
00426
return (
FP_EMUL_ERROR);
00427
#endif
00428
}
00429
00430
00431
00432
00433
00434 sf = (
EM_opcode_sf_type)((OpCode >> 34) &
CONST_FORMAT(0x000000000003));
00435 qp = (
EM_uint_t)(OpCode &
CONST_FORMAT(0x00000000003F));
00436
if (qp >= 16) qp = 16 + (rrbpr + qp - 16) % 48;
00437
00438
00439 ps->
state_PR[qp] = (
EM_boolean_t)(((*ppreds) >> qp) & 0x01);
00440
00441
if (ps->
state_PR[qp] == 0) {
00442
#ifdef DEBUG_UNIX
00443
printf (
"fp_emulate DEBUG: QUALIFYING PREDICATE %d IS 0\n", qp);
00444
#endif
00445
#ifndef unix
00446
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
00447
qualifying predicate PR[%2.2d] = 0\n", qp);
00448
#else
00449
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
00450
qualifying predicate PR[%2.2d] = 0\n", qp);
00451
return (
FP_EMUL_ERROR);
00452
#endif
00453
}
00454
00455 I_dis = sf != 0 && ((
FPSR >> (6 + 6 + 13 * (
EM_uint_t)sf)) & 0x01) ||
00456 ((
FPSR >> 5) & 0x01);
00457 U_dis = sf != 0 && ((
FPSR >> (6 + 6 + 13 * (
EM_uint_t)sf)) & 0x01) ||
00458 ((
FPSR >> 4) & 0x01);
00459 O_dis = sf != 0 && ((
FPSR >> (6 + 6 + 13 * (
EM_uint_t)sf)) & 0x01) ||
00460 ((
FPSR >> 3) & 0x01);
00461 Z_dis = sf != 0 && ((
FPSR >> (6 + 6 + 13 * (
EM_uint_t)sf)) & 0x01) ||
00462 ((
FPSR >> 2) & 0x01);
00463 D_dis = sf != 0 && ((
FPSR >> (6 + 6 + 13 * (
EM_uint_t)sf)) & 0x01) ||
00464 ((
FPSR >> 1) & 0x01);
00465 V_dis = sf != 0 && ((
FPSR >> (6 + 6 + 13 * (
EM_uint_t)sf)) & 0x01) ||
00466 (
FPSR & 0x01);
00467
00468
00469
if ((trap_type ==
FPFLT) &&
00470 (ISRlow & 0x0088)) {
00471
00472
00473
00474
00475
00476
00477
if ((OpCode &
F1_MIN_MASK) ==
F1_PATTERN) {
00478
00479
00480
00481 f4 = (
EM_uint_t)((OpCode >> 27) &
CONST_FORMAT(0x00000000007F));
00482
if (f4 >= 32) f4 = 32 + (rrbfr + f4 - 32) % 96;
00483 f3 = (
EM_uint_t)((OpCode >> 20) &
CONST_FORMAT(0x00000000007F));
00484
if (f3 >= 32) f3 = 32 + (rrbfr + f3 - 32) % 96;
00485 f2 = (
EM_uint_t)((OpCode >> 13) &
CONST_FORMAT(0x00000000007F));
00486
if (f2 >= 32) f2 = 32 + (rrbfr + f2 - 32) % 96;
00487 f1 = (
EM_uint_t)((OpCode >> 6) &
CONST_FORMAT(0x00000000007F));
00488
if (f1 >= 32) f1 = 32 + (rrbfr + f1 - 32) % 96;
00489
00490
#ifdef DEBUG_UNIX
00491
printf (
"DEBUG BEF. F1 SWA FAULT: f1 f2 f3 f4 = %x %x %x %x\n", f1, f2, f3, f4);
00492
#endif
00493
00494
00495 ps->
state_FR[lf2] =
FP128ToFPReg (get_fp_register (f2, fp_state));
00496 ps->
state_FR[lf3] =
FP128ToFPReg (get_fp_register (f3, fp_state));
00497 ps->
state_FR[lf4] =
FP128ToFPReg (get_fp_register (f4, fp_state));
00498
00499
#ifdef DEBUG_UNIX
00500
printf (
"DEBUG BEFORE F1 SWA FAULT: ps->state_FR[lf2] = %x %x %Lx\n",
00501 ps->
state_FR[lf2].
sign, ps->
state_FR[lf2].
exponent, ps->
state_FR[lf2].
significand);
00502 printf (
"DEBUG BEFORE F1 SWA FAULT: ps->state_FR[lf3] = %x %x %Lx\n",
00503 ps->
state_FR[lf3].
sign, ps->
state_FR[lf3].
exponent, ps->
state_FR[lf3].
significand);
00504 printf (
"DEBUG BEFORE F1 SWA FAULT: ps->state_FR[lf4] = %x %x %Lx\n",
00505 ps->
state_FR[lf4].
sign, ps->
state_FR[lf4].
exponent, ps->
state_FR[lf4].
significand);
00506
#endif
00507
00508
switch (OpCode &
F1_MASK) {
00509
00510
case FMA_PATTERN:
00511 SIMD_instruction = 0;
00512
fma (ps, pc_sf, sf, qp, lf1, lf3, lf4, lf2);
00513
break;
00514
case FMA_S_PATTERN:
00515 SIMD_instruction = 0;
00516
fma (ps, pc_s, sf, qp, lf1, lf3, lf4, lf2);
00517
break;
00518
case FMA_D_PATTERN:
00519 SIMD_instruction = 0;
00520
fma (ps, pc_d, sf, qp, lf1, lf3, lf4, lf2);
00521
break;
00522
case FPMA_PATTERN:
00523 SIMD_instruction = 1;
00524
fpma (ps, sf, qp, lf1, lf3, lf4, lf2);
00525
break;
00526
00527
case FMS_PATTERN:
00528 SIMD_instruction = 0;
00529
fms (ps, pc_sf, sf, qp, lf1, lf3, lf4, lf2);
00530
break;
00531
case FMS_S_PATTERN:
00532 SIMD_instruction = 0;
00533
fms (ps, pc_s, sf, qp, lf1, lf3, lf4, lf2);
00534
break;
00535
case FMS_D_PATTERN:
00536 SIMD_instruction = 0;
00537
fms (ps, pc_d, sf, qp, lf1, lf3, lf4, lf2);
00538
break;
00539
case FPMS_PATTERN:
00540 SIMD_instruction = 1;
00541
fpms (ps, sf, qp, lf1, lf3, lf4, lf2);
00542
break;
00543
00544
case FNMA_PATTERN:
00545 SIMD_instruction = 0;
00546
fnma (ps, pc_sf, sf, qp, lf1, lf3, lf4, lf2);
00547
break;
00548
case FNMA_S_PATTERN:
00549 SIMD_instruction = 0;
00550
fnma (ps, pc_s, sf, qp, lf1, lf3, lf4, lf2);
00551
break;
00552
case FNMA_D_PATTERN:
00553 SIMD_instruction = 0;
00554
fnma (ps, pc_d, sf, qp, lf1, lf3, lf4, lf2);
00555
break;
00556
case FPNMA_PATTERN:
00557 SIMD_instruction = 1;
00558
fpnma (ps, sf, qp, lf1, lf3, lf4, lf2);
00559
break;
00560
default:
00561
00562
#ifndef unix
00563
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
00564
instruction opcode %8x %8x not recognized\n", OpCode);
00565
#else
00566
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
00567
instruction opcode %Lx not recognized\n", OpCode);
00568
return (
FP_EMUL_ERROR);
00569
#endif
00570
00571 }
00572
00573
if ((ps->
state_MERCED_RTL >> 16) & 0x0ffff)
goto new_exception;
00574
00575
00576
00577
#ifdef DEBUG_UNIX
00578
printf (
"DEBUG AFTER F1 SWA FAULT: ps->state_FR[lf1] = %x %x %Lx\n",
00579 ps->
state_FR[lf1].
sign, ps->
state_FR[lf1].
exponent,
00580 ps->
state_FR[lf1].
significand);
00581
#endif
00582
set_fp_register (f1,
FPRegToFP128(ps->
state_FR[lf1]), fp_state);
00583
if (f1 < 32)
00584 *pipsr = *pipsr | (
EM_uint64_t)0x10;
00585
else
00586 *pipsr = *pipsr | (
EM_uint64_t)0x20;
00587
00588 *pfpsr = ps->
state_AR[0].
uint_value;
00589
return (
TRUE);
00590
00591
00592 }
else if ((OpCode &
F4_MIN_MASK) ==
F4_PATTERN) {
00593
00594
00595
00596 p2 = (
EM_uint_t)((OpCode >> 27) &
CONST_FORMAT(0x00000000003f));
00597
if (p2 >= 16) p2 = 16 + (rrbpr + p2 - 16) % 48;
00598 f3 = (
EM_uint_t)((OpCode >> 20) &
CONST_FORMAT(0x00000000007F));
00599
if (f3 >= 32) f3 = 32 + (rrbfr + f3 - 32) % 96;
00600 f2 = (
EM_uint_t)((OpCode >> 13) &
CONST_FORMAT(0x00000000007F));
00601
if (f2 >= 32) f2 = 32 + (rrbfr + f2 - 32) % 96;
00602 p1 = (
EM_uint_t)((OpCode >> 6) &
CONST_FORMAT(0x00000000003F));
00603
if (p1 >= 16) p1 = 16 + (rrbpr + p1 - 16) % 48;
00604
00605
00606 ps->
state_FR[lf2] =
FP128ToFPReg (get_fp_register (f2, fp_state));
00607 ps->
state_FR[lf3] =
FP128ToFPReg (get_fp_register (f3, fp_state));
00608
#ifdef DEBUG_UNIX
00609
printf (
"DEBUG BEFORE F4 SWA FAULT: ps->state_FR[lf2] = %x %x %Lx\n",
00610 ps->
state_FR[lf2].
sign, ps->
state_FR[lf2].
exponent, ps->
state_FR[lf2].
significand);
00611 printf (
"DEBUG BEFORE F4 SWA FAULT: ps->state_FR[lf3] = %x %x %Lx\n",
00612 ps->
state_FR[lf3].
sign, ps->
state_FR[lf3].
exponent, ps->
state_FR[lf3].
significand);
00613
#endif
00614
00615
switch (OpCode &
F4_MASK) {
00616
00617
case FCMP_EQ_PATTERN:
00618 SIMD_instruction = 0;
00619
fcmp_eq (ps, ctype_none, sf, qp, p1, p2, lf2, lf3);
00620
break;
00621
case FCMP_LT_PATTERN:
00622 SIMD_instruction = 0;
00623
fcmp_lt (ps, ctype_none, sf, qp, p1, p2, lf2, lf3);
00624
break;
00625
case FCMP_LE_PATTERN:
00626 SIMD_instruction = 0;
00627
fcmp_le (ps, ctype_none, sf, qp, p1, p2, lf2, lf3);
00628
break;
00629
case FCMP_UNORD_PATTERN:
00630 SIMD_instruction = 0;
00631
fcmp_unord (ps, ctype_none, sf, qp, p1, p2, lf2, lf3);
00632
break;
00633
00634
case FCMP_EQ_UNC_PATTERN:
00635 SIMD_instruction = 0;
00636
fcmp_eq (ps, fctypeUNC, sf, qp, p1, p2, lf2, lf3);
00637
break;
00638
case FCMP_LT_UNC_PATTERN:
00639 SIMD_instruction = 0;
00640
fcmp_lt (ps, fctypeUNC, sf, qp, p1, p2, lf2, lf3);
00641
break;
00642
case FCMP_LE_UNC_PATTERN:
00643 SIMD_instruction = 0;
00644
fcmp_le (ps, fctypeUNC, sf, qp, p1, p2, lf2, lf3);
00645
break;
00646
case FCMP_UNORD_UNC_PATTERN:
00647 SIMD_instruction = 0;
00648
fcmp_unord (ps, fctypeUNC, sf, qp, p1, p2, lf2, lf3);
00649
break;
00650
default:
00651
00652
#ifndef unix
00653
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
00654
instruction opcode %8x %8x not recognized\n", OpCode);
00655
#else
00656
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
00657
instruction opcode %Lx not recognized\n", OpCode);
00658
return (
FP_EMUL_ERROR);
00659
#endif
00660
00661 }
00662
00663
if ((ps->
state_MERCED_RTL >> 16) & 0x0ffff)
goto new_exception;
00664
00665
00666
00667 *ppreds &= (~(((
EM_uint64_t)1) << (
EM_uint_t)p1));
00668 *ppreds |= (((
EM_uint64_t)(ps->
state_PR[p1] & 0x01)) << (
EM_uint_t)p1);
00669 *ppreds &= (~(((
EM_uint64_t)1) << (
EM_uint_t)p2));
00670 *ppreds |= (((
EM_uint64_t)(ps->
state_PR[p2] & 0x01)) << (
EM_uint_t)p2);
00671 *pfpsr = ps->
state_AR[0].
uint_value;
00672
#ifdef DEBUG_UNIX
00673
printf (
"DEBUG AFTER F4 SWA FAULT: *ppreds = %Lx\n", (*ppreds));
00674
#endif
00675
return (
TRUE);
00676
00677 }
else if ((OpCode &
F6_MIN_MASK) ==
F6_PATTERN) {
00678
00679
switch (OpCode &
F6_MASK) {
00680
00681
case FRCPA_PATTERN:
00682 SIMD_instruction = 0;
00683
break;
00684
case FPRCPA_PATTERN:
00685 SIMD_instruction = 1;
00686
break;
00687
default:
00688
00689
#ifndef unix
00690
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
00691
instruction opcode %8x %8x not recognized\n", OpCode);
00692
#else
00693
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
00694
instruction opcode %Lx not recognized\n", OpCode);
00695
return (
FP_EMUL_ERROR);
00696
#endif
00697
}
00698
00699
00700 ftz = (
int)((
FPSR >> 6) & 0x01);
00701
00702
00703 rc = (
EM_sf_rc_type)((
FPSR >> (6 + 4 + 13 * (
EM_uint_t)sf)) & 0x03);
00704
00705
00706 p2 = (
EM_uint_t)((OpCode >> 27) &
CONST_FORMAT(0x00000000003f));
00707
if (p2 >= 16) p2 = 16 + (rrbpr + p2 - 16) % 48;
00708 f3 = (
EM_uint_t)((OpCode >> 20) &
CONST_FORMAT(0x00000000007F));
00709
if (f3 >= 32) f3 = 32 + (rrbfr + f3 - 32) % 96;
00710 f2 = (
EM_uint_t)((OpCode >> 13) &
CONST_FORMAT(0x00000000007F));
00711
if (f2 >= 32) f2 = 32 + (rrbfr + f2 - 32) % 96;
00712 f1 = (
EM_uint_t)((OpCode >> 6) &
CONST_FORMAT(0x00000000007F));
00713
if (f1 >= 32) f1 = 32 + (rrbfr + f1 - 32) % 96;
00714
00715
00716 ps->
state_FR[lf2] =
FP128ToFPReg (get_fp_register (f2, fp_state));
00717 ps->
state_FR[lf3] =
FP128ToFPReg (get_fp_register (f3, fp_state));
00718
#ifdef DEBUG_UNIX
00719
printf (
"DEBUG BEFORE F6 SWA FAULT: ps->state_FR[lf2] = %x %x %Lx\n",
00720 ps->
state_FR[lf2].
sign, ps->
state_FR[lf2].
exponent, ps->
state_FR[lf2].
significand);
00721 printf (
"DEBUG BEFORE F6 SWA FAULT: ps->state_FR[lf3] = %x %x %Lx\n",
00722 ps->
state_FR[lf3].
sign, ps->
state_FR[lf3].
exponent, ps->
state_FR[lf3].
significand);
00723
#endif
00724
00725
switch (OpCode &
F6_MASK) {
00726
00727
case FRCPA_PATTERN:
00728
00729
00730 sign_a = (
EM_uint_t)ps->
state_FR[lf2].
sign;
00731 exponent_a = (
EM_int_t)ps->
state_FR[lf2].
exponent;
00732 significand_a = ps->
state_FR[lf2].
significand;
00733
00734
00735
00736 sign_b = (
EM_uint_t)ps->
state_FR[lf3].
sign;
00737 exponent_b = (
EM_int_t)ps->
state_FR[lf3].
exponent;
00738 significand_b = ps->
state_FR[lf3].
significand;
00739
00740
00741
if (significand_a == 0 || significand_b == 0) {
00742
00743
frcpa (ps, sf, qp, lf1, p2, lf2, lf3);
00744
00745
if ((ps->
state_MERCED_RTL >> 16) & 0x0ffff)
goto new_exception;
00746
00747 *pfpsr = ps->
state_AR[0].
uint_value;
00748
00749
00750
#ifdef DEBUG_UNIX
00751
printf (
"DEBUG AFTER F6 SWA FAULT FOR a OR b ZERO/PSEUDO-ZERO: ps->state_FR[lf1] = %x %x %Lx\n",
00752 ps->
state_FR[lf1].
sign, ps->
state_FR[lf1].
exponent,
00753 ps->
state_FR[lf1].
significand);
00754
#endif
00755
set_fp_register (f1,
FPRegToFP128(ps->
state_FR[lf1]), fp_state);
00756
if (f1 < 32)
00757 *pipsr = *pipsr | (
EM_uint64_t)0x10;
00758
else
00759 *pipsr = *pipsr | (
EM_uint64_t)0x20;
00760
00761 *ppreds &= (~(((
EM_uint64_t)1) << (
EM_uint_t)p2));
00762
#ifdef DEBUG_UNIX
00763
printf (
"DEBUG AFTER F6 SWA FAULT FOR a OR b ZERO/PSEUDO-ZERO: p2 = %x\n", p2);
00764
#endif
00765
#ifdef DEBUG_UNIX
00766
printf (
"DEBUG AFTER F6 SWA FAULT FOR a OR b ZERO/PSEUDO-ZERO: *ppreds = %Lx\n",
00767 *ppreds);
00768
#endif
00769
return (
TRUE);
00770
00771 }
00772
00773
00774
if (exponent_a == 0x1ffff &&
00775 significand_a ==
CONST_FORMAT(0x8000000000000000) ||
00776 exponent_b == 0x1ffff &&
00777 significand_b ==
CONST_FORMAT(0x8000000000000000)) {
00778
00779
frcpa (ps, sf, qp, lf1, p2, lf2, lf3);
00780
00781
if ((ps->
state_MERCED_RTL >> 16) & 0x0ffff)
goto new_exception;
00782
00783
00784 *pfpsr = ps->
state_AR[0].
uint_value;
00785
00786
00787
#ifdef DEBUG_UNIX
00788
printf (
"DEBUG AFTER F6 SWA FAULT FOR a OR b INFINITY: ps->state_FR[lf1] = %x %x %Lx\n",
00789 ps->
state_FR[lf1].
sign, ps->
state_FR[lf1].
exponent,
00790 ps->
state_FR[lf1].
significand);
00791
#endif
00792
set_fp_register (f1,
FPRegToFP128(ps->
state_FR[lf1]), fp_state);
00793
if (f1 < 32)
00794 *pipsr = *pipsr | (
EM_uint64_t)0x10;
00795
else
00796 *pipsr = *pipsr | (
EM_uint64_t)0x20;
00797
00798
00799 *ppreds &= (~(((
EM_uint64_t)1) << (
EM_uint_t)p2));
00800
#ifdef DEBUG_UNIX
00801
printf (
"DEBUG AFTER F6 SWA FAULT FOR a OR b INFINITY: p2 = %x\n", p2);
00802
#endif
00803
#ifdef DEBUG_UNIX
00804
printf (
"DEBUG AFTER F6 SWA FAULT FOR a OR b INFINITY: *ppreds = %Lx\n",
00805 *ppreds);
00806
#endif
00807
return (
TRUE);
00808
00809 }
00810
00811
00812
00813
00814
if (exponent_a == 0) exponent_a = 0xc001;
00815
00816
00817 exponent_a = exponent_a - 0xffff;
00818
00819
if (exponent_b == 0) exponent_b = 0xc001;
00820
00821
00822 exponent_b = exponent_b - 0xffff;
00823
00824 unnormal = 0;
00825
00826
00827
if (!(significand_a &
CONST_FORMAT(0x8000000000000000))) {
00828 unnormal = 1;
00829 }
00830
00831
00832
if (!(significand_b &
CONST_FORMAT(0x8000000000000000))) {
00833 unnormal = 1;
00834 }
00835
#ifdef DEBUG_UNIX
00836
if (unnormal) printf (
"DEBUG F6 FRCPA SWA FAULT: unnormal = 1\n");
00837
#endif
00838
00839
if (unnormal && !D_dis) {
00840 ISRlow = 0x0002;
00841 *pisr = ((*pisr) & 0xffffffffffff0000) | ISRlow;
00842
return (
FALSE);
00843 }
00844
00845
00846
while (!(significand_a &
CONST_FORMAT(0x8000000000000000))) {
00847 significand_a = significand_a << 1;
00848 exponent_a--;
00849 }
00850
00851
00852
while (!(significand_b &
CONST_FORMAT(0x8000000000000000))) {
00853 significand_b = significand_b << 1;
00854 exponent_b--;
00855 }
00856
00857
00858
00859
00860
if ((exponent_b <= exponent_a -
FP_REG_EMAX - 2) ||
00861 (exponent_b == exponent_a -
FP_REG_EMAX - 1) &&
00862 (significand_a >= significand_b)) {
00863
00864
#ifdef DEBUG_UNIX
00865
printf (
"DEBUG: BEGIN F6 SWA FAULT CASE (I) - (II)\n");
00866
#endif
00867
00868
00869
00870
00871
00872 ps->
state_FR[lf2].
exponent = (
EM_uint_t)(0xffff);
00873 ps->
state_FR[lf2].
significand = significand_a;
00874
00875
00876 ps->
state_FR[lf3].
exponent = (
EM_uint_t)(0xffff);
00877 ps->
state_FR[lf3].
significand = significand_b;
00878
00879
00880 a_float128 =
FPRegToFP128 (ps->
state_FR[lf2]);
00881 b_float128 =
FPRegToFP128 (ps->
state_FR[lf3]);
00882
00883
00884
00885
00886
00887 FPSR1 = (
EM_uint64_t)((
FPSR >> ((
EM_uint_t)sf * 13)) & 0x01fc0)
00888 | 0x000000000270003f;
00889
thmF (&FPSR1, &a_float128, &b_float128, &c_float128);
00890 I_flag = FPSR1 & 0x40000 ? 1 : 0;
00891
00892
if (O_dis && (I_dis || !I_flag)) {
00893
00894
00895
00896
00897
00898
if (sign_a ^ sign_b) {
00899
if (rc ==
rc_rn || rc ==
rc_rm) {
00900
00901 ps->
state_FR[lf1].
sign = 1;
00902 ps->
state_FR[lf1].
exponent = 0x1ffff;
00903 ps->
state_FR[lf1].
significand =
00904
CONST_FORMAT(0x8000000000000000);
00905 }
else {
00906
00907 ps->
state_FR[lf1].
sign = 1;
00908 ps->
state_FR[lf1].
exponent = 0x1fffe;
00909 ps->
state_FR[lf1].
significand =
00910
CONST_FORMAT(0xffffffffffffffff);
00911 }
00912 }
else {
00913
if (rc ==
rc_rn || rc ==
rc_rp) {
00914
00915 ps->
state_FR[lf1].
sign = 0;
00916 ps->
state_FR[lf1].
exponent = 0x1ffff;
00917 ps->
state_FR[lf1].
significand =
00918
CONST_FORMAT(0x8000000000000000);
00919 }
else {
00920
00921 ps->
state_FR[lf1].
sign = 0;
00922 ps->
state_FR[lf1].
exponent = 0x1fffe;
00923 ps->
state_FR[lf1].
significand =
00924
CONST_FORMAT(0xffffffffffffffff);
00925 }
00926 }
00927
00928
00929
if (unnormal) {
00930
00931 *pfpsr = *pfpsr |
00932 ((
EM_uint64_t)1 << (6 + (
EM_uint_t)sf * 13 + 8));
00933 }
00934
00935
00936
00937 *pfpsr = *pfpsr |
00938 ((
EM_uint64_t)1 << (6 + (
EM_uint_t)sf * 13 + 10));
00939
00940 *pfpsr = *pfpsr |
00941 ((
EM_uint64_t)1 << (6 + (
EM_uint_t)sf * 13 + 12));
00942
00943
#ifdef DEBUG_UNIX
00944
printf (
"DEBUG Case (I), (II) AFTER F6 SWA FAULT 1: ps->state_FR[lf1] = %x %x %Lx\n",
00945 ps->
state_FR[lf1].
sign, ps->
state_FR[lf1].
exponent,
00946 ps->
state_FR[lf1].
significand);
00947
#endif
00948
set_fp_register (f1,
FPRegToFP128(ps->
state_FR[lf1]), fp_state);
00949
if (f1 < 32)
00950 *pipsr = *pipsr | (
EM_uint64_t)0x10;
00951
else
00952 *pipsr = *pipsr | (
EM_uint64_t)0x20;
00953
00954
00955 *ppreds &= (~(((
EM_uint64_t)1) << (
EM_uint_t)p2));
00956
#ifdef DEBUG_UNIX
00957
printf (
"DEBUG Case (I), (II) AFTER F6 SWA FAULT 1 a: *ppreds = %Lx\n",
00958 *ppreds);
00959
#endif
00960
return (
TRUE);
00961
00962 }
else if (!O_dis) {
00963
00964
00965
00966
00967
00968
00969 ps->
state_FR[lf1] =
FP128ToFPReg (c_float128);
00970
00971 exponent_c = (
EM_uint_t)ps->
state_FR[lf1].
exponent +
00972 exponent_a - exponent_b;
00973 ISRlow = 0x0801;
00974 ps->
state_FR[lf1].
exponent = exponent_c & 0x1ffff;
00975
00976
00977
00978
if (I_flag == 1) {
00979
00980
00981 c_float128.hiFlt64 = c_float128.hiFlt64 &
00982
CONST_FORMAT(0x000000000001ffff);
00983 b_float128.hiFlt64 = b_float128.hiFlt64 &
00984
CONST_FORMAT(0x000000000001ffff);
00985 a_float128.hiFlt64 = a_float128.hiFlt64 &
00986
CONST_FORMAT(0x000000000001ffff);
00987
00988 FPSR1 =
CONST_FORMAT(0x00000000000003bf);
00989
run_fms (&FPSR1, &d_float128, &b_float128, &c_float128,
00990 &a_float128);
00991
00992
if (d_float128.hiFlt64 &
CONST_FORMAT(0x020000)) {
00993
00994 ISRlow = ISRlow | 0x2000;
00995 }
else {
00996
00997 ISRlow = ISRlow | 0x6000;
00998 }
00999
01000 }
01001
01002
01003 *pisr = ((*pisr) & 0xffffffffffff0000) | ISRlow;
01004
01005
#ifdef DEBUG_UNIX
01006
printf (
"DEBUG Case (I), (II) AFTER F6 SWA FAULT 2: ps->state_FR[lf1] = %x %x %Lx\n",
01007 ps->
state_FR[lf1].
sign, ps->
state_FR[lf1].
exponent,
01008 ps->
state_FR[lf1].
significand);
01009
#endif
01010
set_fp_register (f1,
FPRegToFP128(ps->
state_FR[lf1]), fp_state);
01011
if (f1 < 32)
01012 *pipsr = *pipsr | (
EM_uint64_t)0x10;
01013
else
01014 *pipsr = *pipsr | (
EM_uint64_t)0x20;
01015
01016
01017
01018 *ppreds &= (~(((
EM_uint64_t)1) << (
EM_uint_t)p2));
01019
#ifdef DEBUG_UNIX
01020
printf (
"DEBUG Case (I), (II) AFTER F6 SWA FAULT 2 a: *ppreds = %Lx\n", *ppreds);
01021
#endif
01022
01023
01024
if (unnormal) {
01025
01026 *pfpsr = *pfpsr |
01027 ((
EM_uint64_t)1 << (6 + (
EM_uint_t)sf * 13 + 8));
01028 }
01029
01030 *pfpsr = *pfpsr |
01031 ((
EM_uint64_t)1 << (6 + (
EM_uint_t)sf * 13 + 10));
01032
01033
if (I_flag) *pfpsr = *pfpsr |
01034 ((
EM_uint64_t)1 << (6 + (
EM_uint_t)sf * 13 + 12));
01035
01036
01037
return (
FALSE |
FAULT_TO_TRAP);
01038
01039 }
else {
01040
01041
01042
01043
01044
01045
01046
if (sign_a ^ sign_b) {
01047
if (rc ==
rc_rn || rc ==
rc_rm) {
01048
01049 ps->
state_FR[lf1].
sign = 1;
01050 ps->
state_FR[lf1].
exponent = 0x1ffff;
01051 ps->
state_FR[lf1].
significand =
01052
CONST_FORMAT(0x8000000000000000);
01053 fpa = 1;
01054 }
else {
01055
01056 ps->
state_FR[lf1].
sign = 1;
01057 ps->
state_FR[lf1].
exponent = 0x1fffe;
01058 ps->
state_FR[lf1].
significand =
01059
CONST_FORMAT(0xffffffffffffffff);
01060 fpa = 0;
01061 }
01062 }
else {
01063
if (rc ==
rc_rn || rc ==
rc_rp) {
01064
01065 ps->
state_FR[lf1].
sign = 0;
01066 ps->
state_FR[lf1].
exponent = 0x1ffff;
01067 ps->
state_FR[lf1].
significand =
01068
CONST_FORMAT(0x8000000000000000);
01069 fpa = 1;
01070 }
else {
01071
01072 ps->
state_FR[lf1].
sign = 0;
01073 ps->
state_FR[lf1].
exponent = 0x1fffe;
01074 ps->
state_FR[lf1].
significand =
01075
CONST_FORMAT(0xffffffffffffffff);
01076 fpa = 0;
01077 }
01078 }
01079
01080 ISRlow = 0x2001 | (fpa == 1 ? 0x4000 : 0x0000);
01081 *pisr = ((*pisr) & 0xffffffffffff0000) | ISRlow;
01082
01083
01084
#ifdef DEBUG_UNIX
01085
printf (
"DEBUG Case (I), (II) AFTER F6 SWA FAULT 3: ps->state_FR[lf1] = %x %x %Lx\n",
01086 ps->
state_FR[lf1].
sign, ps->
state_FR[lf1].
exponent,
01087 ps->
state_FR[lf1].
significand);
01088
#endif
01089
set_fp_register (f1,
FPRegToFP128(ps->
state_FR[lf1]), fp_state);
01090
if (f1 < 32)
01091 *pipsr = *pipsr | (
EM_uint64_t)0x10;
01092
else
01093 *pipsr = *pipsr | (
EM_uint64_t)0x20;
01094
01095
01096
01097 *ppreds &= (~(((
EM_uint64_t)1) << (
EM_uint_t)p2));
01098
#ifdef DEBUG_UNIX
01099
printf (
"DEBUG Case (I), (II) AFTER F6 SWA FAULT 3 a: *ppreds = %Lx\n",
01100 *ppreds);
01101
#endif
01102
01103
01104
if (unnormal) {
01105
01106 *pfpsr = *pfpsr |
01107 ((
EM_uint64_t)1 << (6 + (
EM_uint_t)sf * 13 + 8));
01108 }
01109
01110
01111 *pfpsr = *pfpsr |
01112 ((
EM_uint64_t)1 << (6 + (
EM_uint_t)sf * 13 + 10));
01113
01114 *pfpsr = *pfpsr |
01115 ((
EM_uint64_t)1 << (6 + (
EM_uint_t)sf * 13 + 12));
01116
01117
01118
return (
FALSE |
FAULT_TO_TRAP);
01119
01120 }
01121
01122
01123
01124
01125 }
else if ((exponent_b == exponent_a -
FP_REG_EMAX - 1) &&
01126 (significand_a < significand_b) ||
01127 (exponent_b == exponent_a -
FP_REG_EMAX) ||
01128 (exponent_a -
FP_REG_EMAX + 1 <= exponent_b ) &&
01129 (exponent_b <= exponent_a -
FP_REG_EMIN - 2) &&
01130 ((exponent_a <=
FP_REG_EMIN +
N64 - 1) ||
01131 (exponent_b <=
FP_REG_EMIN - 1) ||
01132 (exponent_b >=
FP_REG_EMAX - 2)) ||
01133 (exponent_b == exponent_a -
FP_REG_EMIN - 1) ||
01134 (exponent_b == exponent_a -
FP_REG_EMIN) &&
01135 (significand_a >= significand_b)) {
01136
01137
#ifdef DEBUG_UNIX
01138
printf (
"DEBUG: BEGIN F6 SWA FAULT CASE (III) - (VII)\n");
01139
#endif
01140
01141
01142
01143
01144
01145 ps->
state_FR[lf2].
exponent = (
EM_uint_t)(0xffff);
01146 ps->
state_FR[lf2].
significand = significand_a;
01147
01148
01149 ps->
state_FR[lf3].
exponent = (
EM_uint_t)(0xffff);
01150 ps->
state_FR[lf3].
significand = significand_b;
01151
01152
01153 a_float128 =
FPRegToFP128 (ps->
state_FR[lf2]);
01154 b_float128 =
FPRegToFP128 (ps->
state_FR[lf3]);
01155
01156
01157
01158
01159
01160 FPSR1 = (
EM_uint64_t)((
FPSR >> ((
EM_uint_t)sf * 13)) & 0x01fc0)
01161 | 0x000000000270003f;
01162
thmF (&FPSR1, &a_float128, &b_float128, &c_float128);
01163 I_flag = FPSR1 & 0x40000 ? 1 : 0;
01164
01165
01166
01167 ps->
state_FR[lf1] =
FP128ToFPReg (c_float128);
01168
01169 ps->
state_FR[lf1].
exponent = (
EM_uint_t)ps->
state_FR[lf1].
exponent
01170 + exponent_a - exponent_b;
01171
01172
if (I_dis || !I_flag) {
01173
01174
01175
if (unnormal) {
01176
01177 *pfpsr = *pfpsr |
01178 ((
EM_uint64_t)1 << (6 + (
EM_uint_t)sf * 13 + 8));
01179 }
01180
01181
01182
if (I_flag) *pfpsr = *pfpsr |
01183 ((
EM_uint64_t)1 << (6 + (
EM_uint_t)sf * 13 + 12));
01184
01185
#ifdef DEBUG_UNIX
01186
printf (
"DEBUG Case (III) - (VII) AFTER F6 SWA FAULT 4: ps->state_FR[lf1] = %x %x %Lx\n",
01187 ps->
state_FR[lf1].
sign, ps->
state_FR[lf1].
exponent,
01188 ps->
state_FR[lf1].
significand);
01189
#endif
01190
set_fp_register (f1,
FPRegToFP128(ps->
state_FR[lf1]), fp_state);
01191
if (f1 < 32)
01192 *pipsr = *pipsr | (
EM_uint64_t)0x10;
01193
else
01194 *pipsr = *pipsr | (
EM_uint64_t)0x20;
01195
01196
01197 *ppreds &= (~(((
EM_uint64_t)1) << (
EM_uint_t)p2));
01198
#ifdef DEBUG_UNIX
01199
printf (
"DEBUG Case (III) - (VII) AFTER F6 SWA FAULT 4 a: *ppreds = %Lx\n",
01200 *ppreds);
01201
#endif
01202
return (
TRUE);
01203
01204 }
else {
01205
01206
01207 c_float128.hiFlt64 = c_float128.hiFlt64 &
01208
CONST_FORMAT(0x000000000001ffff);
01209 b_float128.hiFlt64 = b_float128.hiFlt64 &
01210
CONST_FORMAT(0x000000000001ffff);
01211 a_float128.hiFlt64 = a_float128.hiFlt64 &
01212
CONST_FORMAT(0x000000000001ffff);
01213 FPSR1 =
CONST_FORMAT(0x00000000000003bf);
01214
run_fms (&FPSR1, &d_float128, &b_float128, &c_float128,
01215 &a_float128);
01216
01217
if (d_float128.hiFlt64 &
CONST_FORMAT(0x0000000000020000)) {
01218
01219 ISRlow = 0x2001;
01220 }
else {
01221
01222 ISRlow = 0x6001;
01223 }
01224
01225 *pisr = ((*pisr) & 0xffffffffffff0000) | ISRlow;
01226
01227
01228
#ifdef DEBUG_UNIX
01229
printf (
"DEBUG Case (III) - (VII) AFTER F6 SWA FAULT 5: ps->state_FR[lf1] = %x %x %Lx\n",
01230 ps->
state_FR[lf1].
sign, ps->
state_FR[lf1].
exponent,
01231 ps->
state_FR[lf1].
significand);
01232
#endif
01233
set_fp_register (f1,
FPRegToFP128(ps->
state_FR[lf1]), fp_state);
01234
if (f1 < 32)
01235 *pipsr = *pipsr | (
EM_uint64_t)0x10;
01236
else
01237 *pipsr = *pipsr | (
EM_uint64_t)0x20;
01238
01239
01240
01241 *ppreds &= (~(((
EM_uint64_t)1) << (
EM_uint_t)p2));
01242
#ifdef DEBUG_UNIX
01243
printf (
"DEBUG Case (III) -(VII) AFTER F6 SWA FAULT 5 a: *ppreds = %Lx\n",
01244 *ppreds);
01245
#endif
01246
01247
01248
if (unnormal) {
01249
01250 *pfpsr = *pfpsr |
01251 ((
EM_uint64_t)1 << (6 + (
EM_uint_t)sf * 13 + 8));
01252 }
01253
01254
if (I_flag) *pfpsr = *pfpsr |
01255 ((
EM_uint64_t)1 << (6 + (
EM_uint_t)sf * 13 + 12));
01256
01257
01258
return (
FALSE |
FAULT_TO_TRAP);
01259
01260 }
01261
01262
01263
01264
01265
01266
01267
01268 }
else if ( (exponent_b == exponent_a -
FP_REG_EMIN) &&
01269 (significand_a < significand_b) ||
01270 (exponent_b >= exponent_a -
FP_REG_EMIN + 1)) {
01271
01272
#ifdef DEBUG_UNIX
01273
printf (
"DEBUG: BEGIN F6 SWA FAULT CASE (VIII) - (XII)\n");
01274
#endif
01275
01276
01277
01278
01279 ps->
state_FR[lf2].
exponent = (
EM_uint_t)(0xffff);
01280 ps->
state_FR[lf2].
significand = significand_a;
01281
01282
01283 ps->
state_FR[lf3].
exponent = (
EM_uint_t)(0xffff);
01284 ps->
state_FR[lf3].
significand = significand_b;
01285
01286
01287 a_float128 =
FPRegToFP128 (ps->
state_FR[lf2]);
01288 b_float128 =
FPRegToFP128 (ps->
state_FR[lf3]);
01289
01290
01291
01292
01293
01294 FPSR1 = (
EM_uint64_t)((
FPSR >> ((
EM_uint_t)sf * 13)) & 0x01fc0)
01295 | 0x000000000270003f;
01296
thmF (&FPSR1, &a_float128, &b_float128, &c_float128);
01297 I_flag = FPSR1 & 0x40000 ? 1 : 0;
01298
01299 c1_float128 = c_float128;
01300
01301
if (I_flag == 1) {
01302
01303
01304 c1_float128.hiFlt64 = c1_float128.hiFlt64 &
01305
CONST_FORMAT(0x000000000001ffff);
01306 b_float128.hiFlt64 = b_float128.hiFlt64 &
01307
CONST_FORMAT(0x000000000001ffff);
01308 a_float128.hiFlt64 = a_float128.hiFlt64 &
01309
CONST_FORMAT(0x000000000001ffff);
01310 FPSR1 =
CONST_FORMAT(0x00000000000003bf);
01311
run_fms (&FPSR1, &d_float128, &b_float128, &c1_float128,
01312 &a_float128);
01313
if (d_float128.hiFlt64 &
CONST_FORMAT(0x020000)) {
01314
01315 fpa = 0;
01316 }
else {
01317
01318 fpa = 1;
01319 }
01320 }
else {
01321 fpa = 0;
01322 }
01323
01324
if (!U_dis) {
01325
01326
01327
01328
01329
01330
01331 ps->
state_FR[lf1] =
FP128ToFPReg (c_float128);
01332
01333 exponent_c = (
EM_uint_t)ps->
state_FR[lf1].
exponent +
01334 exponent_a - exponent_b;
01335 ps->
state_FR[lf1].
exponent = exponent_c & 0x1ffff;
01336
01337 ISRlow = 0x1001;
01338
01339
if (I_flag == 1) {
01340
if (fpa == 0) {
01341 ISRlow = ISRlow | 0x2000;
01342 }
else {
01343 ISRlow = ISRlow | 0x6000;
01344 }
01345 }
01346
01347 *pisr = ((*pisr) & 0xffffffffffff0000) | ISRlow;
01348
01349
01350
#ifdef DEBUG_UNIX
01351
printf (
"DEBUG Case (VIII) - (XII) AFTER F6 SWA FAULT 7: ps->state_FR[lf1] = %x %x %Lx\n",
01352 ps->
state_FR[lf1].
sign, ps->
state_FR[lf1].
exponent,
01353 ps->
state_FR[lf1].
significand);
01354
#endif
01355
set_fp_register (f1,
FPRegToFP128(ps->
state_FR[lf1]), fp_state);
01356
if (f1 < 32)
01357 *pipsr = *pipsr | (
EM_uint64_t)0x10;
01358
else
01359 *pipsr = *pipsr | (
EM_uint64_t)0x20;
01360
01361
01362
01363 *ppreds &= (~(((
EM_uint64_t)1) << (
EM_uint_t)p2));
01364
#ifdef DEBUG_UNIX
01365
printf (
"DEBUG Case (VIII) - (XII) AFTER F6 SWA FAULT 7 a: *ppreds = %Lx\n",
01366 *ppreds);
01367
#endif
01368
01369
01370
if (unnormal) {
01371
01372 *pfpsr = *pfpsr |
01373 ((
EM_uint64_t)1 << (6 + (
EM_uint_t)sf * 13 + 8));
01374 }
01375
01376 *pfpsr = *pfpsr |
01377 ((
EM_uint64_t)1 << (6 + (
EM_uint_t)sf * 13 + 11));
01378
01379
if (I_flag) {
01380 *pfpsr = *pfpsr |
01381 ((
EM_uint64_t)1 << (6 + (
EM_uint_t)sf * 13 + 12));
01382 }
01383
01384
01385
return (
FALSE |
FAULT_TO_TRAP);
01386
01387 }
else {
01388
01389
01390
01391
01392 ps->
state_FR[lf1] =
FP128ToFPReg (c_float128);
01393
01394
if (ftz == 0) {
01395
01396
01397 sign_c = ps->
state_FR[lf1].
sign;
01398 exponent_c = ps->
state_FR[lf1].
exponent;
01399 significand_c = ps->
state_FR[lf1].
significand;
01400
if (fpa) significand_c = significand_c - 1;
01401
01402
01403
01404
01405
01406
01407 true_bexp = exponent_c + exponent_a - exponent_b;
01408
01409
01410
01411
01412
01413 significand_size =
N64;
01414 shift_cnt =
FP_REG_EMIN - true_bexp + 0x0ffff;
01415
01416
if (shift_cnt <= significand_size) {
01417
01418
01419 round = I_flag;
01420 sticky = 0;
01421
for (ind = 0 ; ind < shift_cnt ; ind++) {
01422 sticky = round | sticky;
01423 round = (
EM_uint_t)(significand_c & 0x01);
01424 significand_c = significand_c >> 1;
01425 }
01426 true_bexp = true_bexp + shift_cnt;
01427 }
else {
01428 significand_c = 0;
01429 round = 0;
01430 sticky = 1;
01431 true_bexp = true_bexp + shift_cnt;
01432 }
01433
01434
01435
01436
switch (rc) {
01437
case rc_rn:
01438 lsb = (
EM_uint_t)(significand_c & 0x01);
01439 fpa = round & (lsb | sticky);
01440
break;
01441
case rc_rm:
01442 fpa = (sign_c == 0 ? 0 : (round | sticky));
01443
break;
01444
case rc_rp:
01445 fpa = (sign_c == 1 ? 0 : (round | sticky));
01446
break;
01447
case rc_rz:
01448 fpa = 0;
01449
break;
01450
default:
01451
#ifndef unix
01452
FP_EMULATION_ERROR1 (
"fp_emulate () Internal \
01453
Error: invalid rc = %d\n", rc);
01454
#else
01455
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
01456
invalid rc = %d\n", rc);
01457
return (
FP_EMUL_ERROR);
01458
#endif
01459
}
01460
01461
01462
01463
if (fpa == 1) {
01464 significand_c = significand_c + 1;
01465 }
01466
01467
if (significand_c == 0) {
01468 true_bexp = 0;
01469 }
01470
01471 exponent_c = true_bexp;
01472
01473
01474 I_flag = round | sticky;
01475
01476 ps->
state_FR[lf1].
exponent = exponent_c;
01477 ps->
state_FR[lf1].
significand = significand_c;
01478
01479 }
else {
01480
01481 fpa = 0;
01482
01483 ps->
state_FR[lf1].
exponent = 0;
01484 ps->
state_FR[lf1].
significand = 0;
01485 I_flag = 1;
01486
01487 }
01488
01489
01490
01491
if (unnormal) {
01492
01493 *pfpsr = *pfpsr |
01494 ((
EM_uint64_t)1 << (6 + (
EM_uint_t)sf * 13 + 8));
01495 }
01496
if (I_flag) {
01497
01498 *pfpsr = *pfpsr |
01499 ((
EM_uint64_t)1 << (6 + (
EM_uint_t)sf * 13 + 11));
01500
01501 *pfpsr = *pfpsr |
01502 ((
EM_uint64_t)1 << (6 + (
EM_uint_t)sf * 13 + 12));
01503 }
01504
01505
01506
#ifdef DEBUG_UNIX
01507
printf (
"DEBUG Case (VIII) - (XII) AFTER F6 SWA FAULT 8: ps->state_FR[lf1] = %x %x %Lx\n",
01508 ps->
state_FR[lf1].
sign, ps->
state_FR[lf1].
exponent,
01509 ps->
state_FR[lf1].
significand);
01510
#endif
01511
set_fp_register (f1,
FPRegToFP128(ps->
state_FR[lf1]), fp_state);
01512
if (f1 < 32)
01513 *pipsr = *pipsr | (
EM_uint64_t)0x10;
01514
else
01515 *pipsr = *pipsr | (
EM_uint64_t)0x20;
01516
01517
01518
01519 *ppreds &= (~(((
EM_uint64_t)1) << (
EM_uint_t)p2));
01520
#ifdef DEBUG_UNIX
01521
printf (
"DEBUG Case (VIII) - (XII) AFTER F6 SWA FAULT 8 a: *ppreds = %Lx\n",
01522 *ppreds);
01523
#endif
01524
01525
if (I_flag && !I_dis) {
01526
01527
01528
01529
01530
01531
01532 ISRlow = 0x2001;
01533
if (fpa) ISRlow = ISRlow | 0x4000;
01534 *pisr = ((*pisr) & 0xffffffffffff0000) | ISRlow;
01535
01536
01537
return (
FALSE |
FAULT_TO_TRAP);
01538
01539 }
01540
01541
return (
TRUE);
01542
01543 }
01544
01545
01546 }
else {
01547
01548
#ifdef DEBUG_UNIX
01549
printf (
"DEBUG: BEGIN F6 SWA FAULT CASE (XIII)\n");
01550
#endif
01551
01552
01553
01554
frcpa (ps, sf, qp, lf1, p2, lf2, lf3);
01555
01556
if ((ps->
state_MERCED_RTL >> 16) & 0x0ffff)
goto new_exception;
01557
01558 *pfpsr = ps->
state_AR[0].
uint_value;
01559
01560
#ifdef DEBUG_UNIX
01561
printf (
"DEBUG Case (XIII) AFTER F6 SWA FAULT 14: ps->state_FR[lf1] = %x %x %Lx\n",
01562 ps->
state_FR[lf1].
sign, ps->
state_FR[lf1].
exponent,
01563 ps->
state_FR[lf1].
significand);
01564
#endif
01565
set_fp_register (f1,
FPRegToFP128(ps->
state_FR[lf1]), fp_state);
01566
if (f1 < 32)
01567 *pipsr = *pipsr | (
EM_uint64_t)0x10;
01568
else
01569 *pipsr = *pipsr | (
EM_uint64_t)0x20;
01570
01571
01572 *ppreds &= (~(((
EM_uint64_t)1) << (
EM_uint_t)p2));
01573 *ppreds |=
01574 (((
EM_uint64_t)(ps->
state_PR[p2] & 0x01)) << (
EM_uint_t)p2);
01575
#ifdef DEBUG_UNIX
01576
printf (
"DEBUG Case (XIII) AFTER F6 SWA FAULT 14 a: *ppreds = %Lx\n",
01577 *ppreds);
01578
#endif
01579
return (
TRUE);
01580
01581 }
01582
01583
break;
01584
01585
case FPRCPA_PATTERN:
01586
01587
01588
fprcpa (ps, sf, qp, lf1, p2, lf2, lf3);
01589
01590
if ((ps->
state_MERCED_RTL >> 16) & 0x0ffff)
goto new_exception;
01591
01592 *pfpsr = ps->
state_AR[0].
uint_value;
01593
01594
01595
#ifdef DEBUG_UNIX
01596
printf (
"DEBUG AFTER F6 FPRCPA SWA FAULT 15: ps->state_FR[lf1] = %x %x %Lx\n",
01597 ps->
state_FR[lf1].
sign, ps->
state_FR[lf1].
exponent,
01598 ps->
state_FR[lf1].
significand);
01599
#endif
01600
set_fp_register (f1,
FPRegToFP128(ps->
state_FR[lf1]), fp_state);
01601
if (f1 < 32)
01602 *pipsr = *pipsr | (
EM_uint64_t)0x10;
01603
else
01604 *pipsr = *pipsr | (
EM_uint64_t)0x20;
01605
01606
01607 *ppreds &= (~(((
EM_uint64_t)1) << (
EM_uint_t)p2));
01608 *ppreds |=
01609 (((
EM_uint64_t)(ps->
state_PR[p2] & 0x01)) << (
EM_uint_t)p2);
01610
#ifdef DEBUG_UNIX
01611
printf (
"DEBUG AFTER F6 FPRCPA SWA FAULT 15 a: *ppreds = %Lx\n",
01612 *ppreds);
01613
#endif
01614
return (
TRUE);
01615
01616 }
01617
01618 }
else if ((OpCode &
F7_MIN_MASK) ==
F7_PATTERN) {
01619
01620
01621
switch (OpCode &
F7_MASK) {
01622
01623
case FRSQRTA_PATTERN:
01624 SIMD_instruction = 0;
01625
break;
01626
case FPRSQRTA_PATTERN:
01627 SIMD_instruction = 1;
01628
break;
01629
default:
01630
01631
#ifndef unix
01632
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
01633
instruction opcode %8x %8x not recognized\n", OpCode);
01634
#else
01635
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
01636
instruction opcode %Lx not recognized\n", OpCode);
01637
return (
FP_EMUL_ERROR);
01638
#endif
01639
}
01640
01641
01642 rc = (
EM_sf_rc_type)((
FPSR >> (6 + 4 + 13 * (
EM_uint_t)sf)) & 0x03);
01643
01644
01645 p2 = (
EM_uint_t)((OpCode >> 27) &
CONST_FORMAT(0x00000000003f));
01646
if (p2 >= 16) p2 = 16 + (rrbpr + p2 - 16) % 48;
01647
#ifdef DEBUG_UNIX
01648
printf (
"DEBUG F7 instruction: p2 = %x\n", p2);
01649
#endif
01650
f3 = (
EM_uint_t)((OpCode >> 20) &
CONST_FORMAT(0x00000000007F));
01651
if (f3 >= 32) f3 = 32 + (rrbfr + f3 - 32) % 96;
01652 f1 = (
EM_uint_t)((OpCode >> 6) &
CONST_FORMAT(0x00000000007F));
01653
if (f1 >= 32) f1 = 32 + (rrbfr + f1 - 32) % 96;
01654
01655
01656 ps->
state_FR[lf3] =
FP128ToFPReg (get_fp_register (f3, fp_state));
01657
#ifdef DEBUG_UNIX
01658
printf (
"DEBUG BEFORE F7 SWA FAULT: ps->state_FR[lf3] = %x %x %Lx\n",
01659 ps->
state_FR[lf3].
sign, ps->
state_FR[lf3].
exponent, ps->
state_FR[lf3].
significand);
01660
#endif
01661
01662
switch (OpCode &
F7_MASK) {
01663
01664
case FRSQRTA_PATTERN:
01665
01666
01667
01668
01669
01670 sign_a = (
EM_uint_t)ps->
state_FR[lf3].
sign;
01671 exponent_a = (
EM_int_t)ps->
state_FR[lf3].
exponent;
01672 significand_a = ps->
state_FR[lf3].
significand;
01673
if (exponent_a == 0 && significand_a != 0) exponent_a = 0xc001;
01674
01675 unnormal = 0;
01676
if (!(significand_a &
CONST_FORMAT(0x8000000000000000))) {
01677 unnormal = 1;
01678 }
01679
#ifdef DEBUG_UNIX
01680
if (unnormal) printf (
"DEBUG F7 FRSQRTA SWA FAULT: unnormal = 1\n");
01681
#endif
01682
01683
01684
if (unnormal && !D_dis && !(sign_a == 1 && significand_a != 0)) {
01685 ISRlow = 0x0002;
01686 *pisr = ((*pisr) & 0xffffffffffff0000) | ISRlow;
01687
return (
FALSE);
01688 }
01689
01690
01691
if (exponent_a != 0 && significand_a == 0 ||
01692 sign_a == 1 && significand_a != 0) {
01693
01694
01695
frsqrta (ps, sf, qp, lf1, p2, lf3);
01696
01697
if ((ps->
state_MERCED_RTL >> 16) & 0x0ffff)
goto new_exception;
01698
01699 *pfpsr = ps->
state_AR[0].
uint_value;
01700
01701
01702
#ifdef DEBUG_UNIX
01703
printf (
"DEBUG AFTER F7 SWA FAULT FOR PSEUDO-ZERO OR -DEN: ps->state_FR[lf1] = %x %x %Lx\n",
01704 ps->
state_FR[lf1].
sign, ps->
state_FR[lf1].
exponent,
01705 ps->
state_FR[lf1].
significand);
01706
#endif
01707
set_fp_register (f1,
FPRegToFP128(ps->
state_FR[lf1]), fp_state);
01708
if (f1 < 32)
01709 *pipsr = *pipsr | (
EM_uint64_t)0x10;
01710
else
01711 *pipsr = *pipsr | (
EM_uint64_t)0x20;
01712
01713
01714 *ppreds &= (~(((
EM_uint64_t)1) << (
EM_uint_t)p2));
01715 *ppreds |=
01716 (((
EM_uint64_t)(ps->
state_PR[p2] & 0x01)) << (
EM_uint_t)p2);
01717
#ifdef DEBUG_UNIX
01718
printf (
"DEBUG AFTER F7 SWA FAULT FOR PSEUDO-ZERO OR -DEN: p2 = %x\n", p2);
01719
#endif
01720
#ifdef DEBUG_UNIX
01721
printf (
"DEBUG AFTER F7 SWA FAULT FOR PSEUDO-ZERO OR -DEN: *ppreds = %Lx\n", *ppreds);
01722
#endif
01723
return (
TRUE);
01724
01725 }
01726
01727
01728
while (!(significand_a &
CONST_FORMAT(0x8000000000000000))) {
01729 significand_a = significand_a << 1;
01730 exponent_a--;
01731 }
01732
01733
01734
01735
01736
if (exponent_a - 0xffff <=
FP_REG_EMIN +
N64 - 1) {
01737
01738
01739
01740
01741
if (exponent_a % 2 != 0)
01742 ps->
state_FR[lf3].
exponent = (
EM_uint_t)0xffff;
01743
else
01744 ps->
state_FR[lf3].
exponent = (
EM_uint_t)0x10000;
01745 ps->
state_FR[lf3].
significand = significand_a;
01746
01747
01748 a_float128 =
FPRegToFP128 (ps->
state_FR[lf3]);
01749
01750
01751
01752
01753
01754
01755 FPSR1 = (
EM_uint64_t)((
FPSR >> ((
EM_uint_t)sf * 13)) & 0x01fc0) |
01756 0x000000000270003f;
01757
thmL (&FPSR1, &a_float128, &s_float128);
01758 I_flag = FPSR1 & 0x40000 ? 1 : 0;
01759
01760
01761 ps->
state_FR[lf1] =
FP128ToFPReg (s_float128);
01762
01763
01764
if (exponent_a % 2 != 0)
01765 ps->
state_FR[lf1].
exponent += ((exponent_a - 0xffff) / 2);
01766
else
01767 ps->
state_FR[lf1].
exponent += ((exponent_a - 0xffff - 1) / 2);
01768
01769
if (I_dis || !I_flag) {
01770
01771
01772
01773
if (unnormal) {
01774
01775 *pfpsr = *pfpsr |
01776 ((
EM_uint64_t)1 << (6 + (
EM_uint_t)sf * 13 + 8));
01777 }
01778
if (I_flag) {
01779
01780 *pfpsr = *pfpsr |
01781 ((
EM_uint64_t)1 << (6 + (
EM_uint_t)sf * 13 + 12));
01782 }
01783
01784
01785
#ifdef DEBUG_UNIX
01786
printf (
"DEBUG Case (I) AFTER F7 SWA FAULT 1: ps->state_FR[lf1] = %x %x %Lx\n",
01787 ps->
state_FR[lf1].
sign, ps->
state_FR[lf1].
exponent,
01788 ps->
state_FR[lf1].
significand);
01789
#endif
01790
set_fp_register (f1,
FPRegToFP128(ps->
state_FR[lf1]), fp_state);
01791
if (f1 < 32)
01792 *pipsr = *pipsr | (
EM_uint64_t)0x10;
01793
else
01794 *pipsr = *pipsr | (
EM_uint64_t)0x20;
01795
01796
01797 *ppreds &= (~(((
EM_uint64_t)1) << (
EM_uint_t)p2));
01798
#ifdef DEBUG_UNIX
01799
printf (
"DEBUG Case (I) AFTER F7 SWA FAULT 1 a: *ppreds = %Lx\n",
01800 *ppreds);
01801
#endif
01802
return (
TRUE);
01803
01804 }
else {
01805
01806
01807
01808 FPSR1 =
CONST_FORMAT(0x00000000000003bf);
01809
run_fms (&FPSR1, &d_float128, &s_float128, &s_float128,
01810 &a_float128);
01811
01812
if (d_float128.hiFlt64 &
CONST_FORMAT(0x0000000000020000)) {
01813
01814 ISRlow = 0x2001;
01815 }
else {
01816
01817 ISRlow = 0x6001;
01818 }
01819
01820 *pisr = ((*pisr) & 0xffffffffffff0000) | ISRlow;
01821
01822
01823
#ifdef DEBUG_UNIX
01824
printf (
"DEBUG Case (I) AFTER F7 SWA FAULT 2: ps->state_FR[lf1] = %x %x %Lx\n",
01825 ps->
state_FR[lf1].
sign, ps->
state_FR[lf1].
exponent,
01826 ps->
state_FR[lf1].
significand);
01827
#endif
01828
set_fp_register (f1,
FPRegToFP128(ps->
state_FR[lf1]), fp_state);
01829
if (f1 < 32)
01830 *pipsr = *pipsr | (
EM_uint64_t)0x10;
01831
else
01832 *pipsr = *pipsr | (
EM_uint64_t)0x20;
01833
01834
01835
01836 *ppreds &= (~(((
EM_uint64_t)1) << (
EM_uint_t)p2));
01837
#ifdef DEBUG_UNIX
01838
printf (
"DEBUG Case (I) AFTER F7 SWA FAULT 2 a: *ppreds = %Lx\n",
01839 *ppreds);
01840
#endif
01841
01842
01843
if (unnormal) {
01844
01845 *pfpsr = *pfpsr |
01846 ((
EM_uint64_t)1 << (6 + (
EM_uint_t)sf * 13 + 8));
01847 }
01848
01849 *pfpsr = *pfpsr |
01850 ((
EM_uint64_t)1 << (6 + (
EM_uint_t)sf * 13 + 12));
01851
01852
01853
return (
FALSE |
FAULT_TO_TRAP);
01854
01855 }
01856
01857
01858 }
else {
01859
01860
frsqrta (ps, sf, qp, lf1, p2, lf3);
01861
01862
if ((ps->
state_MERCED_RTL >> 16) & 0x0ffff)
goto new_exception;
01863
01864 *pfpsr = ps->
state_AR[0].
uint_value;
01865
01866
#ifdef DEBUG_UNIX
01867
printf (
"DEBUG Case (II) AFTER F7 SWA FAULT 3: ps->state_FR[lf1] = %x %x %Lx\n",
01868 ps->
state_FR[lf1].
sign, ps->
state_FR[lf1].
exponent,
01869 ps->
state_FR[lf1].
significand);
01870
#endif
01871
set_fp_register (f1,
FPRegToFP128(ps->
state_FR[lf1]), fp_state);
01872
if (f1 < 32)
01873 *pipsr = *pipsr | (
EM_uint64_t)0x10;
01874
else
01875 *pipsr = *pipsr | (
EM_uint64_t)0x20;
01876
01877
01878 *ppreds &= (~(((
EM_uint64_t)1) << (
EM_uint_t)p2));
01879 *ppreds |=
01880 (((
EM_uint64_t)(ps->
state_PR[p2] & 0x01)) << (
EM_uint_t)p2);
01881
#ifdef DEBUG_UNIX
01882
printf (
"DEBUG Case (II) AFTER F7 SWA FAULT 3 a: p2 = %x\n", p2);
01883
#endif
01884
#ifdef DEBUG_UNIX
01885
printf (
"DEBUG Case (II) AFTER F7 SWA FAULT 3 a: *ppreds = %Lx\n", *ppreds);
01886
#endif
01887
return (
TRUE);
01888
01889 }
01890
01891
break;
01892
01893
case FPRSQRTA_PATTERN:
01894
01895
01896
fprsqrta (ps, sf, qp, lf1, p2, lf3);
01897
01898
if ((ps->
state_MERCED_RTL >> 16) & 0x0ffff)
goto new_exception;
01899
01900 *pfpsr = ps->
state_AR[0].
uint_value;
01901
01902
01903
#ifdef DEBUG_UNIX
01904
printf (
"DEBUG AFTER F7 FPRSQRTA SWA FAULT 4: ps->state_FR[lf1] = %x %x %Lx\n",
01905 ps->
state_FR[lf1].
sign, ps->
state_FR[lf1].
exponent,
01906 ps->
state_FR[lf1].
significand);
01907
#endif
01908
set_fp_register (f1,
FPRegToFP128(ps->
state_FR[lf1]), fp_state);
01909
if (f1 < 32)
01910 *pipsr = *pipsr | (
EM_uint64_t)0x10;
01911
else
01912 *pipsr = *pipsr | (
EM_uint64_t)0x20;
01913
01914
01915 *ppreds &= (~(((
EM_uint64_t)1) << (
EM_uint_t)p2));
01916 *ppreds |=
01917 (((
EM_uint64_t)(ps->
state_PR[p2] & 0x01)) << (
EM_uint_t)p2);
01918
#ifdef DEBUG_UNIX
01919
printf (
"DEBUG AFTER F7 FPRSQRTA SWA FAULT 4 a: *ppreds = %Lx\n", *ppreds);
01920
#endif
01921
return (
TRUE);
01922
01923 }
01924
01925 }
else if ((OpCode &
F8_MIN_MASK) ==
F8_PATTERN) {
01926
01927
01928
01929 f3 = (
EM_fp_reg_specifier)((OpCode >> 20) &
CONST_FORMAT(0x00000000007F));
01930
if (f3 >= 32) f3 = 32 + (rrbfr + f3 - 32) % 96;
01931 f2 = (
EM_fp_reg_specifier)((OpCode >> 13) &
CONST_FORMAT(0x00000000007F));
01932
if (f2 >= 32) f2 = 32 + (rrbfr + f2 - 32) % 96;
01933 f1 = (
EM_fp_reg_specifier)((OpCode >> 6) &
CONST_FORMAT(0x00000000007F));
01934
if (f1 >= 32) f1 = 32 + (rrbfr + f1 - 32) % 96;
01935
01936
01937 ps->
state_FR[lf2] =
FP128ToFPReg (get_fp_register (f2, fp_state));
01938 ps->
state_FR[lf3] =
FP128ToFPReg (get_fp_register (f3, fp_state));
01939
#ifdef DEBUG_UNIX
01940
printf (
"DEBUG BEFORE F8 SWA FAULT: ps->state_FR[lf2] = %x %x %Lx\n",
01941 ps->
state_FR[lf2].
sign, ps->
state_FR[lf2].
exponent, ps->
state_FR[lf2].
significand);
01942 printf (
"DEBUG BEFORE F8 SWA FAULT: ps->state_FR[lf3] = %x %x %Lx\n",
01943 ps->
state_FR[lf3].
sign, ps->
state_FR[lf3].
exponent, ps->
state_FR[lf3].
significand);
01944
#endif
01945
01946
switch (OpCode &
F8_MASK) {
01947
01948
case FMIN_PATTERN:
01949 SIMD_instruction = 0;
01950
fmin (ps, sf, qp, lf1, lf2, lf3);
01951
break;
01952
case FMAX_PATTERN:
01953 SIMD_instruction = 0;
01954
fmax (ps, sf, qp, lf1, lf2, lf3);
01955
break;
01956
case FAMIN_PATTERN:
01957 SIMD_instruction = 0;
01958
famin (ps, sf, qp, lf1, lf2, lf3);
01959
break;
01960
case FAMAX_PATTERN:
01961 SIMD_instruction = 0;
01962
famax (ps, sf, qp, lf1, lf2, lf3);
01963
break;
01964
case FPMIN_PATTERN:
01965 SIMD_instruction = 1;
01966
fpmin (ps, sf, qp, lf1, lf2, lf3);
01967
break;
01968
case FPMAX_PATTERN:
01969 SIMD_instruction = 1;
01970
fpmax (ps, sf, qp, lf1, lf2, lf3);
01971
break;
01972
case FPAMIN_PATTERN:
01973 SIMD_instruction = 1;
01974
fpamin (ps, sf, qp, lf1, lf2, lf3);
01975
break;
01976
case FPAMAX_PATTERN:
01977 SIMD_instruction = 1;
01978
fpamax (ps, sf, qp, lf1, lf2, lf3);
01979
break;
01980
01981
case FPCMP_EQ_PATTERN:
01982 SIMD_instruction = 1;
01983
fpcmp_eq (ps, sf, qp, lf1, lf2, lf3);
01984
break;
01985
case FPCMP_LT_PATTERN:
01986 SIMD_instruction = 1;
01987
fpcmp_lt (ps, sf, qp, lf1, lf2, lf3);
01988
break;
01989
case FPCMP_LE_PATTERN:
01990 SIMD_instruction = 1;
01991
fpcmp_le (ps, sf, qp, lf1, lf2, lf3);
01992
break;
01993
case FPCMP_UNORD_PATTERN:
01994 SIMD_instruction = 1;
01995
fpcmp_unord (ps, sf, qp, lf1, lf2, lf3);
01996
break;
01997
case FPCMP_NEQ_PATTERN:
01998 SIMD_instruction = 1;
01999
fpcmp_neq (ps, sf, qp, lf1, lf2, lf3);
02000
break;
02001
case FPCMP_NLT_PATTERN:
02002 SIMD_instruction = 1;
02003
fpcmp_nlt (ps, sf, qp, lf1, lf2, lf3);
02004
break;
02005
case FPCMP_NLE_PATTERN:
02006 SIMD_instruction = 1;
02007
fpcmp_nle (ps, sf, qp, lf1, lf2, lf3);
02008
break;
02009
case FPCMP_ORD_PATTERN:
02010 SIMD_instruction = 1;
02011
fpcmp_ord (ps, sf, qp, lf1, lf2, lf3);
02012
break;
02013
02014
default:
02015
02016
#ifndef unix
02017
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
02018
instruction opcode %8x %8x not recognized\n", OpCode);
02019
#else
02020
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
02021
instruction opcode %Lx not recognized\n", OpCode);
02022
return (
FP_EMUL_ERROR);
02023
#endif
02024
}
02025
02026
if ((ps->
state_MERCED_RTL >> 16) & 0x0ffff)
goto new_exception;
02027
02028
02029
02030
#ifdef DEBUG_UNIX
02031
printf (
"DEBUG AFTER F8 SWA FAULT: ps->state_FR[lf1] = %x %x %Lx\n",
02032 ps->
state_FR[lf1].
sign, ps->
state_FR[lf1].
exponent,
02033 ps->
state_FR[lf1].
significand);
02034
#endif
02035
set_fp_register (f1,
FPRegToFP128(ps->
state_FR[lf1]), fp_state);
02036
if (f1 < 32)
02037 *pipsr = *pipsr | (
EM_uint64_t)0x10;
02038
else
02039 *pipsr = *pipsr | (
EM_uint64_t)0x20;
02040
02041 *pfpsr = ps->
state_AR[0].
uint_value;
02042
return (
TRUE);
02043
02044 }
else if ((OpCode &
F10_MIN_MASK) ==
F10_PATTERN) {
02045
02046
02047
02048 f2 = (
EM_uint_t)((OpCode >> 13) &
CONST_FORMAT(0x00000000007F));
02049
if (f2 >= 32) f2 = 32 + (rrbfr + f2 - 32) % 96;
02050 f1 = (
EM_uint_t)((OpCode >> 6) &
CONST_FORMAT(0x00000000007F));
02051
if (f1 >= 32) f1 = 32 + (rrbfr + f1 - 32) % 96;
02052
02053
02054 ps->
state_FR[lf2] =
FP128ToFPReg (get_fp_register (f2, fp_state));
02055
#ifdef DEBUG_UNIX
02056
printf (
"DEBUG BEFORE F10 SWA FAULT: ps->state_FR[lf2] = %x %x %Lx\n",
02057 ps->
state_FR[lf2].
sign, ps->
state_FR[lf2].
exponent, ps->
state_FR[lf2].
significand);
02058
#endif
02059
02060
switch (OpCode &
F10_MASK) {
02061
02062
case FCVT_FX_PATTERN:
02063 SIMD_instruction = 0;
02064
fcvt_fx (ps, sf, qp, lf1, lf2);
02065
break;
02066
case FCVT_FXU_PATTERN:
02067 SIMD_instruction = 0;
02068
fcvt_fxu (ps, sf, qp, lf1, lf2);
02069
break;
02070
case FCVT_FX_TRUNC_PATTERN:
02071 SIMD_instruction = 0;
02072
fcvt_fx_trunc (ps, sf, qp, lf1, lf2);
02073
break;
02074
case FCVT_FXU_TRUNC_PATTERN:
02075 SIMD_instruction = 0;
02076
fcvt_fxu_trunc (ps, sf, qp, lf1, lf2);
02077
break;
02078
case FPCVT_FX_PATTERN:
02079 SIMD_instruction = 1;
02080
fpcvt_fx (ps, sf, qp, lf1, lf2);
02081
break;
02082
case FPCVT_FXU_PATTERN:
02083 SIMD_instruction = 1;
02084
fpcvt_fxu (ps, sf, qp, lf1, lf2);
02085
break;
02086
case FPCVT_FX_TRUNC_PATTERN:
02087 SIMD_instruction = 1;
02088
fpcvt_fx_trunc (ps, sf, qp, lf1, lf2);
02089
break;
02090
case FPCVT_FXU_TRUNC_PATTERN:
02091 SIMD_instruction = 1;
02092
fpcvt_fxu_trunc (ps, sf, qp, lf1, lf2);
02093
break;
02094
default:
02095
02096
#ifndef unix
02097
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
02098
instruction opcode %8x %8x not recognized\n", OpCode);
02099
#else
02100
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
02101
instruction opcode %Lx not recognized\n", OpCode);
02102
return (
FP_EMUL_ERROR);
02103
#endif
02104
}
02105
02106
if ((ps->
state_MERCED_RTL >> 16) & 0x0ffff)
goto new_exception;
02107
02108
02109
02110
#ifdef DEBUG_UNIX
02111
printf (
"DEBUG AFTER F10 SWA FAULT: ps->state_FR[lf1] = %x %x %Lx\n",
02112 ps->
state_FR[lf1].
sign, ps->
state_FR[lf1].
exponent,
02113 ps->
state_FR[lf1].
significand);
02114
#endif
02115
set_fp_register (f1,
FPRegToFP128(ps->
state_FR[lf1]), fp_state);
02116
if (f1 < 32)
02117 *pipsr = *pipsr | (
EM_uint64_t)0x10;
02118
else
02119 *pipsr = *pipsr | (
EM_uint64_t)0x20;
02120
02121 *pfpsr = ps->
state_AR[0].
uint_value;
02122
return (
TRUE);
02123
02124 }
else {
02125
02126
02127
#ifndef unix
02128
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
02129
instruction opcode %8x %8x not recognized\n", OpCode);
02130
#else
02131
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
02132
instruction opcode %Lx not recognized\n", OpCode);
02133
return (
FP_EMUL_ERROR);
02134
#endif
02135
}
02136
02137
02138
02139
return (
TRUE);
02140
02141
02142
02143 }
else if ((trap_type ==
FPTRAP) &&
swa_trap (sf, FPSR, ISRlow)) {
02144
02145
02146
02147
02148
02149
02150
02151
02152
02153
02154
02155
02156
if ((ISRlow & 0x1980) == 0)
return (
TRUE);
02157
02158
02159
02160
02161
02162
02163
02164
02165
02166
02167
02168
02169
02170
02171
02172
if ((OpCode &
F1_MIN_MASK) ==
F1_PATTERN) {
02173
02174
02175
02176 f1 = (
EM_uint_t)((OpCode >> 6) &
CONST_FORMAT(0x00000000007F));
02177
if (f1 >= 32) f1 = 32 + (rrbfr + f1 - 32) % 96;
02178
#ifdef DEBUG_UNIX
02179
printf (
"DEBUG BEFORE F1 SWA TRAP: f1 = %x\n", f1);
02180
#endif
02181
02182
02183
02184
02185
02186 ps->
state_FR[lf1] =
FP128ToFPReg (get_fp_register (f1, fp_state));
02187
#ifdef DEBUG_UNIX
02188
printf (
"DEBUG BEFORE F1 SWA TRAP: ps->state_FR[lf1] = %x %x %Lx\n",
02189 ps->
state_FR[lf1].
sign, ps->
state_FR[lf1].
exponent,
02190 ps->
state_FR[lf1].
significand);
02191
#endif
02192
02193
switch (OpCode &
F1_MASK) {
02194
02195
case FMA_PATTERN:
02196
case FMS_PATTERN:
02197
case FNMA_PATTERN:
02198 opcode_pc =
pc_sf;
02199
break;
02200
case FMA_S_PATTERN:
02201
case FMS_S_PATTERN:
02202
case FNMA_S_PATTERN:
02203 opcode_pc =
pc_s;
02204
break;
02205
case FMA_D_PATTERN:
02206
case FMS_D_PATTERN:
02207
case FNMA_D_PATTERN:
02208 opcode_pc =
pc_d;
02209
break;
02210
case FPMA_PATTERN:
02211
case FPMS_PATTERN:
02212
case FPNMA_PATTERN:
02213 opcode_pc =
pc_simd;
02214
break;
02215
02216
default:
02217
02218
#ifndef unix
02219
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
02220
instruction opcode %8x %8x not recognized\n", OpCode);
02221
#else
02222
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
02223
instruction opcode %Lx not recognized\n", OpCode);
02224
return (
FP_EMUL_ERROR);
02225
#endif
02226
}
02227
02228
02229
02230
02231 rc = (
EM_sf_rc_type)((
FPSR >> (6 + 4 + 13 * (
EM_uint_t)sf)) & 0x03);
02232 pc = (
EM_sf_pc_type)((
FPSR >> (6 + 2 + 13 * (
EM_uint_t)sf)) & 0x03);
02233 wre = (
EM_uint_t)((
FPSR >> (6 + 1 + 13 * (
EM_uint_t)sf)) & 0x01);
02234
02235
02236
02237
if (opcode_pc ==
pc_simd || opcode_pc ==
pc_s && wre == 0) {
02238 significand_size = 24;
02239 emin =
EMIN_08_BITS;
02240 }
else if (opcode_pc ==
pc_d && wre == 0) {
02241 significand_size = 53;
02242 emin =
EMIN_11_BITS;
02243 }
else if (opcode_pc ==
pc_s && wre == 1) {
02244 significand_size = 24;
02245 emin =
EMIN_17_BITS;
02246 }
else if (opcode_pc ==
pc_d && wre == 1) {
02247 significand_size = 53;
02248 emin =
EMIN_17_BITS;
02249 }
else if (opcode_pc ==
pc_sf) {
02250
if (pc ==
sf_single && wre == 0) {
02251 significand_size = 24;
02252 emin =
EMIN_15_BITS;
02253 }
else if (pc ==
sf_double && wre == 0) {
02254 significand_size = 53;
02255 emin =
EMIN_15_BITS;
02256 }
else if (pc ==
sf_double_extended && wre == 0) {
02257 significand_size = 64;
02258 emin =
EMIN_15_BITS;
02259 }
else if (pc ==
sf_single && wre == 1) {
02260 significand_size = 24;
02261 emin =
EMIN_17_BITS;
02262 }
else if (pc ==
sf_double && wre == 1) {
02263 significand_size = 53;
02264 emin =
EMIN_17_BITS;
02265 }
else if (pc ==
sf_double_extended && wre == 1) {
02266 significand_size = 64;
02267 emin =
EMIN_17_BITS;
02268 }
else {
02269
#ifndef unix
02270
FP_EMULATION_ERROR0 (
"fp_emulate () internal error in \
02271
determining the computation model\n");
02272 }
02273 }
else {
02274
FP_EMULATION_ERROR0 (
"fp_emulate () internal error in \
02275
determining the computation model\n");
02276
#else
02277
FP_EMULATION_ERROR0 (
"fp_emulate () internal error in \
02278
determining the computation model\n");
02279
return (
FP_EMUL_ERROR);
02280 }
02281 }
else {
02282
FP_EMULATION_ERROR0 (
"fp_emulate () internal error in \
02283
determining the computation model\n");
02284
return (
FP_EMUL_ERROR);
02285
#endif
02286
}
02287
02288 tmp_fp = ps->
state_FR[lf1];
02289
02290
02291
02292
02293
if (opcode_pc !=
pc_simd) {
02294
02295 fpa = (ISRlow >> 14) & 0x01;
02296 I_exc = (ISRlow >> 13) & 0x01;
02297 U_exc = (ISRlow >> 12) & 0x01;
02298 O_exc = (ISRlow >> 11) & 0x01;
02299
02300 sign = tmp_fp.
sign;
02301 exponent = tmp_fp.
exponent;
02302 significand = tmp_fp.
significand;
02303
02304
02305
if (U_dis && U_exc) {
02306
02307
02308 decr_exp = 0;
02309
02310
02311
02312
02313
02314
if (significand_size == 64) {
02315
if (fpa == 1) {
02316 significand = significand - 1;
02317
if (significand ==
CONST_FORMAT(0x07fffffffffffffff)) {
02318 significand =
CONST_FORMAT(0x0ffffffffffffffff);
02319 decr_exp = 1;
02320 }
02321 }
02322 }
else if (significand_size == 53) {
02323
02324 significand = significand >> 11;
02325
if (fpa == 1) {
02326 significand = significand - 1;
02327
if (significand ==
CONST_FORMAT(0x0fffffffffffff)) {
02328 significand =
CONST_FORMAT(0x01fffffffffffff);
02329 decr_exp = 1;
02330 }
02331 }
02332 }
else if (significand_size == 24) {
02333
02334 significand = significand >> 40;
02335
if (fpa == 1) {
02336 significand = significand - 1;
02337
if (significand ==
CONST_FORMAT(0x07fffff)) {
02338 significand =
CONST_FORMAT(0x0ffffff);
02339 decr_exp = 1;
02340 }
02341 }
02342 }
else {
02343
02344
#ifndef unix
02345
FP_EMULATION_ERROR6 (
"fp_emulate (): incorrect \
02346
significand size %d for ISRlow = %4.4x and FR[%d] = %1.1x %5.5x %8.8x %8.8x\n",
02347 significand_size, ISRlow, f1, tmp_fp.
sign, tmp_fp.
exponent,
02348 tmp_fp.
significand)
02349 #
else
02350
FP_EMULATION_ERROR6 (
"fp_emulate (): incorrect \
02351
significand size %d for ISRlow = %4.4x and FR[%d] = %1.1x %5.5x %Lx\n",
02352 significand_size, ISRlow, f1, tmp_fp.
sign, tmp_fp.
exponent,
02353 tmp_fp.
significand)
02354 return (FP_EMUL_ERROR);
02355 #endif
02356 }
02357
02358 true_bexp = ((exponent + 0x1007b) & 0x1ffff) - 0x1007b;
02359
02360
02361
02362 if (true_bexp - 0x0ffff > emin - 1) {
02363
#ifndef unix
02364
FP_EMULATION_ERROR0 (
"fp_emulate () Internal Error: non-tiny res\n");
02365
#else
02366
FP_EMULATION_ERROR0 (
"fp_emulate () Internal Error: non-tiny res\n");
02367
return (
FP_EMUL_ERROR);
02368
#endif
02369
}
02370
02371
02372
if (decr_exp) true_bexp--;
02373
02374
02375
02376 shift_cnt = emin - true_bexp + 0x0ffff;
02377
02378
if (shift_cnt <= significand_size) {
02379
02380
02381 round = I_exc;
02382
02383 sticky = 0;
02384
for (ind = 0 ; ind < shift_cnt ; ind++) {
02385 sticky = round | sticky;
02386 round = (
EM_uint_t)(significand & 0x01);
02387 significand = significand >> 1;
02388 }
02389 true_bexp = true_bexp + shift_cnt;
02390 }
else {
02391 significand = 0;
02392 round = 0;
02393 sticky = 1;
02394 true_bexp = true_bexp + shift_cnt;
02395 }
02396
02397
02398
02399
switch (rc) {
02400
case rc_rn:
02401 lsb = (
EM_uint_t)(significand & 0x01);
02402 fpa = round & (lsb | sticky);
02403
break;
02404
case rc_rm:
02405 fpa = (sign == 0 ? 0 : (round | sticky));
02406
break;
02407
case rc_rp:
02408 fpa = (sign == 1 ? 0 : (round | sticky));
02409
break;
02410
case rc_rz:
02411 fpa = 0;
02412
break;
02413
default:
02414
#ifndef unix
02415
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
02416
invalid rc = %d\n", rc)
02417 #
else
02418
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
02419
invalid rc = %d\n", rc)
02420 return (FP_EMUL_ERROR);
02421 #endif
02422 }
02423
02424
02425
02426
02427
02428 if (fpa == 1) {
02429
02430 significand = significand + 1;
02431
02432
if (significand_size == 64) {
02433
if (significand ==
CONST_FORMAT(0x0)) {
02434 significand =
CONST_FORMAT(0x08000000000000000);
02435 true_bexp++;
02436 }
02437 }
else if (significand_size == 53) {
02438
if (significand ==
CONST_FORMAT(0x020000000000000)) {
02439 significand =
CONST_FORMAT(0x010000000000000);
02440 true_bexp++;
02441 }
02442 }
else if (significand_size == 24) {
02443
if (significand ==
CONST_FORMAT(0x01000000)) {
02444 significand =
CONST_FORMAT(0x0800000);
02445 true_bexp++;
02446 }
02447 }
else {
02448
02449
#ifndef unix
02450
FP_EMULATION_ERROR1 (
02451
"fp_emulate (): incorrect significand size %d\n",
02452 significand_size)
02453 #
else
02454
FP_EMULATION_ERROR1 (
02455
"fp_emulate (): incorrect significand size %d\n",
02456 significand_size)
02457 return (FP_EMUL_ERROR);
02458 #endif
02459 }
02460
02461 }
02462
02463 if (significand == 0) {
02464 true_bexp = 0;
02465 }
02466
02467 exponent = true_bexp;
02468
02469
02470 I_exc = round | sticky;
02471
02472
02473
02474
02475
02476
02477
02478
if (I_exc) {
02479
02480
02481 *pfpsr = *pfpsr |
02482 ((
EM_uint64_t)3 << (6 + (
EM_uint_t)sf * 13 + 11));
02483
if (!I_dis) {
02484
02485 ISRlow = (ISRlow & 0xefff) | 0x2000;
02486
02487
if (fpa)
02488 ISRlow = ISRlow | 0x4000;
02489
else
02490 ISRlow = ISRlow & 0xbfff;
02491 }
02492 }
02493
02494
02495
if (significand_size == 53)
02496 significand = significand << 11;
02497
else if (significand_size == 24)
02498 significand = significand << 40;
02499
02500
02501
02502
if (exponent == 0xc001 && ((significand & 0x8000000000000000) == 0))
02503 exponent = 0x0;
02504
02505 }
else if (O_dis && O_exc) {
02506
02507
02508
02509
02510
02511
02512
switch (rc) {
02513
case rc_rn:
02514 exponent = 0x01ffff;
02515 significand =
CONST_FORMAT(0x8000000000000000);
02516
break;
02517
case rc_rm:
02518 exponent = (sign == 0 ? 0x01fffe : 0x01ffff);
02519 significand = (sign == 0 ?
CONST_FORMAT(0x0ffffffffffffffff) :
02520
CONST_FORMAT(0x8000000000000000));
02521
break;
02522
case rc_rp:
02523 exponent = (sign == 0 ? 0x01ffff : 0x01fffe);
02524 significand = (sign == 0 ?
CONST_FORMAT(0x8000000000000000) :
02525
CONST_FORMAT(0x0ffffffffffffffff));
02526
break;
02527
case rc_rz:
02528 exponent = 0x01fffe;
02529 significand =
CONST_FORMAT(0x0ffffffffffffffff);
02530
break;
02531
default:
02532
#ifndef unix
02533
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error:\
02534
invalid rc = %d for non-SIMD F1 instruction\n", rc)
02535 #
else
02536
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error:\
02537
invalid rc = %d for non-SIMD F1 instruction\n", rc)
02538 return (FP_EMUL_ERROR);
02539 #endif
02540 }
02541
02542
02543 *pfpsr = *pfpsr | ((EM_uint64_t)5 << (6 + (EM_uint_t)sf * 13 + 10));
02544
02545 if (!I_dis) {
02546
02547
if (exponent == 0x1ffff)
02548 fpa = 1;
02549
else
02550 fpa = 0;
02551
02552
02553 ISRlow = (ISRlow & 0xf7ff) | 0x2000;
02554
02555
if (fpa)
02556 ISRlow = ISRlow | 0x4000;
02557
else
02558 ISRlow = ISRlow & 0xbfff;
02559
02560
02561
02562
02563 }
02564
02565 }
else if (I_dis && I_exc) {
02566
02567
02568 ;
02569
02570 }
else {
02571
02572
02573
#ifndef unix
02574
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
02575
SWA trap code invoked with F1 instruction, w/o O or U set in ISR.code = %x\n",
02576 ISRlow & 0x0ffff)
02577 #
else
02578
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
02579
SWA trap code invoked with F1 instruction, w/o O or U set in ISR.code = %x\n",
02580 ISRlow & 0x0ffff)
02581
return (
FP_EMUL_ERROR);
02582
#endif
02583
}
02584
02585
02586
02587 ps->
state_FR[lf1].
exponent = exponent;
02588 ps->
state_FR[lf1].
significand = significand;
02589
02590
02591
02592
02593
02594
#ifdef DEBUG_UNIX
02595
printf (
"DEBUG AFTER F1 SWA TRAP 1: ps->state_FR[lf1] = %x %x %Lx\n",
02596 ps->
state_FR[lf1].
sign, ps->
state_FR[lf1].
exponent,
02597 ps->
state_FR[lf1].
significand);
02598
#endif
02599
#ifdef DEBUG_UNIX
02600
printf (
"DEBUG AFTER F1 SWA TRAP: f1 = %x\n", f1);
02601
#endif
02602
02603
set_fp_register (f1,
FPRegToFP128(ps->
state_FR[lf1]), fp_state);
02604
if (f1 < 32)
02605 *pipsr = *pipsr | (
EM_uint64_t)0x10;
02606
else
02607 *pipsr = *pipsr | (
EM_uint64_t)0x20;
02608
02609
02610
if (I_dis || I_exc == 0) {
02611
02612
return (
TRUE);
02613
02614 }
else {
02615
02616
02617 *pisr = ((*pisr) & 0xffffffffffff0000) | ISRlow;
02618
02619
#ifdef DEBUG_UNIX
02620
printf (
"DEBUG AFTER F1 SWA TRAP 1 A RET FALSE: ps->state_FR[lf1] = %x %x %Lx\n",
02621 ps->
state_FR[lf1].
sign, ps->
state_FR[lf1].
exponent,
02622 ps->
state_FR[lf1].
significand);
02623
#endif
02624
return (
FALSE);
02625
02626 }
02627
02628 }
else {
02629
02630
02631
02632 fpa_hi = (ISRlow >> 14) & 0x01;
02633 I_exc_hi = (ISRlow >> 13) & 0x01;
02634 U_exc_hi = (ISRlow >> 12) & 0x01;
02635 O_exc_hi = (ISRlow >> 11) & 0x01;
02636 fpa_lo = (ISRlow >> 10) & 0x01;
02637 I_exc_lo = (ISRlow >> 9) & 0x01;
02638 U_exc_lo = (ISRlow >> 8) & 0x01;
02639 O_exc_lo = (ISRlow >> 7) & 0x01;
02640
02641
if (!U_exc_lo && !U_exc_hi && !O_exc_lo && !O_exc_hi) {
02642
02643
02644
#ifndef unix
02645
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
02646
SWA trap code invoked with SIMD F1 instruction, w/o O or U set in \
02647
ISR.code = %x\n", ISRlow & 0x0ffff)
02648 #
else
02649
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
02650
SWA trap code invoked with SIMD F1 instruction, w/o O or U set in \
02651
ISR.code = %x\n", ISRlow & 0x0ffff)
02652
return (
FP_EMUL_ERROR);
02653
#endif
02654
02655 }
02656
02657 sign_lo = (
EM_uint_t)((tmp_fp.
significand >> 31) & 0x01);
02658 exponent_lo = (
EM_uint_t)((tmp_fp.
significand >> 23) & 0x0ff);
02659 significand_lo = (
EM_uint_t)((tmp_fp.
significand) & 0x07fffff);
02660
02661
02662
02663
02664
02665 significand_lo = significand_lo | 0x800000;
02666
02667 sign_hi = (
EM_uint_t)((tmp_fp.
significand >> 63) & 0x01);
02668 exponent_hi = (
EM_uint_t)((tmp_fp.
significand >> 55) & 0x0ff);
02669 significand_hi = (
EM_uint_t)((tmp_fp.
significand >> 32) & 0x07fffff);
02670
02671
02672
02673
02674
02675 significand_hi = significand_hi | 0x800000;
02676
02677
02678
02679
02680
if (U_dis && U_exc_lo) {
02681
02682
02683 decr_exp_lo = 0;
02684
02685
if (fpa_lo == 1) {
02686 significand_lo = significand_lo - 1;
02687
if (significand_lo == 0x07fffff) {
02688 significand_lo = 0x0ffffff;
02689 decr_exp_lo = 1;
02690 }
02691 }
02692
02693 true_bexp_lo = (exponent_lo == 0 ? exponent_lo : exponent_lo - 0x100);
02694
02695
02696
02697
if (true_bexp_lo - 0x07f > emin - 1) {
02698
#ifndef unix
02699
FP_EMULATION_ERROR0 (
"fp_emulate () Internal Error:non-tiny resL\n");
02700
#else
02701
FP_EMULATION_ERROR0 (
"fp_emulate () Internal Error:non-tiny resL\n");
02702
return (
FP_EMUL_ERROR);
02703
#endif
02704
}
02705
02706
02707
if (decr_exp_lo) true_bexp_lo--;
02708
02709
02710
02711 shift_cnt_lo = emin - true_bexp_lo + 0x07f;
02712
02713
if (shift_cnt_lo <= significand_size) {
02714
02715
02716 round_lo = I_exc_lo;
02717
02718 sticky_lo = 0;
02719
for (ind = 0 ; ind < shift_cnt_lo ; ind++) {
02720 sticky_lo = round_lo | sticky_lo;
02721 round_lo = significand_lo & 0x01;
02722 significand_lo = significand_lo >> 1;
02723 }
02724 true_bexp_lo = true_bexp_lo + shift_cnt_lo;
02725 }
else {
02726 significand_lo = 0;
02727 round_lo = 0;
02728 sticky_lo = 1;
02729 true_bexp_lo = true_bexp_lo + shift_cnt_lo;
02730 }
02731
02732
02733
02734
switch (rc) {
02735
case rc_rn:
02736 lsb_lo = significand_lo & 0x01;
02737 fpa_lo = round_lo & (lsb_lo | sticky_lo);
02738
break;
02739
case rc_rm:
02740 fpa_lo = (sign_lo == 0 ? 0 : (round_lo | sticky_lo));
02741
break;
02742
case rc_rp:
02743 fpa_lo = (sign_lo == 1 ? 0 : (round_lo | sticky_lo));
02744
break;
02745
case rc_rz:
02746 fpa_lo = 0;
02747
break;
02748
default:
02749
#ifndef unix
02750
FP_EMULATION_ERROR1 (
"fp_emulate () Internal \
02751
Error: invalid rc = %d for SIMD F1 instruction\n", rc)
02752 #
else
02753
FP_EMULATION_ERROR1 (
"fp_emulate () Internal \
02754
Error: invalid rc = %d for SIMD F1 instruction\n", rc)
02755 return (FP_EMUL_ERROR);
02756 #endif
02757 }
02758
02759
02760
02761
02762
02763 if (fpa_lo == 1) {
02764 significand_lo = significand_lo + 1;
02765
02766
if (significand_lo == 0x01000000) {
02767 significand_lo = 0x0800000;
02768 true_bexp_lo++;
02769 }
02770 }
02771
02772
if (significand_lo == 0) {
02773 true_bexp_lo = 0;
02774 }
02775
02776 exponent_lo = true_bexp_lo;
02777
02778
if ((exponent_lo == 0x01) && ((significand_lo & 0x0800000) == 0)) {
02779 exponent_lo = 0x0;
02780
#ifdef DEBUG_UNIX
02781
printf (
"DEBUG: result low is denormal\n");
02782
#endif
02783
}
02784
02785
02786 I_exc_lo = round_lo | sticky_lo;
02787
02788
02789
02790
02791
if (!I_exc_lo) {
02792
02793
02794
02795
02796
02797
02798
02799 ISRlow = ISRlow & 0xfeff;
02800
02801
02802
02803
02804
02805
02806 U_exc_lo = 0;
02807
02808
02809
02810 ISRlow = ISRlow & 0xfbff;
02811
02812 }
else {
02813
02814
02815
if (I_dis) {
02816
02817
02818
02819 ISRlow = ISRlow & 0xf8ff;
02820 }
else {
02821
02822 ISRlow = (ISRlow & 0xfeff) | 0x0200;
02823
02824
if (fpa_lo)
02825 ISRlow = ISRlow | 0x0400;
02826
else
02827 ISRlow = ISRlow & 0xfbff;
02828
02829 }
02830
02831 }
02832
02833 }
02834
02835
if (O_dis && O_exc_lo) {
02836
02837
02838
02839
02840
02841
02842
02843
switch (rc) {
02844
case rc_rn:
02845 exponent_lo = 0x0ff;
02846 significand_lo = 0x0800000;
02847
break;
02848
case rc_rm:
02849 exponent_lo = (sign_lo == 0 ? 0x0fe : 0x0ff);
02850 significand_lo = (sign_lo == 0 ? 0x0ffffff : 0x0800000);
02851
break;
02852
case rc_rp:
02853 exponent_lo = (sign_lo == 0 ? 0x0ff : 0x0fe);
02854 significand_lo = (sign_lo == 0 ? 0x0800000 : 0x0ffffff);
02855
break;
02856
case rc_rz:
02857 exponent_lo = 0x0fe;
02858 significand_lo = 0x0ffffff;
02859
break;
02860
default:
02861
#ifndef unix
02862
FP_EMULATION_ERROR1 (
"fp_emulate () Internal \
02863
Error: invalid rc = %d for SIMD F1 instruction\n", rc)
02864 #
else
02865
FP_EMULATION_ERROR1 (
"fp_emulate () Internal \
02866
Error: invalid rc = %d for SIMD F1 instruction\n", rc)
02867 return (FP_EMUL_ERROR);
02868 #endif
02869 }
02870
02871 if (exponent_lo == 0xff)
02872 fpa_lo = 1;
02873 else
02874 fpa_lo = 0;
02875
02876
02877 O_exc_lo = 1;
02878 I_exc_lo = 1;
02879
02880 if (I_dis) {
02881
02882
02883
02884 ISRlow = ISRlow & 0xf97f;
02885
02886 }
else {
02887
02888
02889
02890
02891 ISRlow = (ISRlow & 0xff7f) | 0x0200;
02892
02893
if (fpa_lo)
02894 ISRlow = ISRlow | 0x0400;
02895
else
02896 ISRlow = ISRlow & 0xfbff;
02897
02898
02899
02900 }
02901
02902 }
02903
02904
if (I_dis && I_exc_lo) {
02905
02906 ;
02907
02908
02909 }
02910
02911
if (U_dis && U_exc_hi) {
02912
02913
02914 decr_exp_hi = 0;
02915
02916
if (fpa_hi == 1) {
02917 significand_hi = significand_hi - 1;
02918
if (significand_hi == 0x07fffff) {
02919 significand_hi = 0x0ffffff;
02920 decr_exp_hi = 1;
02921 }
02922 }
02923
02924 true_bexp_hi = (exponent_hi == 0 ? exponent_hi : exponent_hi - 0x100);
02925
02926
02927
02928
if (true_bexp_hi - 0x07f > emin - 1) {
02929
#ifndef unix
02930
FP_EMULATION_ERROR0 (
"fp_emulate () Internal Error:non-tiny resH\n");
02931
#else
02932
FP_EMULATION_ERROR0 (
"fp_emulate () Internal Error:non-tiny resH\n");
02933
return (
FP_EMUL_ERROR);
02934
#endif
02935
}
02936
02937
02938
if (decr_exp_hi) true_bexp_hi--;
02939
02940
02941
02942 shift_cnt_hi = emin - true_bexp_hi + 0x07f;
02943
02944
if (shift_cnt_hi <= significand_size) {
02945
02946
02947 round_hi = I_exc_hi;
02948
02949 sticky_hi = 0;
02950
for (ind = 0 ; ind < shift_cnt_hi ; ind++) {
02951 sticky_hi = round_hi | sticky_hi;
02952 round_hi = significand_hi & 0x01;
02953 significand_hi = significand_hi >> 1;
02954 }
02955 true_bexp_hi = true_bexp_hi + shift_cnt_hi;
02956 }
else {
02957 significand_hi = 0;
02958 round_hi = 0;
02959 sticky_hi = 1;
02960 true_bexp_hi = true_bexp_hi + shift_cnt_hi;
02961 }
02962
02963
02964
02965
switch (rc) {
02966
case rc_rn:
02967 lsb_hi = significand_hi & 0x01;
02968 fpa_hi = round_hi & (lsb_hi | sticky_hi);
02969
break;
02970
case rc_rm:
02971 fpa_hi = (sign_hi == 0 ? 0 : (round_hi | sticky_hi));
02972
break;
02973
case rc_rp:
02974 fpa_hi = (sign_hi == 1 ? 0 : (round_hi | sticky_hi));
02975
break;
02976
case rc_rz:
02977 fpa_hi = 0;
02978
break;
02979
default:
02980
#ifndef unix
02981
FP_EMULATION_ERROR1 (
"fp_emulate () Internal \
02982
Error: invalid rc = %d for SIMD F1 instruction\n", rc)
02983 #
else
02984
FP_EMULATION_ERROR1 (
"fp_emulate () Internal \
02985
Error: invalid rc = %d for SIMD F1 instruction\n", rc)
02986 return (FP_EMUL_ERROR);
02987 #endif
02988 }
02989
02990
02991
02992
02993
02994 if (fpa_hi == 1) {
02995 significand_hi = significand_hi + 1;
02996
02997
if (significand_hi == 0x01000000) {
02998 significand_hi = 0x0800000;
02999 true_bexp_hi++;
03000 }
03001 }
03002
03003
if (significand_hi == 0) {
03004 true_bexp_hi = 0;
03005 }
03006
03007 exponent_hi = true_bexp_hi;
03008
03009
if ((exponent_hi == 0x01) && ((significand_hi & 0x0800000) == 0)) {
03010 exponent_hi = 0x0;
03011
#ifdef DEBUG_UNIX
03012
printf (
"DEBUG: result high is denormal\n");
03013
#endif
03014
}
03015
03016
03017 I_exc_hi = round_hi | sticky_hi;
03018
03019
03020
03021
03022
if (!I_exc_hi) {
03023
03024
03025
03026
03027
03028
03029
03030 ISRlow = ISRlow & 0xefff;
03031
03032
03033
03034
03035
03036
03037 U_exc_hi = 0;
03038
03039
03040
03041 ISRlow = ISRlow & 0xbfff;
03042
03043 }
else {
03044
03045
03046
if (I_dis) {
03047
03048
03049
03050 ISRlow = ISRlow & 0x8fff;
03051 }
else {
03052
03053 ISRlow = (ISRlow & 0xefff) | 0x2000;
03054
03055
if (fpa_hi)
03056 ISRlow = ISRlow | 0x4000;
03057
else
03058 ISRlow = ISRlow & 0xbfff;
03059 }
03060
03061 }
03062
03063 }
03064
03065
if (O_dis && O_exc_hi) {
03066
03067
03068
03069
03070
03071
03072
03073
switch (rc) {
03074
case rc_rn:
03075 exponent_hi = 0x0ff;
03076 significand_hi = 0x0800000;
03077
break;
03078
case rc_rm:
03079 exponent_hi = (sign_hi == 0 ? 0x0fe : 0x0ff);
03080 significand_hi = (sign_hi == 0 ? 0x0ffffff : 0x0800000);
03081
break;
03082
case rc_rp:
03083 exponent_hi = (sign_hi == 0 ? 0x0ff : 0x0fe);
03084 significand_hi = (sign_hi == 0 ? 0x0800000 : 0x0ffffff);
03085
break;
03086
case rc_rz:
03087 exponent_hi = 0x0fe;
03088 significand_hi = 0x0ffffff;
03089
break;
03090
default:
03091
#ifndef unix
03092
FP_EMULATION_ERROR1 (
"fp_emulate () Internal \
03093
Error: invalid rc = %d for SIMD F1 instruction\n", rc)
03094 #
else
03095
FP_EMULATION_ERROR1 (
"fp_emulate () Internal \
03096
Error: invalid rc = %d for SIMD F1 instruction\n", rc)
03097 return (FP_EMUL_ERROR);
03098 #endif
03099 }
03100
03101 if (exponent_hi == 0xff)
03102 fpa_hi = 1;
03103 else
03104 fpa_hi = 0;
03105
03106
03107 O_exc_hi = 1;
03108 I_exc_hi = 1;
03109
03110 if (I_dis) {
03111
03112
03113
03114 ISRlow = ISRlow & 0x97ff;
03115
03116 }
else {
03117
03118
03119
03120
03121 ISRlow = (ISRlow & 0xf7ff) | 0x2000;
03122
03123
if (fpa_hi)
03124 ISRlow = ISRlow | 0x4000;
03125
else
03126 ISRlow = ISRlow & 0xbfff;
03127
03128
03129
03130 }
03131
03132 }
03133
03134
if (I_dis && I_exc_hi) {
03135
03136 ;
03137
03138
03139 }
03140
03141
03142 low_half = (sign_lo << 31) | (exponent_lo << 23) |
03143 significand_lo & 0x07fffff;
03144
03145 high_half = (sign_hi << 31) | (exponent_hi << 23) |
03146 significand_hi & 0x07fffff;
03147
03148 ps->
state_FR[lf1].
significand = high_half << 32 | low_half;
03149
03150
03151
03152
03153
03154
03155
#ifdef DEBUG_UNIX
03156
printf (
"DEBUG AFTER F1 SWA TRAP 2: ps->state_FR[lf1] = %x %x %Lx\n",
03157 ps->
state_FR[lf1].
sign, ps->
state_FR[lf1].
exponent,
03158 ps->
state_FR[lf1].
significand);
03159
#endif
03160
set_fp_register (f1,
FPRegToFP128(ps->
state_FR[lf1]), fp_state);
03161
if (f1 < 32)
03162 *pipsr = *pipsr | (
EM_uint64_t)0x10;
03163
else
03164 *pipsr = *pipsr | (
EM_uint64_t)0x20;
03165
03166
03167
if (I_exc_lo || I_exc_hi) {
03168
03169 *pfpsr = *pfpsr |
03170 ((
EM_uint64_t)1 << (6 + (
EM_uint_t)sf * 13 + 12));
03171 }
03172
if (U_exc_lo || U_exc_hi) {
03173
03174 *pfpsr = *pfpsr |
03175 ((
EM_uint64_t)1 << (6 + (
EM_uint_t)sf * 13 + 11));
03176 }
03177
if (O_exc_lo || O_exc_hi) {
03178
03179 *pfpsr = *pfpsr |
03180 ((
EM_uint64_t)1 << (6 + (
EM_uint_t)sf * 13 + 10));
03181 }
03182
03183
03184
if ((I_dis || I_exc_lo == 0 && I_exc_hi == 0) &&
03185 (U_dis || U_exc_lo == 0 && U_exc_hi == 0) &&
03186 (O_dis || O_exc_lo == 0 && O_exc_hi == 0)) {
03187
03188
return (
TRUE);
03189
03190 }
else {
03191
03192
03193
03194
03195
03196
03197 *pisr = ((*pisr) & 0xffffffffffff0000) | ISRlow;
03198
03199
return (
FALSE |
SIMD_INSTRUCTION);
03200
03201 }
03202
03203 }
03204
03205 }
else {
03206
03207
03208
#ifndef unix
03209
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
03210
instruction opcode %8x %8x not valid for SWA trap\n", OpCode)
03211 #
else
03212
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
03213
instruction opcode %Lx not valid for SWA trap\n", OpCode)
03214 return (FP_EMUL_ERROR);
03215 #endif
03216
03217 }
03218
03219
03220
03221 } else if (trap_type == FPFLT || trap_type == FPTRAP) {
03222
03223
#ifdef DEBUG_UNIX
03224
printf (
"DEBUG: INSTRUCTION NOT EMULATED\n");
03225
#endif
03226
03227
03228
03229
03230
03231
03232
03233
03234
if ((OpCode &
F1_MIN_MASK) ==
F1_PATTERN) {
03235
03236
03237
switch (OpCode &
F1_MASK) {
03238
case FMA_PATTERN:
03239
case FMA_S_PATTERN:
03240
case FMA_D_PATTERN:
03241
case FMS_PATTERN:
03242
case FMS_S_PATTERN:
03243
case FMS_D_PATTERN:
03244
case FNMA_PATTERN:
03245
case FNMA_S_PATTERN:
03246
case FNMA_D_PATTERN:
03247 SIMD_instruction = 0;
03248
break;
03249
case FPMA_PATTERN:
03250
case FPMS_PATTERN:
03251
case FPNMA_PATTERN:
03252 SIMD_instruction = 1;
03253
break;
03254
default:
03255
03256
#ifndef unix
03257
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
03258
instruction opcode %8x %8x not recognized\n", OpCode)
03259 #
else
03260
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
03261
instruction opcode %Lx not recognized\n", OpCode)
03262 return (FP_EMUL_ERROR);
03263 #endif
03264 }
03265
03266 } else if ((OpCode & F4_MIN_MASK) == F4_PATTERN) {
03267
03268
03269
switch (OpCode &
F4_MASK) {
03270
case FCMP_EQ_PATTERN:
03271
case FCMP_LT_PATTERN:
03272
case FCMP_LE_PATTERN:
03273
case FCMP_UNORD_PATTERN:
03274
case FCMP_EQ_UNC_PATTERN:
03275
case FCMP_LT_UNC_PATTERN:
03276
case FCMP_LE_UNC_PATTERN:
03277
case FCMP_UNORD_UNC_PATTERN:
03278 SIMD_instruction = 0;
03279
break;
03280
default:
03281
03282
#ifndef unix
03283
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
03284
instruction opcode %8x %8x not recognized\n", OpCode)
03285 #
else
03286
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
03287
instruction opcode %Lx not recognized\n", OpCode)
03288 return (FP_EMUL_ERROR);
03289 #endif
03290 }
03291
03292 } else if ((OpCode & F6_MIN_MASK) == F6_PATTERN) {
03293
03294
03295
switch (OpCode &
F6_MASK) {
03296
case FRCPA_PATTERN:
03297 SIMD_instruction = 0;
03298
break;
03299
case FPRCPA_PATTERN:
03300 SIMD_instruction = 1;
03301
break;
03302
default:
03303
03304
#ifndef unix
03305
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
03306
instruction opcode %8x %8x not recognized\n", OpCode)
03307 #
else
03308
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
03309
instruction opcode %Lx not recognized\n", OpCode)
03310 return (FP_EMUL_ERROR);
03311 #endif
03312 }
03313
03314 } else if ((OpCode & F7_MIN_MASK) == F7_PATTERN) {
03315
03316
03317
switch (OpCode &
F7_MASK) {
03318
case FRSQRTA_PATTERN:
03319 SIMD_instruction = 0;
03320
break;
03321
case FPRSQRTA_PATTERN:
03322 SIMD_instruction = 1;
03323
break;
03324
default:
03325
03326
#ifndef unix
03327
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
03328
instruction opcode %8x %8x not recognized\n", OpCode)
03329 #
else
03330
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
03331
instruction opcode %Lx not recognized\n", OpCode)
03332 return (FP_EMUL_ERROR);
03333 #endif
03334 }
03335
03336 } else if ((OpCode & F8_MIN_MASK) == F8_PATTERN) {
03337
03338
03339
switch (OpCode &
F8_MASK) {
03340
case FMIN_PATTERN:
03341
case FMAX_PATTERN:
03342
case FAMIN_PATTERN:
03343
case FAMAX_PATTERN:
03344 SIMD_instruction = 0;
03345
break;
03346
case FPMIN_PATTERN:
03347
case FPMAX_PATTERN:
03348
case FPAMIN_PATTERN:
03349
case FPAMAX_PATTERN:
03350
case FPCMP_EQ_PATTERN:
03351
case FPCMP_LT_PATTERN:
03352
case FPCMP_LE_PATTERN:
03353
case FPCMP_UNORD_PATTERN:
03354
case FPCMP_NEQ_PATTERN:
03355
case FPCMP_NLT_PATTERN:
03356
case FPCMP_NLE_PATTERN:
03357
case FPCMP_ORD_PATTERN:
03358 SIMD_instruction = 1;
03359
break;
03360
default:
03361
03362
#ifndef unix
03363
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
03364
instruction opcode %8x %8x not recognized\n", OpCode)
03365 #
else
03366
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
03367
instruction opcode %Lx not recognized\n", OpCode)
03368 return (FP_EMUL_ERROR);
03369 #endif
03370 }
03371
03372 } else if ((OpCode & F10_MIN_MASK) == F10_PATTERN) {
03373
03374
03375
switch (OpCode &
F10_MASK) {
03376
case FCVT_FX_PATTERN:
03377
case FCVT_FXU_PATTERN:
03378
case FCVT_FX_TRUNC_PATTERN:
03379
case FCVT_FXU_TRUNC_PATTERN:
03380 SIMD_instruction = 0;
03381
break;
03382
case FPCVT_FX_PATTERN:
03383
case FPCVT_FXU_PATTERN:
03384
case FPCVT_FX_TRUNC_PATTERN:
03385
case FPCVT_FXU_TRUNC_PATTERN:
03386 SIMD_instruction = 1;
03387
break;
03388
default:
03389
03390
#ifndef unix
03391
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
03392
instruction opcode %8x %8x not recognized\n", OpCode)
03393 #
else
03394
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
03395
instruction opcode %Lx not recognized\n", OpCode)
03396 return (FP_EMUL_ERROR);
03397 #endif
03398 }
03399
03400 } else {
03401
03402
03403
#ifndef unix
03404
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
03405
instruction opcode %8x %8x not recognized\n", OpCode)
03406 #
else
03407
FP_EMULATION_ERROR1 (
"fp_emulate () Internal Error: \
03408
instruction opcode %Lx not recognized\n", OpCode)
03409 return (FP_EMUL_ERROR);
03410 #endif
03411
03412 }
03413
03414 #ifdef DEBUG_UNIX
03415 if ((OpCode & F1_MIN_MASK) == F1_PATTERN) {
03416 printf (
"DEBUG AFTER 'NO EMULATION' RET FALSE: ps->state_FR[lf1] = %x %x %Lx\n",
03417 ps->
state_FR[lf1].
sign, ps->
state_FR[lf1].
exponent,
03418 ps->
state_FR[lf1].
significand);
03419 }
03420
#endif
03421
03422
03423
if (SIMD_instruction)
03424
return (
FALSE |
SIMD_INSTRUCTION);
03425
else
03426
return (
FALSE);
03427
03428 }
else {
03429
03430
#ifdef DEBUG_UNIX
03431
printf (
"DEBUG: STATUS FLOAT ERROR\n");
03432
#endif
03433
03434
03435
03436
#ifndef unix
03437
FP_EMULATION_ERROR2 (
"fp_emulate () Internal Error: \
03438
fp_emulate () called w/o trap_type FPFLT or FPTRAP \
03439
OpCode = %8x %8x, and ISR code = %x\n", OpCode, ISRlow)
03440 #
else
03441
FP_EMULATION_ERROR2 (
"fp_emulate () Internal Error: \
03442
fp_emulate () called w/o trap_type FPFLT or FPTRAP \
03443
OpCode = %Lx, and ISR code = %x\n", OpCode, ISRlow)
03444 return (FP_EMUL_ERROR);
03445 #endif
03446
03447 }
03448
03449 new_exception:
03450
03451
03452
03453
03454
03455
03456
03457
03458 new_trap_type = ps->trap_type;
03459
03460 if (new_trap_type == FPFLT) {
03461
03462
03463
03464
03465 fault_ISR_code = (ps->
state_MERCED_RTL >> 16) & 0x0ffff;
03466
if ((fault_ISR_code & 0x077) == 0) {
03467
#ifndef unix
03468
FP_EMULATION_ERROR0 (
03469
"fp_emulate () Internal Error: SWA fault repeated\n");
03470
#else
03471
FP_EMULATION_ERROR0 (
03472
"fp_emulate () Internal Error: SWA fault repeated\n");
03473
return (
FP_EMUL_ERROR);
03474
#endif
03475
}
03476
03477
#ifdef DEBUG_UNIX
03478
printf (
"DEBUG fp_emulate () NEW_EXC fault_ISR_code = %x\n", fault_ISR_code);
03479
#endif
03480
03481
#ifdef DEBUG_UNIX
03482
if ((OpCode &
F1_MIN_MASK) ==
F1_PATTERN)
03483 printf (
"DEBUG NEW_EXC FAULT PART RET FALSE: ps->state_FR[lf1] = %x %x %Lx\n",
03484 ps->
state_FR[lf1].
sign, ps->
state_FR[lf1].
exponent,
03485 ps->
state_FR[lf1].
significand);
03486
#endif
03487
03488
03489
03490 *pisr = ((*pisr) & 0xffffffffffff0000) | fault_ISR_code;
03491
03492
03493
if (SIMD_instruction)
03494
return (
FALSE |
SIMD_INSTRUCTION);
03495
else
03496
return (
FALSE);
03497
03498 }
else if (new_trap_type ==
FPTRAP) {
03499
03500
03501 trap_ISR_code = (ps->
state_MERCED_RTL >> 16) & 0x0ffff;
03502
03503
#ifdef DEBUG_UNIX
03504
printf (
"DEBUG fp_emulate () NEW_EXC trap_ISR_code = %4.4x\n", trap_ISR_code);
03505
#endif
03506
03507
03508
#ifdef DEBUG_UNIX
03509
printf (
"DEBUG NEW_EXC TRAP PART RET FALSE: ps->state_FR[lf1] = %x %x %Lx\n",
03510 ps->
state_FR[lf1].
sign, ps->
state_FR[lf1].
exponent,
03511 ps->
state_FR[lf1].
significand);
03512 printf (
"DEBUG NEW_EXC TRAP PART RET FALSE: f1 f2 f3 f4 = %x %x %x %x\n",
03513 f1, f2, f3, f4);
03514
#endif
03515
set_fp_register (f1,
FPRegToFP128(ps->
state_FR[lf1]), fp_state);
03516
if (f1 < 32)
03517 *pipsr = *pipsr | (
EM_uint64_t)0x10;
03518
else
03519 *pipsr = *pipsr | (
EM_uint64_t)0x20;
03520
03521
03522 *pisr = ((*pisr) & 0xffffffffffff0000) | trap_ISR_code;
03523
03524
03525 *pfpsr = ps->
state_AR[0].
uint_value;
03526
03527
03528
if (SIMD_instruction)
03529
return (
FALSE |
FAULT_TO_TRAP |
SIMD_INSTRUCTION);
03530
else
03531
return (
FALSE |
FAULT_TO_TRAP);
03532
03533 }
else {
03534
#ifndef unix
03535
FP_EMULATION_ERROR1 (
03536
"fp_emulate () Internal Error: new_trap_type = %x\n", new_trap_type)
03537 #
else
03538
FP_EMULATION_ERROR1 (
03539
"fp_emulate () Internal Error: new_trap_type = %x\n", new_trap_type)
03540 return (FP_EMUL_ERROR);
03541 #endif
03542 }
03543
03544 }