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
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 #include "float_rf.h"
00050
00051
00052
00053 #ifndef _DEFINES_H_
00054 #define _DEFINES_H_
00055
00056 #define EXP_INF 0x1ffff
00057 #define EXP_NAN 0x1ffff
00058 #define EXP_NATVAL 0x1ffff
00059 #define EXP_BIAS 0xffff
00060 #define SIGN_SHIFT 17
00061 #ifndef ULONGLONG_MAX
00062 #define ULONGLONG_MAX 0xffffffffffffffffull
00063 #endif
00064 #ifndef LONGLONG_MAX
00065 #define LONGLONG_MAX 0x7fffffffffffffffll
00066 #endif
00067 #define EXP_MIN -65534
00068
00069 #define GUARD_BIT 0x8000000000000000ull
00070 #define STICKY_BIT 0x4000000000000000ull
00071 #define HIGH_BIT 0x8000000000000000ull
00072 #define BIT23 (1ull << 23)
00073 #define BIT52 (1ull << 52)
00074 #define FP_RN 0
00075 #define FP_RM 1
00076 #define FP_RP 2
00077 #define FP_RZ 3
00078
00079 #define INFINITY 1
00080 #define MAXVAL 2
00081 #define MINFINITY 3
00082 #define MMAXVAL 4
00083
00084
00085
00086 #define UNDEF -1
00087 #define SNGL 0
00088 #define DBL 2
00089 #define DBL_EXT 3
00090
00091 #define NATVAL 1
00092 #define SIGNALING_NAN 2
00093 #define QUIET_NAN 4
00094
00095 #define STICKY_MASK 0x7fffffffffffffffull
00096
00097 #ifndef FALSE
00098 #define FALSE 0
00099 #endif
00100 #ifndef TRUE
00101 #define TRUE 1
00102 #endif
00103
00104 #define SEXP_MIN -126
00105 #define SEXP_MAX 127
00106
00107 #define DEXP_MIN -1022
00108 #define DEXP_MAX 1023
00109
00110 #define DEEXP_MIN -16382
00111 #define DEEXP_MAX 16383
00112
00113 #define WEXP_MIN -65534
00114 #define WEXP_MAX 65535
00115
00116 #endif
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136 #ifndef _FPSWA_H_
00137 #define _FPSWA_H_
00138
00139
00140 typedef enum {
00141 op_fcmp,
00142 op_fpcmp,
00143 op_fcvt_fx,
00144 op_fpcvt_fx,
00145 op_fcvt_fxu,
00146 op_fpcvt_fxu,
00147 op_fma,
00148 op_fpma,
00149 op_fminmax,
00150 op_fpminmax,
00151 op_fms_fnma,
00152 op_fpms_fpnma,
00153 op_fnorm,
00154 op_frcpa,
00155 op_fprcpa,
00156 op_frsqrta,
00157 op_fprsqrta
00158 } fp_op_type;
00159
00160
00161
00162 int fp_software_assistance_required(fp_op_type opcode,const float_rf *fr2,
00163 const float_rf *fr3, const float_rf *fr4,
00164 int sf_dd);
00165
00166 inline int fp_is_natval(const float_rf *freg);
00167 inline int fp_is_inf(const float_rf *freg);
00168 inline int fp_is_nan(const float_rf *freg);
00169 inline int fp_is_qnan(const float_rf *freg);
00170 inline int fp_is_snan(const float_rf *freg);
00171 inline int fp_is_neg_inf(const float_rf *freg);
00172 inline int fp_is_neg_non_zero(const float_rf *freg);
00173 inline int fp_is_normal(const float_rf *freg);
00174 inline int fp_is_pos_inf(const float_rf *freg);
00175 inline int fp_is_pos_non_zero(const float_rf *freg);
00176 inline int fp_is_pseudo_zero(const float_rf *freg);
00177 inline int fp_is_unorm(const float_rf *freg);
00178 inline int fp_is_unorm_not_pseudo_denorm(const float_rf *freg);
00179 inline int fp_is_unsupported(const float_rf *freg);
00180 inline int fp_is_zero(const float_rf *freg);
00181
00182
00183 #endif
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204 int
00205 fp_is_zero(const float_rf *freg){
00206
00207 if((freg->exp == 0) && (freg->frac == 0)) {
00208 return(1);
00209 }
00210 else {
00211 return(0);
00212 }
00213 }
00214
00215 int
00216 fp_is_natval(const float_rf *freg){
00217
00218 if((freg->sign == 0)
00219 && (freg->exp == 0x1fffe)
00220 && (freg->frac == 0)) {
00221 return(1);
00222 }
00223 else {
00224 return(0);
00225 }
00226 }
00227
00228 int
00229 fp_is_inf(const float_rf *freg){
00230
00231 if((freg->exp == 0x1ffff) && (freg->frac == 0x8000000000000000ull)) {
00232 return(1);
00233 }
00234 else {
00235 return(0);
00236 }
00237 }
00238
00239
00240 int
00241 fp_is_nan(const float_rf *freg){
00242
00243 if((freg->exp == 0x1ffff)
00244 && ((freg->frac & 0x8000000000000000ull) != 0)
00245 && ((freg->frac & 0x7fffffffffffffffull) != 0)) {
00246 return(1);
00247 }
00248 else {
00249 return(0);
00250 }
00251 }
00252
00253 int
00254 fp_is_snan(const float_rf *freg){
00255
00256 if((freg->exp == 0x1ffff)
00257 && ((freg->frac & 0xc000000000000000ull) == 0xc000000000000000ull)
00258 && ((freg->frac & 0x3fffffffffffffffull) != 0)){
00259 return(1);
00260 }
00261 else {
00262 return(0);
00263 }
00264 }
00265
00266 int
00267 fp_is_qnan(const float_rf *freg){
00268
00269 if((freg->exp == 0x1ffff)
00270 && ((freg->frac & 0xc000000000000000ull) == 0xc000000000000000ull)){
00271 return(1);
00272 }
00273 else {
00274 return(0);
00275 }
00276 }
00277
00278 int
00279 fp_is_neg_inf(const float_rf *freg){
00280
00281 if((freg->sign == 1)
00282 && (freg->exp == 0x1ffff)
00283 && (freg->frac == 0x8000000000000000ull)) {
00284 return(1);
00285 }
00286 else {
00287 return(0);
00288 }
00289 }
00290
00291 int
00292 fp_is_neg_non_zero(const float_rf *freg){
00293
00294 if((freg->sign == 1) && !fp_is_zero(freg)) {
00295 return(1);
00296 }
00297 else {
00298 return(0);
00299 }
00300 }
00301
00302 int
00303 fp_is_normal(const float_rf *freg){
00304
00305 if((freg->exp != 0)
00306 && (freg->exp != 0x1ffff)
00307 && ((freg->frac & 0x8000000000000000ull) != 0)) {
00308 return(1);
00309 }
00310 else {
00311 return(0);
00312 }
00313 }
00314
00315 int
00316 fp_is_pos_inf(const float_rf *freg){
00317
00318 if((freg->sign == 0)
00319 && (freg->exp == 0x1ffff)
00320 && (freg->frac == 0x8000000000000000ull)) {
00321 return(1);
00322 }
00323 else {
00324 return(0);
00325 }
00326 }
00327
00328 int
00329 fp_is_pos_non_zero(const float_rf *freg){
00330
00331 if((freg->sign == 0) && !fp_is_zero(freg)) {
00332 return(1);
00333 }
00334 else {
00335 return(0);
00336 }
00337 }
00338
00339 int
00340 fp_is_pseudo_zero(const float_rf *freg){
00341
00342 if((freg->exp != 0)
00343 && (freg->exp != 0x1ffff)
00344 && (freg->frac == 0)
00345 && (!fp_is_natval(freg))) {
00346 return(1);
00347 }
00348 else {
00349 return(0);
00350 }
00351 }
00352
00353 int
00354 fp_is_unorm(const float_rf *freg){
00355
00356 if((((freg->exp != 0)
00357 && (freg->exp != 0x1ffff)
00358 && ((freg->frac & 0x8000000000000000ull) == 0))
00359 && (!fp_is_natval(freg)))
00360
00361 || ((freg->exp == 0) && (freg->frac != 0))) {
00362 return(1);
00363 }
00364 else {
00365 return(0);
00366 }
00367 }
00368
00369
00370 int
00371 fp_is_unorm_not_pseudo_denorm(const float_rf *freg){
00372
00373 if(((freg->exp != 0)
00374 && (freg->exp != 0x1ffff)
00375 &&((freg->frac & 0x8000000000000000ull) == 0))
00376
00377 || ((freg->exp == 0) &&
00378 (freg->frac & 0x8000000000000000ull) == 0)) {
00379 return(1);
00380 }
00381 else {
00382 return(0);
00383 }
00384 }
00385
00386
00387 int
00388 fp_is_unsupported(const float_rf *freg){
00389
00390 if(fp_is_natval(freg) || fp_is_nan(freg) || fp_is_inf(freg)
00391 || fp_is_normal(freg) || fp_is_unorm(freg) || fp_is_zero(freg)) {
00392 return(0);
00393 }
00394 else {
00395 return(1);
00396 }
00397 }
00398
00399
00400 #ifdef BARF
00401 int
00402 fp_software_assistance_required(fp_op_type opcode,const float_rf *fr2,
00403 const float_rf *fr3, const float_rf *fr4,
00404 int sf_dd){
00405
00406 int do_swa_fault=0;
00407
00408
00409
00410
00411
00412
00413 switch (opcode) {
00414 case op_fcmp:
00415 if((fp_is_unsupported(fr2) || fp_is_unsupported(fr3)) ||
00416 (fp_is_nan(fr2) || fp_is_nan(fr3))){
00417 do_swa_fault = 0;
00418 }
00419 else if(fp_is_unorm(fr2) || fp_is_unorm(fr3)) {
00420 do_swa_fault = 1;
00421 }
00422 break;
00423
00424 case op_fpcmp:
00425 if(fp_is_nan(fr2) || fp_is_nan(fr3)) {
00426 do_swa_fault = 0;
00427 }
00428 else if(fp_is_unorm(fr2) || fp_is_unorm(fr3)) {
00429 do_swa_fault = 1;
00430 }
00431 break;
00432
00433 case op_fcvt_fx:
00434 if(fp_is_unsupported(fr2) || fp_is_nan(fr2)) {
00435 do_swa_fault = 0;
00436 }
00437 else if(fp_is_unorm(fr2)) {
00438 do_swa_fault = 1;
00439 }
00440 break;
00441
00442 case op_fpcvt_fx:
00443 if(fp_is_nan(fr2)) {
00444 do_swa_fault = 0;
00445 }
00446 else if(fp_is_unorm(fr2)) {
00447 do_swa_fault = 1;
00448 }
00449 break;
00450
00451 case op_fcvt_fxu:
00452 if(fp_is_unsupported(fr2) || fp_is_nan(fr2)) {
00453 do_swa_fault = 0;
00454 }
00455 else if(fp_is_unorm(fr2)) {
00456 do_swa_fault = 1;
00457 }
00458 break;
00459
00460 case op_fpcvt_fxu:
00461 if(fp_is_nan(fr2)) {
00462 do_swa_fault = 0;
00463 }
00464 else if(fp_is_unorm(fr2)) {
00465 do_swa_fault = 1;
00466 }
00467 break;
00468
00469 case op_fma:
00470 if(
00471 (fp_is_unsupported(fr2) || fp_is_unsupported(fr3) || fp_is_unsupported(fr4)) ||
00472 (fp_is_nan(fr2) || fp_is_nan(fr3) || fp_is_nan(fr4)) ||
00473
00474 ((fp_is_pos_inf(fr3) && fp_is_pos_non_zero(fr4) && fp_is_neg_inf(fr2))
00475 || (fp_is_pos_inf(fr3) && fp_is_neg_non_zero(fr4) && fp_is_pos_inf(fr2))
00476
00477 || (fp_is_neg_inf(fr3) && fp_is_pos_non_zero(fr4) && fp_is_pos_inf(fr2))
00478 || (fp_is_neg_inf(fr3) && fp_is_neg_non_zero(fr4) && fp_is_neg_inf(fr2))
00479
00480 || (fp_is_pos_non_zero(fr3) && fp_is_pos_inf(fr4) && fp_is_neg_inf(fr2))
00481 || (fp_is_pos_non_zero(fr3) && fp_is_neg_inf(fr4) && fp_is_pos_inf(fr2))
00482
00483 || (fp_is_neg_non_zero(fr3) && fp_is_pos_inf(fr4) && fp_is_pos_inf(fr2))
00484 || (fp_is_neg_non_zero(fr3) && fp_is_neg_inf(fr4) && fp_is_neg_inf(fr2))) ||
00485
00486 ((fp_is_inf(fr3) && fp_is_zero(fr4)) || (fp_is_zero(fr3) && fp_is_inf(fr4)))) {
00487 do_swa_fault = 0;
00488 }
00489 else if(fp_is_unorm(fr2) || fp_is_unorm(fr3) || fp_is_unorm(fr4)) {
00490 do_swa_fault = 1;
00491 }
00492 break;
00493
00494 case op_fpma:
00495 if(
00496 (fp_is_nan(fr2) || fp_is_nan(fr3) || fp_is_nan(fr4)) ||
00497
00498 ((fp_is_pos_inf(fr3) && fp_is_pos_non_zero(fr4)
00499 && fp_is_neg_inf(fr2))
00500 || (fp_is_pos_inf(fr3) && fp_is_neg_non_zero(fr4)
00501 && fp_is_pos_inf(fr2))
00502
00503 || (fp_is_neg_inf(fr3) && fp_is_pos_non_zero(fr4)
00504 && fp_is_pos_inf(fr2))
00505 || (fp_is_neg_inf(fr3) && fp_is_neg_non_zero(fr4)
00506 && fp_is_neg_inf(fr2))
00507
00508 || (fp_is_pos_non_zero(fr3) && fp_is_pos_inf(fr4)
00509 && fp_is_neg_inf(fr2))
00510 || (fp_is_pos_non_zero(fr3) && fp_is_neg_inf(fr4)
00511 && fp_is_pos_inf(fr2))
00512
00513 || (fp_is_neg_non_zero(fr3) && fp_is_pos_inf(fr4)
00514 && fp_is_pos_inf(fr2))
00515 || (fp_is_neg_non_zero(fr3) && fp_is_neg_inf(fr4)
00516 && fp_is_neg_inf(fr2))) ||
00517
00518 ((fp_is_inf(fr3) && fp_is_zero(fr4))
00519 || (fp_is_zero(fr3) && fp_is_inf(fr4)))) {
00520 do_swa_fault = 0;
00521 }
00522 else if(fp_is_unorm(fr2) || fp_is_unorm(fr3) || fp_is_unorm(fr4)) {
00523 do_swa_fault = 1;
00524 }
00525 break;
00526
00527 case op_fminmax:
00528 if((fp_is_unsupported(fr2) || fp_is_unsupported(fr3)) ||
00529 (fp_is_nan(fr2) || fp_is_nan(fr3)) ){
00530 do_swa_fault = 0;
00531 }
00532 else if(fp_is_unorm(fr2) || fp_is_unorm(fr3)) {
00533 do_swa_fault = 1;
00534 }
00535 break;
00536
00537 case op_fpminmax:
00538 if(fp_is_nan(fr2) || fp_is_nan(fr3)) {
00539 do_swa_fault = 0;
00540 }
00541 else if(fp_is_unorm(fr2) || fp_is_unorm(fr3)) {
00542 do_swa_fault = 1;
00543 }
00544 break;
00545
00546 case op_fms_fnma:
00547 if(
00548 (fp_is_unsupported(fr2) || fp_is_unsupported(fr3) || fp_is_unsupported(fr4)) ||
00549 (fp_is_nan(fr2) || fp_is_nan(fr3) || fp_is_nan(fr4)) ||
00550
00551 ((fp_is_pos_inf(fr3) && fp_is_pos_non_zero(fr4) && fp_is_pos_inf(fr2))
00552 || (fp_is_pos_inf(fr3) && fp_is_neg_non_zero(fr4) && fp_is_neg_inf(fr2))
00553 || (fp_is_neg_inf(fr3) && fp_is_pos_non_zero(fr4) && fp_is_neg_inf(fr2))
00554 || (fp_is_neg_inf(fr3) && fp_is_neg_non_zero(fr4) && fp_is_pos_inf(fr2))
00555 || (fp_is_pos_non_zero(fr3) && fp_is_pos_inf(fr4) && fp_is_pos_inf(fr2))
00556 || (fp_is_pos_non_zero(fr3) && fp_is_neg_inf(fr4) && fp_is_neg_inf(fr2))
00557 || (fp_is_neg_non_zero(fr3) && fp_is_pos_inf(fr4) && fp_is_neg_inf(fr2))
00558 || (fp_is_neg_non_zero(fr3) && fp_is_neg_inf(fr4) && fp_is_pos_inf(fr2))) ||
00559
00560 ((fp_is_inf(fr3) && fp_is_zero(fr4)) || (fp_is_zero(fr3) && fp_is_inf(fr4)))) {
00561 do_swa_fault = 0;
00562 }
00563 else if(fp_is_unorm(fr2) || fp_is_unorm(fr3) || fp_is_unorm(fr4)) {
00564 do_swa_fault = 1;
00565 }
00566 break;
00567
00568 case op_fpms_fpnma:
00569 if(
00570 (fp_is_unsupported(fr2) || fp_is_unsupported(fr3) || fp_is_unsupported(fr4)) ||
00571 (fp_is_nan(fr2) || fp_is_nan(fr3) || fp_is_nan(fr4)) ||
00572
00573 ((fp_is_pos_inf(fr3) && fp_is_pos_non_zero(fr4)
00574 && fp_is_pos_inf(fr2))
00575 || (fp_is_pos_inf(fr3) && fp_is_neg_non_zero(fr4)
00576 && fp_is_neg_inf(fr2))
00577 || (fp_is_neg_inf(fr3) && fp_is_pos_non_zero(fr4)
00578 && fp_is_neg_inf(fr2))
00579 || (fp_is_neg_inf(fr3) && fp_is_neg_non_zero(fr4)
00580 && fp_is_pos_inf(fr2))
00581 || (fp_is_pos_non_zero(fr3) && fp_is_pos_inf(fr4)
00582 && fp_is_pos_inf(fr2))
00583 || (fp_is_pos_non_zero(fr3) && fp_is_neg_inf(fr4)
00584 && fp_is_neg_inf(fr2))
00585 || (fp_is_neg_non_zero(fr3) && fp_is_pos_inf(fr4)
00586 && fp_is_neg_inf(fr2))
00587 || (fp_is_neg_non_zero(fr3) && fp_is_neg_inf(fr4)
00588 && fp_is_pos_inf(fr2))) ||
00589
00590 ((fp_is_inf(fr3) && fp_is_zero(fr4))
00591 || (fp_is_zero(fr3) && fp_is_inf(fr4)) )) {
00592 do_swa_fault = 0;
00593 }
00594 else if(fp_is_unorm(fr2) || fp_is_unorm(fr3) || fp_is_unorm(fr4)) {
00595 do_swa_fault = 1;
00596 }
00597 break;
00598
00599 case op_fnorm:
00600 if(fp_is_unsupported(fr3) || fp_is_nan(fr3)) {
00601 do_swa_fault = 0;
00602 }
00603 else if(fp_is_unorm(fr3)) {
00604 if(((fr3->exp > 0) && (fr3->exp < 0x1ffff)) &&
00605 (sf_dd == 1)) {
00606 do_swa_fault = 0;
00607 }
00608 else {
00609 do_swa_fault = 1;
00610 }
00611 }
00612 break;
00613
00614 case op_frcpa:
00615 if(
00616 (fp_is_unsupported(fr2) || fp_is_unsupported(fr3)) ||
00617 (fp_is_nan(fr2) || fp_is_nan(fr3)) ||
00618
00619 ((fp_is_inf(fr2) && fp_is_inf(fr3))
00620 || ((fp_is_zero(fr2) || fp_is_pseudo_zero(fr2))
00621 && (fp_is_zero(fr3) || fp_is_pseudo_zero(fr3)))) ||
00622
00623 (((fp_is_normal(fr2) && !fp_is_zero(fr2))
00624 || (fp_is_unorm(fr2) && !fp_is_pseudo_zero(fr2)))
00625 && (fp_is_zero(fr3) || fp_is_pseudo_zero(fr3)))) {
00626 do_swa_fault = 0;
00627 }
00628 else if(fp_is_unorm(fr2) || fp_is_unorm(fr3)) {
00629 do_swa_fault = 1;
00630 }
00631 break;
00632
00633 case op_fprcpa:
00634 if((fp_is_nan(fr2) || fp_is_nan(fr3)) ||
00635 ((fp_is_inf(fr2) && fp_is_inf(fr3))
00636 || (fp_is_zero(fr2) && fp_is_zero(fr3))) ||
00637 (!fp_is_zero(fr2) && fp_is_zero(fr3))) {
00638 do_swa_fault = 0;
00639 }
00640 else if(fp_is_unorm(fr2) || fp_is_unorm(fr3)) {
00641 do_swa_fault = 1;
00642 }
00643
00644 break;
00645
00646 case op_frsqrta:
00647 if(fp_is_unsupported(fr2) ||
00648 fp_is_nan(fr2) ||
00649 fp_is_neg_inf(fr2) ||
00650 (fp_is_neg_non_zero(fr2) && !fp_is_pseudo_zero(fr2) &&
00651 !fp_is_unorm_not_pseudo_denorm(fr2))) {
00652 do_swa_fault = 0;
00653 }
00654 else if(fp_is_unorm(fr2)) {
00655 do_swa_fault = 1;
00656 }
00657 break;
00658
00659 case op_fprsqrta:
00660 if(fp_is_nan(fr2) || fp_is_neg_inf(fr2) ||
00661 (fp_is_neg_non_zero(fr2) && !fp_is_unorm(fr2))) {
00662 do_swa_fault = 0;
00663 }
00664 else if(fp_is_unorm(fr2)) {
00665 do_swa_fault = 1;
00666 }
00667
00668 break;
00669 }
00670
00671 return(do_swa_fault);
00672
00673 }
00674 #endif
00675
00676
00677
00678
00679
00680
00681 float_rf
00682 Infinity_rf =
00683 {
00684 0, 0, 0x1ffff,
00685 0x8000000000000000ll,
00686 };
00687
00688 float_rf
00689 Quiet_nan_rf =
00690 {
00691 0, 1, 0x1ffff,
00692 0xc000000000000000ll,
00693 };
00694
00695 float_rf
00696 NaTVal_rf =
00697 {
00698 0, 0, 0x1ffff,
00699 0x4000000000000000ll,
00700 };
00701
00702 float_rf
00703 Zero_rf =
00704 {
00705 0, 0, 0x00000,
00706 0x0000000000000000ll,
00707 };
00708
00709
00710
00711
00712 #include <stdio.h>
00713
00714 #if !defined(linux)
00715 #include <inttypes.h>
00716 #endif
00717
00718
00719 static
00720 unsigned short
00721 recip_table[256] = {
00722 0x3fc, 0x3f4, 0x3ec, 0x3e4, 0x3dd, 0x3d5, 0x3cd, 0x3c6,
00723 0x3be, 0x3b7, 0x3af, 0x3a8, 0x3a1, 0x399, 0x392, 0x38b,
00724 0x384, 0x37d, 0x376, 0x36f, 0x368, 0x361, 0x35b, 0x354,
00725 0x34d, 0x346, 0x340, 0x339, 0x333, 0x32c, 0x326, 0x320,
00726 0x319, 0x313, 0x30d, 0x307, 0x300, 0x2fa, 0x2f4, 0x2ee,
00727 0x2e8, 0x2e2, 0x2dc, 0x2d7, 0x2d1, 0x2cb, 0x2c5, 0x2bf,
00728 0x2ba, 0x2b4, 0x2af, 0x2a9, 0x2a3, 0x29e, 0x299, 0x293,
00729 0x28e, 0x288, 0x283, 0x27e, 0x279, 0x273, 0x26e, 0x269,
00730 0x264, 0x25f, 0x25a, 0x255, 0x250, 0x24b, 0x246, 0x241,
00731 0x23c, 0x237, 0x232, 0x22e, 0x229, 0x224, 0x21f, 0x21b,
00732 0x216, 0x211, 0x20d, 0x208, 0x204, 0x1ff, 0x1fb, 0x1f6,
00733 0x1f2, 0x1ed, 0x1e9, 0x1e5, 0x1e0, 0x1dc, 0x1d8, 0x1d4,
00734 0x1cf, 0x1cb, 0x1c7, 0x1c3, 0x1bf, 0x1bb, 0x1b6, 0x1b2,
00735 0x1ae, 0x1aa, 0x1a6, 0x1a2, 0x19e, 0x19a, 0x197, 0x193,
00736 0x18f, 0x18b, 0x187, 0x183, 0x17f, 0x17c, 0x178, 0x174,
00737 0x171, 0x16d, 0x169, 0x166, 0x162, 0x15e, 0x15b, 0x157,
00738 0x154, 0x150, 0x14d, 0x149, 0x146, 0x142, 0x13f, 0x13b,
00739 0x138, 0x134, 0x131, 0x12e, 0x12a, 0x127, 0x124, 0x120,
00740 0x11d, 0x11a, 0x117, 0x113, 0x110, 0x10d, 0x10a, 0x107,
00741 0x103, 0x100, 0x0fd, 0x0fa, 0x0f7, 0x0f4, 0x0f1, 0x0ee,
00742 0x0eb, 0x0e8, 0x0e5, 0x0e2, 0x0df, 0x0dc, 0x0d9, 0x0d6,
00743 0x0d3, 0x0d0, 0x0cd, 0x0ca, 0x0c8, 0x0c5, 0x0c2, 0x0bf,
00744 0x0bc, 0x0b9, 0x0b7, 0x0b4, 0x0b1, 0x0ae, 0x0ac, 0x0a9,
00745 0x0a6, 0x0a4, 0x0a1, 0x09e, 0x09c, 0x099, 0x096, 0x094,
00746 0x091, 0x08e, 0x08c, 0x089, 0x087, 0x084, 0x082, 0x07f,
00747 0x07c, 0x07a, 0x077, 0x075, 0x073, 0x070, 0x06e, 0x06b,
00748 0x069, 0x066, 0x064, 0x061, 0x05f, 0x05d, 0x05a, 0x058,
00749 0x056, 0x053, 0x051, 0x04f, 0x04c, 0x04a, 0x048, 0x045,
00750 0x043, 0x041, 0x03f, 0x03c, 0x03a, 0x038, 0x036, 0x033,
00751 0x031, 0x02f, 0x02d, 0x02b, 0x029, 0x026, 0x024, 0x022,
00752 0x020, 0x01e, 0x01c, 0x01a, 0x018, 0x015, 0x013, 0x011,
00753 0x00f, 0x00d, 0x00b, 0x009, 0x007, 0x005, 0x003, 0x001
00754 };
00755
00756 unsigned short recip_sqrt_table[256] = {
00757 0x1a5, 0x1a0, 0x19a, 0x195, 0x18f, 0x18a, 0x185, 0x180,
00758 0x17a, 0x175, 0x170, 0x16b, 0x166, 0x161, 0x15d, 0x158,
00759 0x153, 0x14e, 0x14a, 0x145, 0x140, 0x13c, 0x138, 0x133,
00760 0x12f, 0x12a, 0x126, 0x122, 0x11e, 0x11a, 0x115, 0x111,
00761 0x10d, 0x109, 0x105, 0x101, 0x0fd, 0x0fa, 0x0f6, 0x0f2,
00762 0x0ee, 0x0ea, 0x0e7, 0x0e3, 0x0df, 0x0dc, 0x0d8, 0x0d5,
00763 0x0d1, 0x0ce, 0x0ca, 0x0c7, 0x0c3, 0x0c0, 0x0bd, 0x0b9,
00764 0x0b6, 0x0b3, 0x0b0, 0x0ad, 0x0a9, 0x0a6, 0x0a3, 0x0a0,
00765 0x09d, 0x09a, 0x097, 0x094, 0x091, 0x08e, 0x08b, 0x088,
00766 0x085, 0x082, 0x07f, 0x07d, 0x07a, 0x077, 0x074, 0x071,
00767 0x06f, 0x06c, 0x069, 0x067, 0x064, 0x061, 0x05f, 0x05c,
00768 0x05a, 0x057, 0x054, 0x052, 0x04f, 0x04d, 0x04a, 0x048,
00769 0x045, 0x043, 0x041, 0x03e, 0x03c, 0x03a, 0x037, 0x035,
00770 0x033, 0x030, 0x02e, 0x02c, 0x029, 0x027, 0x025, 0x023,
00771 0x020, 0x01e, 0x01c, 0x01a, 0x018, 0x016, 0x014, 0x011,
00772 0x00f, 0x00d, 0x00b, 0x009, 0x007, 0x005, 0x003, 0x001,
00773 0x3fc, 0x3f4, 0x3ec, 0x3e5, 0x3dd, 0x3d5, 0x3cd, 0x3c7,
00774 0x3bf, 0x3b8, 0x3b1, 0x3aa, 0x3a3, 0x39c, 0x395, 0x38e,
00775 0x388, 0x381, 0x37a, 0x374, 0x36d, 0x367, 0x361, 0x35a,
00776 0x354, 0x34e, 0x348, 0x342, 0x33c, 0x336, 0x330, 0x32b,
00777 0x325, 0x31f, 0x31a, 0x314, 0x30f, 0x309, 0x304, 0x2fe,
00778 0x2f9, 0x2f4, 0x2ee, 0x2e9, 0x2e4, 0x2df, 0x2da, 0x2d5,
00779 0x2d0, 0x2cb, 0x2c6, 0x2c1, 0x2bd, 0x2b8, 0x2b3, 0x2ae,
00780 0x2aa, 0x2a5, 0x2a1, 0x29c, 0x298, 0x293, 0x28f, 0x28a,
00781 0x286, 0x282, 0x27d, 0x279, 0x275, 0x271, 0x26d, 0x268,
00782 0x264, 0x260, 0x25c, 0x258, 0x254, 0x250, 0x24c, 0x249,
00783 0x245, 0x241, 0x23d, 0x239, 0x235, 0x232, 0x22e, 0x22a,
00784 0x227, 0x223, 0x220, 0x21c, 0x218, 0x215, 0x211, 0x20e,
00785 0x20a, 0x207, 0x204, 0x200, 0x1fd, 0x1f9, 0x1f6, 0x1f3,
00786 0x1f0, 0x1ec, 0x1e9, 0x1e6, 0x1e3, 0x1df, 0x1dc, 0x1d9,
00787 0x1d6, 0x1d3, 0x1d0, 0x1cd, 0x1ca, 0x1c7, 0x1c4, 0x1c1,
00788 0x1be, 0x1bb, 0x1b8, 0x1b5, 0x1b2, 0x1af, 0x1ac, 0x1aa,
00789 };
00790
00791
00792
00793
00794
00795 float_rf
00796 fma( const float_rf *rs, const float_rf *rt, const float_rf *rr, status_field *sf )
00797 {
00798 uint32_t rssign, rtsign, rrsign;
00799 int32_t rsexp, rtexp, rrexp;
00800 uint64_t rsfrac, rtfrac, rrfrac;
00801 int32_t op_type;
00802 float_rf result_rf;
00803
00804 #ifdef FP_DEBUG
00805 fprintf(stderr, "fma: rs.sign = %x\n", (*rs).sign);
00806 fprintf(stderr, " rs.exp = %x\n", (*rs).exp);
00807 fprintf(stderr, " rs.frac = %016llx\n", (*rs).frac);
00808 fprintf(stderr, " rt.sign = %x\n", (*rt).sign);
00809 fprintf(stderr, " rt.exp = %x\n", (*rt).exp);
00810 fprintf(stderr, " rt.frac = %016llx\n", (*rt).frac);
00811 fprintf(stderr, " rr.sign = %x\n", (*rr).sign);
00812 fprintf(stderr, " rr.exp = %x\n", (*rr).exp);
00813 fprintf(stderr, " rr.frac = %016llx\n", (*rr).frac);
00814 fprintf(stderr, " sf = %016llx\n\n", sf->i);
00815 #endif
00816
00817 if(fp_software_assistance_required(op_fma,rs,rt,rr,sf->b.den_unn_op_trap_disabled)){
00818 sf->b.ISR_fpa = 1;
00819 return(Zero_rf);
00820 }
00821
00822 if ( op_type = breakout_and_test3(rs, &rssign, &rsexp, &rsfrac,
00823 rt, &rtsign, &rtexp, &rtfrac,
00824 rr, &rrsign, &rrexp, &rrfrac,
00825 sf)
00826 )
00827 {
00828 #ifdef FP_DEBUG
00829 fprintf(stderr, " op_type = %x\n", op_type);
00830 #endif
00831 if ( op_type == NATVAL )
00832 {
00833 result_rf = NaTVal_rf;
00834
00835 return ( result_rf );
00836 }
00837 else if ( op_type == SIGNALING_NAN )
00838 {
00839 sf->b.invalid_flag = 1;
00840
00841 result_rf = Quiet_nan_rf;
00842 return ( result_rf );
00843 }
00844 else if ( op_type == QUIET_NAN )
00845 {
00846
00847
00848 sf->b.invalid_flag = 1;
00849
00850 if ( (rsexp == EXP_NAN) && (rsfrac > (1ull << 63)) )
00851 {
00852 result_rf = *rs;
00853 return ( result_rf );
00854 }
00855 else if ( (rtexp == EXP_NAN) && (rtfrac > (1ull << 63)) )
00856 {
00857 result_rf = *rt;
00858 return ( result_rf );
00859 }
00860 else
00861 {
00862 result_rf = *rr;
00863 return ( result_rf );
00864 }
00865 }
00866 }
00867
00868 return ( madd(rssign, rsexp, rsfrac, rtsign, rtexp, rtfrac,
00869 rrsign, rrexp, rrfrac, sf) );
00870 }
00871
00872
00873
00874
00875
00876
00877
00878 float_rf
00879 fnorm( const float_rf *rs, const float_rf *rt, const float_rf *rr, status_field *sf )
00880 {
00881 uint32_t rssign, rtsign, rrsign;
00882 int32_t rsexp, rtexp, rrexp;
00883 uint64_t rsfrac, rtfrac, rrfrac;
00884 int32_t op_type;
00885 float_rf result_rf;
00886
00887 #ifdef FP_DEBUG
00888 fprintf(stderr, "fma: rs.sign = %x\n", (*rs).sign);
00889 fprintf(stderr, " rs.exp = %x\n", (*rs).exp);
00890 fprintf(stderr, " rs.frac = %016llx\n", (*rs).frac);
00891 fprintf(stderr, " rt.sign = %x\n", (*rt).sign);
00892 fprintf(stderr, " rt.exp = %x\n", (*rt).exp);
00893 fprintf(stderr, " rt.frac = %016llx\n", (*rt).frac);
00894 fprintf(stderr, " rr.sign = %x\n", (*rr).sign);
00895 fprintf(stderr, " rr.exp = %x\n", (*rr).exp);
00896 fprintf(stderr, " rr.frac = %016llx\n", (*rr).frac);
00897 fprintf(stderr, " sf = %016llx\n\n", sf->i);
00898 #endif
00899
00900 if(fp_software_assistance_required(op_fnorm,rs,rt,rr,sf->b.den_unn_op_trap_disabled)){
00901 sf->b.ISR_fpa = 1;
00902 return(Zero_rf);
00903 }
00904
00905 if ( op_type = breakout_and_test3(rs, &rssign, &rsexp, &rsfrac,
00906 rt, &rtsign, &rtexp, &rtfrac,
00907 rr, &rrsign, &rrexp, &rrfrac,
00908 sf)
00909 )
00910 {
00911 #ifdef FP_DEBUG
00912 fprintf(stderr, " op_type = %x\n", op_type);
00913 #endif
00914 if ( op_type == NATVAL )
00915 {
00916 result_rf = NaTVal_rf;
00917
00918 return ( result_rf );
00919 }
00920 else if ( op_type == SIGNALING_NAN )
00921 {
00922 sf->b.invalid_flag = 1;
00923
00924 result_rf = Quiet_nan_rf;
00925 return ( result_rf );
00926 }
00927 else if ( op_type == QUIET_NAN )
00928 {
00929
00930
00931 sf->b.invalid_flag = 1;
00932
00933 if ( (rsexp == EXP_NAN) && (rsfrac > (1ull << 63)) )
00934 {
00935 result_rf = *rs;
00936 return ( result_rf );
00937 }
00938 else if ( (rtexp == EXP_NAN) && (rtfrac > (1ull << 63)) )
00939 {
00940 result_rf = *rt;
00941 return ( result_rf );
00942 }
00943 else
00944 {
00945 result_rf = *rr;
00946 return ( result_rf );
00947 }
00948 }
00949 }
00950
00951 return ( madd(rssign, rsexp, rsfrac, rtsign, rtexp, rtfrac,
00952 rrsign, rrexp, rrfrac, sf) );
00953 }
00954
00955
00956
00957
00958 float_rf
00959 fms( const float_rf *rs, const float_rf *rt, const float_rf *rr, status_field *sf )
00960 {
00961 uint32_t rssign, rtsign, rrsign;
00962 int32_t rsexp, rtexp, rrexp;
00963 uint64_t rsfrac, rtfrac, rrfrac;
00964 int32_t op_type;
00965 float_rf result_rf;
00966
00967 if(fp_software_assistance_required(op_fms_fnma,rs,rt,rr,0)){
00968 sf->b.ISR_fpa = 1;
00969 return(Zero_rf);
00970 }
00971
00972 if ( op_type = breakout_and_test3(rs, &rssign, &rsexp, &rsfrac,
00973 rt, &rtsign, &rtexp, &rtfrac,
00974 rr, &rrsign, &rrexp, &rrfrac,
00975 sf)
00976 )
00977 {
00978 if ( op_type == NATVAL )
00979 {
00980 result_rf = NaTVal_rf;
00981
00982 return ( result_rf );
00983 }
00984 else if ( op_type == SIGNALING_NAN )
00985 {
00986 sf->b.invalid_flag = 1;
00987
00988 result_rf = Quiet_nan_rf;
00989 return ( result_rf );
00990 }
00991 else if ( op_type == QUIET_NAN )
00992 {
00993
00994 sf->b.invalid_flag = 1;
00995
00996 if ( (rsexp == EXP_NAN) && (rsfrac > (1ull << 63)) )
00997 {
00998 result_rf = *rs;
00999 return ( result_rf );
01000 }
01001 else if ( (rtexp == EXP_NAN) && (rtfrac > (1ull << 63)) )
01002 {
01003 result_rf = *rt;
01004 return ( result_rf );
01005 }
01006 else
01007 {
01008 result_rf = *rr;
01009 return ( result_rf );
01010 }
01011 }
01012 }
01013
01014 return ( madd(rssign, rsexp, rsfrac, rtsign, rtexp, rtfrac,
01015 rrsign ^ 1, rrexp, rrfrac, sf) );
01016 }
01017
01018
01019
01020 float_rf
01021 fnma( const float_rf *rs, const float_rf *rt, const float_rf *rr, status_field *sf )
01022 {
01023 uint32_t rssign, rtsign, rrsign;
01024 int32_t rsexp, rtexp, rrexp;
01025 uint64_t rsfrac, rtfrac, rrfrac;
01026 int32_t op_type;
01027 float_rf result_rf;
01028
01029 if(fp_software_assistance_required(op_fms_fnma,rs,rt,rr,0)){
01030 sf->b.ISR_fpa = 1;
01031 return(Zero_rf);
01032 }
01033
01034 if ( op_type = breakout_and_test3(rs, &rssign, &rsexp, &rsfrac,
01035 rt, &rtsign, &rtexp, &rtfrac,
01036 rr, &rrsign, &rrexp, &rrfrac,
01037 sf)
01038 )
01039 {
01040 if ( op_type == NATVAL )
01041 {
01042 result_rf = NaTVal_rf;
01043
01044 return ( result_rf );
01045 }
01046 else if ( op_type == SIGNALING_NAN )
01047 {
01048 sf->b.invalid_flag = 1;
01049
01050 result_rf = Quiet_nan_rf;
01051 return ( result_rf );
01052 }
01053 else if ( op_type == QUIET_NAN )
01054 {
01055
01056
01057 sf->b.invalid_flag = 1;
01058
01059 if ( (rsexp == EXP_NAN) && (rsfrac > (1ull << 63)) )
01060 {
01061 result_rf = *rs;
01062 return ( result_rf );
01063 }
01064 else if ( (rtexp == EXP_NAN) && (rtfrac > (1ull << 63)) )
01065 {
01066 result_rf = *rt;
01067 return ( result_rf );
01068 }
01069 else
01070 {
01071 result_rf = *rr;
01072 return ( result_rf );
01073 }
01074 }
01075 }
01076
01077 return ( madd(rssign ^ 1, rsexp, rsfrac, rtsign, rtexp, rtfrac,
01078 rrsign, rrexp, rrfrac, sf) );
01079 }
01080
01081
01082
01083
01084 float_rf
01085 fmin( const float_rf *rs, const float_rf *rt, status_field *sf )
01086 {
01087 uint32_t rssign, rtsign;
01088 int32_t rsexp, rtexp;
01089 uint64_t rsfrac, rtfrac;
01090 int32_t op_type;
01091 float_rf result_rf;
01092
01093 if(fp_software_assistance_required(op_fminmax,rs,rt,NULL,0)){
01094 sf->b.ISR_fpa = 1;
01095 }
01096
01097 if ( op_type = breakout_and_test2(rs, &rssign, &rsexp, &rsfrac,
01098 rt, &rtsign, &rtexp, &rtfrac, sf)
01099 )
01100 {
01101 if ( op_type == NATVAL )
01102 {
01103 result_rf = NaTVal_rf;
01104
01105 return ( result_rf );
01106 }
01107 else if ( (op_type == SIGNALING_NAN) || (op_type == QUIET_NAN) )
01108 {
01109 sf->b.invalid_flag = 1;
01110
01111 result_rf = *rt;
01112 return ( result_rf );
01113 }
01114 }
01115
01116
01117
01118
01119
01120 if ( (rsexp == 0) && (rsfrac == 0) &&
01121 (rtexp == 0) && (rtfrac == 0)
01122 )
01123 {
01124
01125
01126 result_rf = *rt;
01127 return ( result_rf );
01128 }
01129
01130 if ( (rsexp == 0) && (rsfrac == 0) )
01131 {
01132 if ( rtsign == 1 )
01133 {
01134
01135
01136 result_rf = *rt;
01137 return ( result_rf );
01138 }
01139 else
01140 {
01141 result_rf = *rs;
01142 return ( result_rf );
01143 }
01144 }
01145
01146 if ( (rtexp == 0) && (rtfrac == 0) )
01147 {
01148 if ( rssign == 1 )
01149 {
01150
01151
01152 result_rf = *rs;
01153 return ( result_rf );
01154 }
01155 else
01156 {
01157 result_rf = *rt;
01158 return ( result_rf );
01159 }
01160 }
01161
01162 if ( (rssign == 0) && (rtsign == 1) )
01163 {
01164 result_rf = *rt;
01165 return ( result_rf );
01166 }
01167
01168 if ( (rssign == 1) && (rtsign == 0) )
01169 {
01170 result_rf = *rs;
01171 return ( result_rf );
01172 }
01173
01174
01175
01176 if ( (rsexp == rtexp) && (rsfrac == rtfrac) )
01177 {
01178 result_rf = *rt;
01179 return ( result_rf );
01180 }
01181
01182 if ( rssign == 0 )
01183 {
01184 if ( rsexp < rtexp )
01185 {
01186 result_rf = *rs;
01187 return ( result_rf );
01188 }
01189 else if ( rsexp > rtexp )
01190 {
01191 result_rf = *rt;
01192 return ( result_rf );
01193 }
01194 else if ( rsfrac < rtfrac )
01195 {
01196 result_rf = *rs;
01197 return ( result_rf );
01198 }
01199 else
01200 {
01201 result_rf = *rt;
01202 return ( result_rf );
01203 }
01204 }
01205 else
01206 {
01207 if ( rsexp < rtexp )
01208 {
01209 result_rf = *rt;
01210 return ( result_rf );
01211 }
01212 else if ( rsexp > rtexp )
01213 {
01214 result_rf = *rs;
01215 return ( result_rf );
01216 }
01217 else if ( rsfrac < rtfrac )
01218 {
01219 result_rf = *rt;
01220 return ( result_rf );
01221 }
01222 else
01223 {
01224 result_rf = *rs;
01225 return ( result_rf );
01226 }
01227 }
01228 }
01229
01230
01231
01232 float_rf
01233 fmax( const float_rf *rs, const float_rf *rt, status_field *sf )
01234 {
01235 uint32_t rssign, rtsign;
01236 int32_t rsexp, rtexp;
01237 uint64_t rsfrac, rtfrac;
01238 int32_t op_type;
01239 float_rf result_rf;
01240
01241 if(fp_software_assistance_required(op_fminmax,rs,rt,NULL,0)){
01242 sf->b.ISR_fpa = 1;
01243 }
01244
01245 if ( op_type = breakout_and_test2(rs, &rssign, &rsexp, &rsfrac,
01246 rt, &rtsign, &rtexp, &rtfrac, sf)
01247 )
01248 {
01249 if ( op_type == NATVAL )
01250 {
01251 result_rf = NaTVal_rf;
01252
01253 return ( result_rf );
01254 }
01255 else if ( (op_type == SIGNALING_NAN) || (op_type == QUIET_NAN) )
01256 {
01257 sf->b.invalid_flag = 1;
01258
01259 result_rf = *rt;
01260 return ( result_rf );
01261 }
01262 }
01263
01264
01265
01266
01267
01268 if ( (rsexp == 0) && (rsfrac == 0) &&
01269 (rtexp == 0) && (rtfrac == 0)
01270 )
01271 {
01272
01273
01274 result_rf = *rt;
01275 return ( result_rf );
01276 }
01277
01278 if ( (rsexp == 0) && (rsfrac == 0) )
01279 {
01280 if ( rtsign == 1 )
01281 {
01282
01283
01284 result_rf = *rs;
01285 return ( result_rf );
01286 }
01287 else
01288 {
01289 result_rf = *rt;
01290 return ( result_rf );
01291 }
01292 }
01293
01294 if ( (rtexp == 0) && (rtfrac == 0) )
01295 {
01296 if ( rssign == 1 )
01297 {
01298
01299
01300 result_rf = *rt;
01301 return ( result_rf );
01302 }
01303 else
01304 {
01305 result_rf = *rs;
01306 return ( result_rf );
01307 }
01308 }
01309
01310 if ( (rssign == 0) && (rtsign == 1) )
01311 {
01312 result_rf = *rs;
01313 return ( result_rf );
01314 }
01315
01316 if ( (rssign == 1) && (rtsign == 0) )
01317 {
01318 result_rf = *rt;
01319 return ( result_rf );
01320 }
01321
01322
01323
01324 if ( (rsexp == rtexp) && (rsfrac == rtfrac) )
01325 {
01326 result_rf = *rt;
01327 return ( result_rf );
01328 }
01329
01330 if ( rssign == 0 )
01331 {
01332 if ( rsexp < rtexp )
01333 {
01334 result_rf = *rt;
01335 return ( result_rf );
01336 }
01337 else if ( rsexp > rtexp )
01338 {
01339 result_rf = *rs;
01340 return ( result_rf );
01341 }
01342 else if ( rsfrac < rtfrac )
01343 {
01344 result_rf = *rt;
01345 return ( result_rf );
01346 }
01347 else
01348 {
01349 result_rf = *rs;
01350 return ( result_rf );
01351 }
01352 }
01353 else
01354 {
01355 if ( rsexp < rtexp )
01356 {
01357 result_rf = *rs;
01358 return ( result_rf );
01359 }
01360 else if ( rsexp > rtexp )
01361 {
01362 result_rf = *rt;
01363 return ( result_rf );
01364 }
01365 else if ( rsfrac < rtfrac )
01366 {
01367 result_rf = *rs;
01368 return ( result_rf );
01369 }
01370 else
01371 {
01372 result_rf = *rt;
01373 return ( result_rf );
01374 }
01375 }
01376 }
01377
01378
01379
01380
01381 float_rf
01382 famin( const float_rf *rs, const float_rf *rt, status_field *sf )
01383 {
01384 uint32_t rssign, rtsign;
01385 int32_t rsexp, rtexp;
01386 uint64_t rsfrac, rtfrac;
01387 int32_t op_type;
01388 float_rf result_rf;
01389
01390 if(fp_software_assistance_required(op_fminmax,rs,rt,NULL,0)){
01391 sf->b.ISR_fpa = 1;
01392 }
01393
01394 if ( op_type = breakout_and_test2(rs, &rssign, &rsexp, &rsfrac,
01395 rt, &rtsign, &rtexp, &rtfrac, sf)
01396 )
01397 {
01398 if ( op_type == NATVAL )
01399 {
01400 result_rf = NaTVal_rf;
01401
01402 return ( result_rf );
01403 }
01404 else if ( (op_type == SIGNALING_NAN) || (op_type == QUIET_NAN) )
01405 {
01406 sf->b.invalid_flag = 1;
01407
01408 result_rf = *rt;
01409 return ( result_rf );
01410 }
01411 }
01412
01413
01414
01415
01416
01417 if ( (rsexp == 0) && (rsfrac == 0) &&
01418 (rtexp == 0) && (rtfrac == 0)
01419 )
01420 {
01421
01422
01423 result_rf = *rt;
01424 return ( result_rf );
01425 }
01426
01427 if ( (rsexp == rtexp) && (rsfrac == rtfrac) )
01428 {
01429 result_rf = *rt;
01430 return ( result_rf );
01431 }
01432
01433 if ( (rsexp < rtexp) || ((rsexp == rtexp) && (rsfrac < rtfrac)) )
01434 {
01435 result_rf = *rs;
01436 return ( result_rf );
01437 }
01438 else
01439 {
01440 result_rf = *rt;
01441 return ( result_rf );
01442 }
01443 }
01444
01445
01446
01447 float_rf
01448 famax( const float_rf *rs, const float_rf *rt, status_field *sf )
01449 {
01450 uint32_t rssign, rtsign;
01451 int32_t rsexp, rtexp;
01452 uint64_t rsfrac, rtfrac;
01453 int32_t op_type;
01454 float_rf result_rf;
01455
01456 if(fp_software_assistance_required(op_fminmax,rs,rt,NULL,0)){
01457 sf->b.ISR_fpa = 1;
01458 }
01459
01460 if ( op_type = breakout_and_test2(rs, &rssign, &rsexp, &rsfrac,
01461 rt, &rtsign, &rtexp, &rtfrac, sf)
01462 )
01463 {
01464 if ( op_type == NATVAL )
01465 {
01466 result_rf = NaTVal_rf;
01467
01468 return ( result_rf );
01469 }
01470 else if ( (op_type == SIGNALING_NAN) || (op_type == QUIET_NAN) )
01471 {
01472 sf->b.invalid_flag = 1;
01473
01474 result_rf = *rt;
01475 return ( result_rf );
01476 }
01477 }
01478
01479
01480
01481
01482
01483 if ( (rsexp == 0) && (rsfrac == 0) &&
01484 (rtexp == 0) && (rtfrac == 0)
01485 )
01486 {
01487
01488
01489 result_rf = *rt;
01490 return ( result_rf );
01491 }
01492
01493
01494
01495 if ( (rsexp == 0) && (rsfrac == 0) &&
01496 (rtexp == 0) && (rtfrac == 0)
01497 )
01498 {
01499
01500
01501 result_rf = *rt;
01502 return ( result_rf );
01503 }
01504
01505 if ( (rsexp == rtexp) && (rsfrac == rtfrac) )
01506 {
01507 result_rf = *rt;
01508 return ( result_rf );
01509 }
01510
01511 if ( (rsexp < rtexp) || ((rsexp == rtexp) && (rsfrac < rtfrac)) )
01512 {
01513 result_rf = *rt;
01514 return ( result_rf );
01515 }
01516 else
01517 {
01518 result_rf = *rs;
01519 return ( result_rf );
01520 }
01521 }
01522
01523
01524
01525 float_rf
01526 fcvtfx( const float_rf *rs, status_field *sf )
01527 {
01528 uint32_t rssign;
01529 int32_t rsexp;
01530 uint64_t rsfrac;
01531 int32_t op_type;
01532 float_rf result_rf;
01533 uint64_t guard_bits;
01534 int32_t shift_count;
01535
01536 #ifdef FP_DEBUG
01537 fprintf(stderr, "fcvtfx: rs.sign = %x\n", rs->sign);
01538 fprintf(stderr, " rs.exp = %x\n", rs->exp);
01539 fprintf(stderr, " rs.frac = %016llx\n", rs->frac);
01540 fprintf(stderr, " sf = %016llx\n", sf->i);
01541 #endif
01542
01543 if(fp_software_assistance_required(op_fcvt_fx,rs,NULL,NULL,0)){
01544 sf->b.ISR_fpa = 1;
01545 return(Zero_rf);
01546 }
01547
01548 op_type = breakout_and_test( rs, &rssign, &rsexp, &rsfrac, sf );
01549
01550
01551
01552 if ( (rssign == 1) && (rsexp == (63 + EXP_BIAS)) &&
01553 (rsfrac == HIGH_BIT)
01554 )
01555 {
01556
01557
01558 result_rf = *rs;
01559 result_rf.sign = 0;
01560
01561 return ( result_rf );
01562 }
01563
01564
01565
01566
01567
01568 if ( op_type == NATVAL )
01569 {
01570 result_rf = NaTVal_rf;
01571
01572 return ( result_rf );
01573 }
01574 else if ( (op_type == SIGNALING_NAN) ||
01575 (op_type == QUIET_NAN) ||
01576 (rsexp >= 63 + EXP_BIAS)
01577 )
01578 {
01579 sf->b.invalid_flag = 1;
01580
01581 result_rf.sign = 0;
01582 result_rf.exp = 0x1003e;
01583 result_rf.frac = LONGLONG_MAX;
01584
01585 return ( result_rf );
01586 }
01587
01588
01589
01590 if ( (rsexp == 0) && (rsfrac == 0ull) )
01591 {
01592
01593
01594 result_rf.sign = 0;
01595 result_rf.exp = 0;
01596 result_rf.frac = 0;
01597
01598 return ( result_rf );
01599 }
01600
01601 rsexp -= EXP_BIAS;
01602
01603 if ( rsexp < -1 )
01604 {
01605 rsfrac = 0;
01606 guard_bits = STICKY_BIT;
01607 }
01608 else if ( rsexp == -1 )
01609 {
01610 guard_bits = rsfrac;
01611 rsfrac = 0;
01612 }
01613 else
01614 {
01615 shift_count = 63 - rsexp;
01616
01617 guard_bits = (rsfrac << (64 - shift_count));
01618 rsfrac >>= shift_count;
01619 }
01620
01621 #ifdef FP_DEBUG
01622 fprintf(stderr, "fpcvtfx calling round_l\n");
01623 fprintf(stderr, " rssign = %x\n", rssign);
01624 fprintf(stderr, " rsfrac = %016llx\n", rsfrac);
01625 fprintf(stderr, " guard_bits = %016llx\n\n", guard_bits);
01626 #endif
01627
01628 result_rf = round_l(rssign, rsfrac, guard_bits, sf);
01629
01630 #ifdef FP_DEBUG
01631 fprintf(stderr, "fpcvtfx: returning\n");
01632 fprintf(stderr, " result_rf.sign = %x\n", result_rf.sign);
01633 fprintf(stderr, " result_rf.exp = %x\n", result_rf.exp);
01634 fprintf(stderr, " result_rf.frac = %016llx\n", result_rf.frac);
01635 #endif
01636
01637 return ( result_rf );
01638 }
01639
01640
01641
01642 float_rf
01643 fcvtfxtrunc( const float_rf *rs, status_field *sf )
01644 {
01645 uint32_t rssign;
01646 int32_t rsexp;
01647 uint64_t rsfrac;
01648 int32_t op_type;
01649 float_rf result_rf;
01650 uint64_t guard_bits;
01651 int32_t shift_count;
01652
01653 #ifdef FP_DEBUG
01654 fprintf(stderr, "fcvtfxtrunc: rs.sign = %x\n", rs->sign);
01655 fprintf(stderr, " rs.exp = %x\n", rs->exp);
01656 fprintf(stderr, " rs.frac = %016llx\n", rs->frac);
01657 fprintf(stderr, " sf = %016llx\n", sf->i);
01658 #endif
01659
01660 if(fp_software_assistance_required(op_fcvt_fx,rs,NULL,NULL,0)){
01661 sf->b.ISR_fpa = 1;
01662 return(Zero_rf);
01663 }
01664
01665 op_type = breakout_and_test( rs, &rssign, &rsexp, &rsfrac, sf );
01666
01667
01668
01669 if ( (rssign == 1) && (rsexp == (63 + EXP_BIAS)) &&
01670 (rsfrac == HIGH_BIT)
01671 )
01672 {
01673
01674
01675 result_rf = *rs;
01676 result_rf.sign = 0;
01677
01678 return ( result_rf );
01679 }
01680
01681
01682
01683
01684
01685 if ( op_type == NATVAL )
01686 {
01687 result_rf = NaTVal_rf;
01688
01689 return ( result_rf );
01690 }
01691 else if ( (op_type == SIGNALING_NAN) ||
01692 (op_type == QUIET_NAN) ||
01693 (rsexp >= 63 + EXP_BIAS)
01694 )
01695 {
01696 sf->b.invalid_flag = 1;
01697
01698 result_rf.sign = 0;
01699 result_rf.exp = 0x1003e;
01700 result_rf.frac = LONGLONG_MAX;
01701
01702 return ( result_rf );
01703 }
01704
01705
01706
01707 if ( (rsexp == 0) && (rsfrac == 0ull) )
01708 {
01709
01710
01711 result_rf.sign = 0;
01712 result_rf.exp = 0;
01713 result_rf.frac = 0;
01714
01715 return ( result_rf );
01716 }
01717
01718 rsexp -= EXP_BIAS;
01719
01720 if ( rsexp <= -1 )
01721 {
01722 sf->b.inexact_flag = 1;
01723
01724 return ( Zero_rf );
01725 }
01726 else
01727 {
01728 shift_count = 63 - rsexp;
01729
01730 guard_bits = (rsfrac << (64 - shift_count));
01731 rsfrac >>= shift_count;
01732
01733 result_rf.sign = 0;
01734 result_rf.exp = 0x1003e;
01735 if ( rssign == 0 )
01736 result_rf.frac = rsfrac;
01737 else
01738 result_rf.frac = -rsfrac;
01739
01740 if ( guard_bits != 0 )
01741 sf->b.inexact_flag = 1;
01742
01743 return ( result_rf );
01744 }
01745 }
01746
01747
01748
01749 float_rf
01750 fcvtfxu( const float_rf *rs, status_field *sf )
01751 {
01752 uint32_t rssign;
01753 int32_t rsexp;
01754 uint64_t rsfrac;
01755 int32_t op_type;
01756 float_rf result_rf;
01757 uint64_t guard_bits;
01758 int32_t shift_count;
01759
01760 #ifdef FP_DEBUG
01761 fprintf(stderr, "fcvtfxu: rs.sign = %x\n", rs->sign);
01762 fprintf(stderr, " rs.exp = %x\n", rs->exp);
01763 fprintf(stderr, " rs.frac = %016llx\n", rs->frac);
01764 fprintf(stderr, " sf = %016llx\n\n", sf->i);
01765 #endif
01766
01767 if(fp_software_assistance_required(op_fcvt_fxu,rs,NULL,NULL,0)){
01768 sf->b.ISR_fpa = 1;
01769 return(Zero_rf);
01770 }
01771
01772 op_type = breakout_and_test( rs, &rssign, &rsexp, &rsfrac, sf );
01773
01774 #ifdef FP_DEBUG
01775 fprintf(stderr, "fcvtfxu: rssign = %x\n", rssign);
01776 fprintf(stderr, " rsexp = %x\n", rsexp);
01777 fprintf(stderr, " rsfrac = %016llx\n", rsfrac);
01778 fprintf(stderr, " sf = %016llx\n", sf->i);
01779 fprintf(stderr, " op_type = %x\n\n", op_type);
01780 #endif
01781
01782
01783
01784
01785
01786
01787 if ( op_type == NATVAL )
01788 {
01789 result_rf = NaTVal_rf;
01790
01791 return ( result_rf );
01792 }
01793 else if ( (op_type == SIGNALING_NAN) ||
01794 (op_type == QUIET_NAN) ||
01795 (rsexp >= 64 + EXP_BIAS)
01796 )
01797 {
01798 #ifdef FP_DEBUG
01799 fprintf(stderr, "fcvtfxu: setting invalid flag\n\n");
01800 #endif
01801 sf->b.invalid_flag = 1;
01802
01803 #ifdef FP_DEBUG
01804 fprintf(stderr, "fcvtfxu: sf = %016llx\n", sf->i);
01805 fprintf(stderr, " sf->b.invalid_flag = %llx\n", sf->b.invalid_flag);
01806 #endif
01807
01808 result_rf.sign = 0;
01809 result_rf.exp = 0x1003e;
01810 result_rf.frac = ULONGLONG_MAX;
01811
01812 return ( result_rf );
01813 }
01814
01815
01816
01817 if ( (rsexp == 0) && (rsfrac == 0ull) )
01818 {
01819
01820
01821 return ( Zero_rf );
01822 }
01823
01824
01825
01826 if ( rssign != 0 )
01827 {
01828 sf->b.invalid_flag = 1;
01829
01830 result_rf.sign = 0;
01831 result_rf.exp = 0x1003e;
01832 result_rf.frac = ULONGLONG_MAX;
01833
01834 return ( result_rf );
01835 }
01836
01837 rsexp -= EXP_BIAS;
01838
01839 if ( rsexp < -1 )
01840 {
01841 rsfrac = 0;
01842 guard_bits = STICKY_BIT;
01843 }
01844 else if ( rsexp == -1 )
01845 {
01846 guard_bits = rsfrac;
01847 rsfrac = 0;
01848 }
01849 else
01850 {
01851 guard_bits = 0;
01852 shift_count = 63 - rsexp;
01853
01854 if ( shift_count != 0 )
01855 {
01856 guard_bits = (rsfrac << (64 - shift_count));
01857 rsfrac >>= shift_count;
01858 }
01859 }
01860
01861 #ifdef FP_DEBUG
01862 fprintf(stderr, "fpcvtfxu calling round_l\n");
01863 fprintf(stderr, " rssign = %x\n", rssign);
01864 fprintf(stderr, " rsfrac = %016llx\n", rsfrac);
01865 fprintf(stderr, " guard_bits = %016llx\n\n", guard_bits);
01866 #endif
01867
01868 result_rf = round_l(rssign, rsfrac, guard_bits, sf);
01869
01870 #ifdef FP_DEBUG
01871 fprintf(stderr, "fpcvtfxu: returning\n");
01872 fprintf(stderr, " result_rf.sign = %x\n", result_rf.sign);
01873 fprintf(stderr, " result_rf.exp = %x\n", result_rf.exp);
01874 fprintf(stderr, " result_rf.frac = %016llx\n", result_rf.frac);
01875 #endif
01876
01877 return ( result_rf );
01878 }
01879
01880
01881
01882 float_rf
01883 fcvtfxutrunc( const float_rf *rs, status_field *sf )
01884 {
01885 uint32_t rssign;
01886 int32_t rsexp;
01887 uint64_t rsfrac;
01888 int32_t op_type;
01889 float_rf result_rf;
01890 uint64_t guard_bits;
01891 int32_t shift_count;
01892
01893 #ifdef FP_DEBUG
01894 fprintf(stderr, "fcvtfxutrunc: rs.sign = %x\n", rs->sign);
01895 fprintf(stderr, " rs.exp = %x\n", rs->exp);
01896 fprintf(stderr, " rs.frac = %016llx\n", rs->frac);
01897 fprintf(stderr, " sf = %016llx\n\n", sf->i);
01898 #endif
01899
01900 if(fp_software_assistance_required(op_fcvt_fxu,rs,NULL,NULL,0)){
01901 sf->b.ISR_fpa = 1;
01902 return(Zero_rf);
01903 }
01904
01905 op_type = breakout_and_test( rs, &rssign, &rsexp, &rsfrac, sf );
01906
01907 #ifdef FP_DEBUG
01908 fprintf(stderr, "fcvtfxutrunc: rssign = %x\n", rssign);
01909 fprintf(stderr, " rsexp = %x\n", rsexp);
01910 fprintf(stderr, " rsfrac = %016llx\n", rsfrac);
01911 fprintf(stderr, " sf = %016llx\n", sf->i);
01912 fprintf(stderr, " op_type = %x\n\n", op_type);
01913 #endif
01914
01915
01916
01917
01918
01919
01920 if ( op_type == NATVAL )
01921 {
01922 result_rf = NaTVal_rf;
01923
01924 return ( result_rf );
01925 }
01926 else if ( (op_type == SIGNALING_NAN) ||
01927 (op_type == QUIET_NAN) ||
01928 (rsexp >= 64 + EXP_BIAS)
01929 )
01930 {
01931 #ifdef FP_DEBUG
01932 fprintf(stderr, "fcvtfxuftrunc: setting invalid flag\n\n");
01933 #endif
01934 sf->b.invalid_flag = 1;
01935
01936 #ifdef FP_DEBUG
01937 fprintf(stderr, "fcvtfxutrunc: sf = %016llx\n", sf->i);
01938 fprintf(stderr, " sf->b.invalid_flag = %llx\n", sf->b.invalid_flag);
01939 #endif
01940
01941 result_rf.sign = 0;
01942 result_rf.exp = 0x1003e;
01943 result_rf.frac = ULONGLONG_MAX;
01944
01945 return ( result_rf );
01946 }
01947
01948
01949
01950 if ( (rsexp == 0) && (rsfrac == 0ull) )
01951 {
01952
01953
01954 return ( Zero_rf );
01955 }
01956
01957
01958
01959 if ( rssign != 0 )
01960 {
01961 sf->b.invalid_flag = 1;
01962
01963 result_rf.sign = 0;
01964 result_rf.exp = 0x1003e;
01965 result_rf.frac = ULONGLONG_MAX;
01966
01967 return ( result_rf );
01968 }
01969
01970 rsexp -= EXP_BIAS;
01971
01972 if ( rsexp <= -1 )
01973 {
01974 sf->b.inexact_flag = 1;
01975
01976 result_rf.sign = 0;
01977 result_rf.exp = 0;
01978 result_rf.frac = 0;
01979
01980 return ( result_rf );
01981 }
01982 else
01983 {
01984 guard_bits = 0;
01985 shift_count = 63 - rsexp;
01986
01987 if ( shift_count != 0 )
01988 {
01989 guard_bits = (rsfrac << (64 - shift_count));
01990 rsfrac >>= shift_count;
01991 }
01992
01993 result_rf.sign = 0;
01994 result_rf.exp = 0x1003e;
01995 result_rf.frac = rsfrac;
01996
01997 if ( guard_bits != 0 )
01998 sf->b.inexact_flag = 1;
01999
02000 #ifdef FP_DEBUG
02001 fprintf(stderr, "fpcvtfxutrunc: returning\n");
02002 fprintf(stderr, " result_rf.sign = %x\n", result_rf.sign);
02003 fprintf(stderr, " result_rf.exp = %x\n", result_rf.exp);
02004 fprintf(stderr, " result_rf.frac = %016llx\n", result_rf.frac);
02005 #endif
02006
02007 return ( result_rf );
02008 }
02009 }
02010
02011
02012
02013 float_rf
02014 fcvtxf( const float_rf *rs )
02015 {
02016 int32_t rsexp;
02017 uint64_t rsfrac;
02018 float_rf result_rf;
02019 int32_t shift_count;
02020
02021 #ifdef FP_DEBUG
02022 fprintf(stderr, "fcvtxf: rs.sign = %x\n", rs->sign);
02023 fprintf(stderr, " rs.exp = %x\n", rs->exp);
02024 fprintf(stderr, " rs.frac = %016llx\n", rs->frac);
02025 #endif
02026
02027 rsexp = rs->exp;
02028 rsfrac = rs->frac;
02029
02030
02031
02032 if ( (rsexp == EXP_NATVAL) && (rsfrac == (1ull << 61)) )
02033 {
02034 result_rf = *rs;
02035
02036 return ( result_rf );
02037 }
02038
02039
02040
02041 if ( rsfrac == 0ull )
02042 {
02043 result_rf.sign = 0;
02044 result_rf.exp = 0;
02045 result_rf.frac = 0ull;
02046
02047 return ( result_rf );
02048 }
02049
02050
02051
02052 if ( rsfrac == HIGH_BIT )
02053 {
02054 result_rf.sign = 1;
02055 result_rf.exp = 0x1003e;
02056 result_rf.frac = HIGH_BIT;
02057
02058 return ( result_rf );
02059 }
02060
02061 result_rf.sign = 0;
02062
02063 if ( rsfrac & HIGH_BIT )
02064 {
02065 result_rf.sign = 1;
02066
02067 rsfrac = ~rsfrac;
02068 rsfrac += 1;
02069 }
02070
02071 shift_count = renorm( &rsfrac );
02072
02073 rsexp -= shift_count;
02074
02075 result_rf.exp = rsexp;
02076 result_rf.frac = rsfrac;
02077
02078 return ( result_rf );
02079 }
02080
02081 int32_t
02082 fcmp_eq( const float_rf *rs, const float_rf *rt, status_field *sf )
02083 {
02084 uint32_t rssign;
02085 int32_t rsexp;
02086 uint64_t rsfrac;
02087 uint32_t rtsign;
02088 int32_t rtexp;
02089 uint64_t rtfrac;
02090 int32_t op_type;
02091 int32_t result;
02092
02093 if(fp_software_assistance_required(op_fcmp,rs,rt,NULL,0)){
02094 sf->b.ISR_fpa = 1;
02095 }
02096
02097 if ( op_type = breakout_and_test2(rs, &rssign, &rsexp, &rsfrac,
02098 rt, &rtsign, &rtexp, &rtfrac, sf)
02099 )
02100 {
02101 if ( op_type == NATVAL )
02102 {
02103 result = 0;
02104
02105 return ( result );
02106 }
02107 else if ( op_type == SIGNALING_NAN )
02108 {
02109 sf->b.invalid_flag = 1;
02110
02111 result = 0;
02112 }
02113 else
02114 {
02115 result = 0;
02116 }
02117 }
02118 else if ( (rsfrac == 0) && (rtfrac == 0) )
02119 {
02120
02121
02122 result = 1;
02123 }
02124 else if ( rssign != rtsign )
02125 {
02126 result = 0;
02127 }
02128 else
02129 {
02130 if ( (rsexp == rtexp) && (rsfrac == rtfrac) )
02131 result = 1;
02132 else
02133 result = 0;
02134 }
02135
02136 return ( result );
02137 }
02138
02139 int32_t
02140 fcmp_lt( const float_rf *rs, const float_rf *rt, status_field *sf )
02141 {
02142 uint32_t rssign;
02143 int32_t rsexp;
02144 uint64_t rsfrac;
02145 uint32_t rtsign;
02146 int32_t rtexp;
02147 uint64_t rtfrac;
02148 int32_t op_type;
02149 int32_t result;
02150
02151 if(fp_software_assistance_required(op_fcmp,rs,rt,NULL,0)){
02152 sf->b.ISR_fpa = 1;
02153 }
02154
02155 if ( op_type = breakout_and_test2(rs, &rssign, &rsexp, &rsfrac,
02156 rt, &rtsign, &rtexp, &rtfrac, sf)
02157 )
02158 {
02159 if ( op_type == NATVAL )
02160 {
02161 result = 0;
02162
02163 return ( result );
02164 }
02165 else
02166 {
02167 sf->b.invalid_flag = 1;
02168
02169 result = 0;
02170 }
02171 }
02172 else if ( (rsfrac == 0) && (rtfrac == 0) )
02173 {
02174
02175
02176 result = 0;
02177 }
02178 else if ( rsfrac == 0 )
02179 {
02180 if ( rtsign == 0 )
02181 result = 1;
02182 else
02183 result = 0;
02184 }
02185 else if ( rtfrac == 0 )
02186 {
02187 if ( rssign == 0 )
02188 result = 0;
02189 else
02190 result = 1;
02191 }
02192 else
02193 {
02194 if ( rssign != rtsign )
02195 result = rssign;
02196 else if ( rssign == 0 )
02197 {
02198 if ( rsexp < rtexp )
02199 result = 1;
02200 else if ( (rsexp == rtexp) && (rsfrac < rtfrac) )
02201 result = 1;
02202 else
02203 result = 0;
02204 }
02205 else
02206 {
02207 if ( (rsexp > rtexp) ||
02208 ((rsexp == rtexp) && (rsfrac > rtfrac))
02209 )
02210 result = 1;
02211 else
02212 result = 0;
02213 }
02214 }
02215
02216 return ( result );
02217 }
02218
02219 int32_t
02220 fcmp_le( const float_rf *rs, const float_rf *rt, status_field *sf )
02221 {
02222 uint32_t rssign;
02223 int32_t rsexp;
02224 uint64_t rsfrac;
02225 uint32_t rtsign;
02226 int32_t rtexp;
02227 uint64_t rtfrac;
02228 int32_t op_type;
02229 int32_t result;
02230
02231 if(fp_software_assistance_required(op_fcmp,rs,rt,NULL,0)){
02232 sf->b.ISR_fpa = 1;
02233 }
02234
02235 if ( op_type = breakout_and_test2(rs, &rssign, &rsexp, &rsfrac,
02236 rt, &rtsign, &rtexp, &rtfrac, sf)
02237 )
02238 {
02239 #ifdef FP_DEBUG
02240 fprintf(stderr, "fcmp_le: op_type = %d\n\n", op_type);
02241 #endif
02242
02243 if ( op_type == NATVAL )
02244 {
02245 result = 0;
02246
02247 return ( result );
02248 }
02249 else
02250 {
02251 sf->b.invalid_flag = 1;
02252
02253 result = 0;
02254
02255 return ( result );
02256 }
02257 }
02258
02259 #ifdef FP_DEBUG
02260 fprintf(stderr, "fcmp_le: rssign = %x\n", rssign);
02261 fprintf(stderr, " rsexp = %x\n", rsexp);
02262 fprintf(stderr, " rsfrac = %016llx\n", rsfrac);
02263 fprintf(stderr, " rtsign = %x\n", rtsign);
02264 fprintf(stderr, " rtexp = %x\n", rtexp);
02265 fprintf(stderr, " rtfrac = %016llx\n", rtfrac);
02266 fprintf(stderr, " sf = %016llx\n\n", sf->i);
02267 fprintf(stderr, " op_type = %d\n\n", op_type);
02268 #endif
02269
02270 if ( (rsfrac == 0) && (rtfrac == 0) )
02271 {
02272 #ifdef FP_DEBUG
02273 fprintf(stderr, "fcmp_le: rs and rt both zero; returning 1\n\n");
02274 #endif
02275
02276
02277 result = 1;
02278
02279 return ( result );
02280 }
02281
02282 if ( rssign < rtsign )
02283 {
02284 result = 0;
02285 }
02286 else if ( rssign > rtsign )
02287 {
02288 result = 1;
02289 }
02290 else if ( rssign == 0 )
02291 {
02292
02293 if ( (rsexp < rtexp) ||
02294 ((rsexp == rtexp) && (rsfrac <= rtfrac))
02295 )
02296 result = 1;
02297 else
02298 result = 0;
02299 }
02300 else
02301 {
02302 if ( (rsexp > rtexp) ||
02303 ((rsexp == rtexp) && (rsfrac >= rtfrac))
02304 )
02305 result = 1;
02306 else
02307 result = 0;
02308 }
02309
02310 return ( result);
02311 }
02312
02313 int32_t
02314 fcmp_unord( const float_rf *rs, const float_rf *rt, status_field *sf )
02315 {
02316 uint32_t rssign;
02317 int32_t rsexp;
02318 uint64_t rsfrac;
02319 uint32_t rtsign;
02320 int32_t rtexp;
02321 uint64_t rtfrac;
02322 int32_t op_type;
02323 int32_t result;
02324
02325 if(fp_software_assistance_required(op_fcmp,rs,rt,NULL,0)){
02326 sf->b.ISR_fpa = 1;
02327 }
02328
02329 if ( op_type = breakout_and_test2(rs, &rssign, &rsexp, &rsfrac,
02330 rt, &rtsign, &rtexp, &rtfrac, sf)
02331 )
02332 {
02333 if ( op_type == NATVAL )
02334 {
02335 result = 0;
02336
02337 return ( result );
02338 }
02339 else if ( op_type == SIGNALING_NAN )
02340 {
02341 sf->b.invalid_flag = 1;
02342
02343 result = 1;
02344 }
02345 else
02346 {
02347 result = 1;
02348 }
02349 }
02350 else
02351 {
02352 result = 0;
02353 }
02354
02355 return ( result );
02356 }
02357
02358
02359
02360 float_rf
02361 frcpa( int32_t *pr, const float_rf *rs, const float_rf *rt, status_field *sf )
02362 {
02363 uint32_t rssign;
02364 int32_t rsexp;
02365 uint64_t rsfrac;
02366 uint32_t rtsign;
02367 int32_t rtexp;
02368 uint64_t rtfrac;
02369 int32_t op_type;
02370 int32_t precision;
02371 int32_t wre;
02372 int32_t exp_min;
02373 int32_t exp_max;
02374 int32_t index;
02375 float_rf result_rf;
02376
02377 #ifdef FP_DEBUG
02378 fprintf(stderr, "frcpa: rs.sign = %x\n", (*rs).sign);
02379 fprintf(stderr, " rs.exp = %x\n", (*rs).exp);
02380 fprintf(stderr, " rs.frac = %016llx\n", (*rs).frac);
02381 fprintf(stderr, " rt.sign = %x\n", (*rt).sign);
02382 fprintf(stderr, " rt.exp = %x\n", (*rt).exp);
02383 fprintf(stderr, " rt.frac = %016llx\n", (*rt).frac);
02384 fprintf(stderr, " sf = %016llx\n\n", sf->i);
02385 #endif
02386
02387 if(fp_software_assistance_required(op_frcpa,rs,rt,NULL,0)){
02388 sf->b.ISR_fpa = 1;
02389 return(Zero_rf);
02390 }
02391
02392 if ( op_type = breakout_and_test2(rs, &rssign, &rsexp, &rsfrac,
02393 rt, &rtsign, &rtexp, &rtfrac, sf)
02394 )
02395 {
02396 if ( op_type == NATVAL )
02397 {
02398 result_rf = NaTVal_rf;
02399 *pr = 0;
02400
02401 return ( result_rf );
02402 }
02403 else if ( op_type == SIGNALING_NAN )
02404 {
02405 sf->b.invalid_flag = 1;
02406
02407 result_rf = Quiet_nan_rf;
02408 *pr = 0;
02409
02410 return ( result_rf );
02411 }
02412 else
02413 {
02414
02415
02416 if ( (rsexp == EXP_NAN) && (rsfrac > (1ull << 63)) )
02417 {
02418 result_rf = *rs;
02419 *pr = 0;
02420
02421
02422
02423
02424 sf->b.invalid_flag = 1;
02425 return ( result_rf );
02426 }
02427 else if ( (rtexp == EXP_NAN) && (rtfrac > (1ull << 63)) )
02428 {
02429 result_rf = *rt;
02430 *pr = 0;
02431
02432
02433
02434
02435 sf->b.invalid_flag = 1;
02436
02437 return ( result_rf );
02438 }
02439 }
02440 }
02441
02442 if ( (rsexp == EXP_INF) && (rtexp == EXP_INF) )
02443 {
02444 sf->b.invalid_flag = 1;
02445
02446 result_rf = Quiet_nan_rf;
02447 *pr = 0;
02448
02449 return ( result_rf );
02450 }
02451 else if ( rtexp == EXP_INF )
02452 {
02453 result_rf.sign = (rssign ^ rtsign);
02454 result_rf.exp = 0;
02455 result_rf.frac = 0;
02456 *pr = 0;
02457
02458 return ( result_rf );
02459 }
02460 else if ( rsexp == EXP_INF )
02461 {
02462 result_rf.sign = (rssign ^ rtsign);
02463 result_rf.exp = EXP_INF;
02464 result_rf.frac = HIGH_BIT;
02465 *pr = 0;
02466
02467 return ( result_rf );
02468 }
02469 else if ( (rsexp == 0) && (rtexp == 0) )
02470 {
02471 sf->b.invalid_flag = 1;
02472
02473 result_rf = Quiet_nan_rf;
02474 *pr = 0;
02475
02476 return ( result_rf );
02477 }
02478 else if ( rsexp == 0 )
02479 {
02480 result_rf.sign = (rssign ^ rtsign);
02481 result_rf.exp = 0;
02482 result_rf.frac = 0;
02483 *pr = 0;
02484
02485 return ( result_rf );
02486 }
02487 else if ( rtexp == 0 )
02488 {
02489 sf->b.zero_div_flag = 1;
02490
02491 result_rf = Quiet_nan_rf;
02492 *pr = 0;
02493
02494 return ( result_rf );
02495 }
02496
02497 precision = sf->b.pc;
02498
02499 wre = sf->b.wre;
02500
02501 if ( precision == SNGL )
02502 {
02503 exp_min = (wre) ? WEXP_MIN : SEXP_MIN;
02504 exp_max = (wre) ? WEXP_MAX : SEXP_MAX;
02505 }
02506 else if ( precision == DBL )
02507 {
02508 exp_min = (wre) ? WEXP_MIN : DEXP_MIN;
02509 exp_max = (wre) ? WEXP_MAX : DEXP_MAX;
02510 }
02511 else
02512 {
02513 exp_min = (wre) ? WEXP_MIN : DEEXP_MIN;
02514 exp_max = (wre) ? WEXP_MAX : DEEXP_MAX;
02515 }
02516
02517
02518
02519
02520
02521
02522
02523
02524
02525
02526
02527
02528 if ( (rsexp - rtexp - 1 <= exp_min + 2) || (rsexp - rtexp + 1 >= exp_max - 2) )
02529 {
02530 #ifdef FP_DEBUG
02531 fprintf(stderr, "frcpa: pt. 1\n");
02532 #endif
02533 *pr = 0;
02534 result_rf = soft_div( rssign, rsexp, rsfrac, rtsign, rtexp, rtfrac, sf );
02535 return ( result_rf );
02536 }
02537
02538
02539
02540 if ( (-rtexp + EXP_BIAS - 1 <= exp_min + 2) || (-rtexp + EXP_BIAS >= exp_max - 2) )
02541 {
02542 #ifdef FP_DEBUG
02543 fprintf(stderr, "frcpa: pt. 2\n");
02544 #endif
02545 *pr = 0;
02546 result_rf = soft_div( rssign, rsexp, rsfrac, rtsign, rtexp, rtfrac, sf );
02547 return ( result_rf );
02548 }
02549
02550
02551
02552 if ( (-rtexp + EXP_BIAS - 1 ) <= exp_min + 2 )
02553 {
02554 #ifdef FP_DEBUG
02555 fprintf(stderr, "frcpa: pt. 3\n");
02556 #endif
02557 *pr = 0;
02558 result_rf = soft_div( rssign, rsexp, rsfrac, rtsign, rtexp, rtfrac, sf );
02559 return ( result_rf );
02560 }
02561
02562
02563
02564 if ( (rsexp - EXP_BIAS) <= exp_min + 2 )
02565 {
02566 #ifdef FP_DEBUG
02567 fprintf(stderr, "frcpa: pt. 4\n");
02568 #endif
02569 *pr = 0;
02570 result_rf = soft_div( rssign, rsexp, rsfrac, rtsign, rtexp, rtfrac, sf );
02571 return ( result_rf );
02572 }
02573
02574
02575 if ( (rsexp - rtexp - 1) <= exp_min + 2 )
02576 {
02577 #ifdef FP_DEBUG
02578 fprintf(stderr, "frcpa: pt. 5\n");
02579 #endif
02580 *pr = 0;
02581 result_rf = soft_div( rssign, rsexp, rsfrac, rtsign, rtexp, rtfrac, sf );
02582 return ( result_rf );
02583 }
02584
02585
02586
02587 result_rf.sign = rtsign;
02588 result_rf.exp = 0x1ffff - 2 - rtexp;
02589 index = ((rtfrac >> 55) & 0xff);
02590
02591 result_rf.frac = (HIGH_BIT | ((uint64_t)recip_table[index] << 53));
02592
02593 *pr = 1;
02594
02595 return ( result_rf );
02596 }
02597
02598 float_rf
02599 soft_div( uint32_t rssign, int32_t rsexp, uint64_t rsfrac,
02600 uint32_t rtsign, int32_t rtexp, uint64_t rtfrac,
02601 status_field *sf )
02602 {
02603 int32_t precision;
02604 int32_t mantwidth;
02605 uint64_t carry;
02606 float_rf result_rf;
02607 int32_t shift_count;
02608 int32_t i;
02609 uint32_t qsign;
02610 int32_t qexp;
02611 uint64_t qfrac;
02612 uint64_t guard_bits;
02613
02614 #ifdef FP_DEBUG
02615 fprintf(stderr, "soft_div: rssign = %x\n", rssign);
02616 fprintf(stderr, " rsexp = %x\n", rsexp);
02617 fprintf(stderr, " rsfrac = %016llx\n", rsfrac);
02618 fprintf(stderr, " rtsign = %x\n", rtsign);
02619 fprintf(stderr, " rtexp = %x\n", rtexp);
02620 fprintf(stderr, " rtfrac = %016llx\n\n", rtfrac);
02621 #endif
02622
02623 qsign = (rssign ^ rtsign);
02624
02625 qexp = rsexp - rtexp;
02626
02627 if ( rsfrac < rtfrac )
02628 {
02629
02630
02631
02632
02633 carry = 1;
02634 rsfrac <<= 1;
02635 qexp--;
02636 }
02637
02638 precision = sf->b.pc;
02639
02640 if ( precision == SNGL )
02641 mantwidth = 24;
02642 else if ( precision == DBL )
02643 mantwidth = 53;
02644 else
02645 mantwidth = 64;
02646
02647 #ifdef FP_DEBUG
02648 fprintf(stderr, "soft_div: mantwidth = %d\n\n", mantwidth);
02649 #endif
02650
02651
02652
02653 qfrac = 0ull;
02654
02655 for ( i=0; i<mantwidth; i++ )
02656 {
02657 qfrac <<= 1;
02658
02659 if ( carry == 1 )
02660 {
02661 qfrac |= 1ull;
02662 rsfrac -= rtfrac;
02663 carry = 0;
02664 }
02665 else if ( rtfrac <= rsfrac )
02666 {
02667 qfrac |= 1ull;
02668 rsfrac -= rtfrac;
02669 }
02670
02671 if ( rsfrac & HIGH_BIT )
02672 carry = 1;
02673
02674 rsfrac <<= 1;
02675
02676 #ifdef FP_DEBUG
02677 fprintf(stderr, "soft_div: i = %d\n", i);
02678 fprintf(stderr, " qfrac = %016llx\n", qfrac);
02679 fprintf(stderr, " rsfrac = %016llx\n\n", rsfrac);
02680 #endif
02681 }
02682
02683 #ifdef FP_DEBUG
02684 fprintf(stderr, "soft_div: after loop qfrac = %016llx\n\n", qfrac);
02685 #endif
02686
02687 guard_bits = 0ull;
02688
02689 if ( (carry == 1) || (rtfrac <= rsfrac) )
02690 {
02691 guard_bits = GUARD_BIT;
02692 rsfrac -= rtfrac;
02693 }
02694
02695 if ( rsfrac != 0ull )
02696 guard_bits |= STICKY_BIT;
02697
02698 shift_count = renorm( &qfrac );
02699
02700 if ( shift_count != 0 )
02701 {
02702 qfrac |= (guard_bits >> (64 - shift_count));
02703 guard_bits <<= shift_count;
02704 }
02705
02706 #ifdef FP_DEBUG
02707 fprintf(stderr, "soft_div: qsign = %x\n", qsign);
02708 fprintf(stderr, " qexp = %x\n", qexp);
02709 fprintf(stderr, " qfrac = %016llx\n", qfrac);
02710 fprintf(stderr, " guard_bits = %016llx\n", guard_bits);
02711 #endif
02712
02713 result_rf = round(qsign, qexp, qfrac, guard_bits, sf);
02714
02715 return ( result_rf );
02716 }
02717
02718
02719
02720 float_rf
02721 frsqrta( int32_t *pr, const float_rf *rs, status_field *sf )
02722 {
02723 uint32_t rssign;
02724 int32_t rsexp;
02725 uint64_t rsfrac;
02726 int32_t op_type;
02727 int32_t precision;
02728 int32_t wre;
02729 int32_t exp_min;
02730 int32_t exp_max;
02731 float_rf result_rf;
02732
02733 if(fp_software_assistance_required(op_frsqrta,rs,NULL,NULL,0)){
02734 sf->b.ISR_fpa = 1;
02735 return(Zero_rf);
02736 }
02737
02738 if ( op_type = breakout_and_test(rs, &rssign, &rsexp, &rsfrac, sf)
02739 )
02740 {
02741 if ( op_type == NATVAL )
02742 {
02743 result_rf = NaTVal_rf;
02744 *pr = 0;
02745
02746 return ( result_rf );
02747 }
02748 else if ( op_type == SIGNALING_NAN )
02749 {
02750 sf->b.invalid_flag = 1;
02751
02752 result_rf = Quiet_nan_rf;
02753 *pr = 0;
02754
02755 return ( result_rf );
02756 }
02757 else
02758 {
02759
02760
02761
02762
02763
02764 sf->b.invalid_flag = 1;
02765
02766 result_rf = *rs;
02767 *pr = 0;
02768
02769 return ( result_rf );
02770 }
02771 }
02772
02773 if ( rsexp == EXP_INF )
02774 {
02775 if ( rssign == 0 )
02776 {
02777 result_rf = *rs;
02778 *pr = 0;
02779
02780 return ( result_rf );
02781 }
02782
02783 sf->b.invalid_flag = 1;
02784
02785 result_rf = Quiet_nan_rf;
02786 *pr = 0;
02787
02788 return ( result_rf );
02789 }
02790 else if ( rsexp == 0 )
02791 {
02792 result_rf = *rs;
02793 *pr = 0;
02794
02795 return ( result_rf );
02796 }
02797 else if ( rssign == 1 )
02798 {
02799 sf->b.invalid_flag = 1;
02800
02801 result_rf = Quiet_nan_rf;
02802 *pr = 0;
02803
02804 return ( result_rf );
02805 }
02806
02807 precision = sf->b.pc;
02808
02809 wre = sf->b.wre;
02810
02811 if ( precision == SNGL )
02812 {
02813 exp_min = (wre) ? WEXP_MIN : SEXP_MIN - 23;
02814 exp_max = (wre) ? WEXP_MAX : SEXP_MAX;
02815 }
02816 else if ( precision == DBL )
02817 {
02818 exp_min = (wre) ? WEXP_MIN : DEXP_MIN - 52;
02819 exp_max = (wre) ? WEXP_MAX : DEXP_MAX;
02820 }
02821 else
02822 {
02823 exp_min = (wre) ? WEXP_MIN : DEEXP_MIN - 63;
02824 exp_max = (wre) ? WEXP_MAX : DEEXP_MAX;
02825 }
02826
02827 if ( (rsexp - EXP_BIAS) > exp_max )
02828 {
02829 if ( rssign == 0 )
02830 {
02831 result_rf = Infinity_rf;
02832 *pr = 0;
02833
02834 return ( result_rf );
02835 }
02836
02837 sf->b.invalid_flag = 1;
02838
02839 result_rf = Quiet_nan_rf;
02840 *pr = 0;
02841
02842 return ( result_rf );
02843 }
02844 else if ( (rsexp - EXP_BIAS) < exp_min )
02845 {
02846 result_rf.sign = rssign;
02847 result_rf.exp = 0;
02848 result_rf.frac = 0;
02849
02850 return ( result_rf );
02851 }
02852
02853 result_rf = recip_sqrt(rssign, rsexp, rsfrac);
02854
02855 if ( (result_rf.exp == 0) && (result_rf.frac == 0) )
02856 *pr = 0;
02857 else if ( (result_rf.exp == EXP_INF) && (result_rf.frac == HIGH_BIT) )
02858 *pr = 0;
02859
02860 *pr = 1;
02861
02862 return ( result_rf );
02863
02864 }
02865
02866 float_rf
02867 recip_sqrt( uint32_t rssign, int32_t rsexp, uint64_t rsfrac )
02868 {
02869 float_rf result_rf;
02870 int32_t index;
02871
02872 result_rf.sign = rssign;
02873 result_rf.exp = 0xfffe - ((rsexp - EXP_BIAS) >> 1);
02874 index = ((rsexp & 1) << 7) | ((rsfrac >> 56) & 0x7f);
02875 result_rf.frac = HIGH_BIT | ((uint64_t)recip_sqrt_table[index] << 53);
02876
02877 return ( result_rf );
02878 }
02879
02880 float_rf
02881 madd( uint32_t rssign, int32_t rsexp, uint64_t rsfrac,
02882 uint32_t rtsign, int32_t rtexp, uint64_t rtfrac,
02883 uint32_t rrsign, int32_t rrexp, uint64_t rrfrac,
02884 status_field *sf )
02885 {
02886 float_rf result;
02887 int32_t shift_count;
02888 uint32_t prdsign;
02889 int32_t prdexp;
02890 uint64_t prdfrac[2];
02891 uint32_t sumsign;
02892 int32_t sumexp;
02893 uint64_t guard_bits;
02894 uint32_t carry;
02895 uint32_t carry_in, carry_out;
02896 uint64_t sfrac[4], tfrac[4];
02897 uint32_t neg;
02898
02899 #ifdef FP_DEBUG
02900 fprintf(stderr, "madd: rssign = %x\nrsexp = %x\nrsfrac = %016llx\n",
02901 rssign, rsexp, rsfrac);
02902 fprintf(stderr, " rtsign = %x\nrtexp = %x\nrtfrac = %016llx\n",
02903 rtsign, rtexp, rtfrac);
02904 fprintf(stderr, " rrsign = %x\nrrexp = %x\nrrfrac = %016llx\n",
02905 rrsign, rrexp, rrfrac);
02906 #endif
02907
02908 if ( (rsexp == EXP_INF) && (rtexp == EXP_INF) && (rrexp == EXP_INF) )
02909 {
02910
02911
02912 if ( (rssign ^ rtsign) == rrsign )
02913 {
02914 result.sign = rrsign;
02915 result.exp = rrexp;
02916
02917 result.frac = HIGH_BIT;
02918
02919 return ( result );
02920 }
02921
02922 sf->b.invalid_flag = 1;
02923
02924
02925
02926 result = Quiet_nan_rf;
02927
02928 return ( result );
02929 }
02930
02931 if ( (rsexp == EXP_INF) && (rtexp == EXP_INF) )
02932 {
02933
02934
02935 result.sign = (rssign ^ rtsign);
02936 result.exp = rsexp;
02937
02938 result.frac = HIGH_BIT;
02939
02940 return ( result );
02941 }
02942
02943
02944
02945 if ( (rsexp != EXP_INF) && (rtexp == EXP_INF) )
02946 {
02947 rssign ^= rtsign;
02948 rtsign ^= rssign;
02949 rssign ^= rtsign;
02950
02951 rsexp ^= rtexp;
02952 rtexp ^= rsexp;
02953 rsexp ^= rtexp;
02954
02955 rsfrac ^= rtfrac;
02956 rtfrac ^= rsfrac;
02957 rsfrac ^= rtfrac;
02958 }
02959
02960 if ( (rsexp == EXP_INF) && (rrexp == EXP_INF) )
02961 {
02962
02963
02964 if ( ((rtexp == 0) && (rtfrac == 0ll)) ||
02965 ((rssign ^ rtsign) != rrsign)
02966 )
02967 {
02968 sf->b.invalid_flag = 1;
02969
02970
02971
02972 result = Quiet_nan_rf;
02973
02974 return ( result );
02975 }
02976 else
02977 {
02978
02979
02980 result.sign = rrsign;
02981 result.exp = rrexp;
02982
02983 result.frac = rrfrac;
02984
02985 return ( result );
02986 }
02987 }
02988
02989 if ( rsexp == EXP_INF )
02990 {
02991 if ( (rtexp == 0) && (rtfrac == 0ll) )
02992 {
02993 sf->b.invalid_flag = 1;
02994
02995
02996
02997 result = Quiet_nan_rf;
02998
02999 return ( result );
03000 }
03001
03002 result.sign = (rssign ^ rtsign);
03003 result.exp = rsexp;
03004
03005 result.frac = rsfrac;
03006
03007 return ( result );
03008 }
03009
03010 if ( rrexp == EXP_INF )
03011 {
03012
03013
03014 result.sign = rrsign;
03015 result.exp = rrexp;
03016
03017 result.frac = rrfrac;
03018
03019 return ( result );
03020 }
03021
03022 if ( ((rsexp == 0) && (rsfrac == 0ull)) ||
03023 ((rtexp == 0) && (rtfrac == 0ull))
03024 )
03025 {
03026
03027
03028 if ( (rrexp == 0) && (rrfrac == 0ull) )
03029 {
03030
03031
03032 if ( sf->b.rc == FP_RM )
03033 {
03034
03035
03036 result.sign = ((rssign ^ rtsign) | rrsign);
03037 result.exp = 0;
03038 result.frac = 0;
03039 }
03040 else
03041 {
03042 result.sign = ((rssign ^ rtsign) & rrsign);
03043 result.exp = 0;
03044 result.frac = 0;
03045 }
03046
03047 return ( result );
03048 }
03049 else
03050 {
03051
03052 guard_bits = 0x0;
03053
03054
03055 rrexp -= EXP_BIAS;
03056 result = round(rrsign,rrexp,rrfrac,guard_bits,sf);
03057
03058
03059
03060
03061
03062 return ( result );
03063 }
03064 }
03065
03066
03067
03068 rsexp -= EXP_BIAS;
03069 rtexp -= EXP_BIAS;
03070
03071 prdsign = (rssign ^ rtsign);
03072 prdexp = rsexp + rtexp;
03073 prdfrac[0] = mul64(rsfrac, rtfrac, &prdfrac[1]);
03074
03075
03076
03077
03078
03079 shift_count = renorm( &prdfrac[0] );
03080
03081
03082
03083
03084 if ( shift_count == 0 )
03085 {
03086
03087
03088
03089
03090 prdexp++;
03091 }
03092 else
03093 {
03094 prdfrac[0] |= (prdfrac[1] >> (64 - shift_count));
03095 prdfrac[1] <<= shift_count;
03096 }
03097
03098 #ifdef FP_DEBUG
03099 fprintf(stderr, "madd: prdsign = %x\n", prdsign);
03100 fprintf(stderr, " prdexp = %x\n", prdexp);
03101 fprintf(stderr, " prdfrac[0] = %016llx\n", prdfrac[0]);
03102 fprintf(stderr, " prdfrac[1] = %016llx\n", prdfrac[1]);
03103 #endif
03104
03105 if ( (rrexp == 0) && (rrfrac == 0ull) )
03106 {
03107
03108
03109 result = round(prdsign, prdexp, prdfrac[0], prdfrac[1], sf);
03110
03111 return ( result );
03112 }
03113
03114 rrexp -= EXP_BIAS;
03115
03116 if ( (prdsign != rrsign) && (prdexp == rrexp) &&
03117 (prdfrac[0] == rrfrac) && (prdfrac[1] == 0ull)
03118 )
03119 {
03120
03121
03122 if ( sf->b.rc == FP_RM )
03123 {
03124
03125
03126 result.sign = (prdsign | rrsign);
03127 result.exp = 0;
03128 result.frac = 0;
03129 }
03130 else
03131 {
03132 result.sign = (prdsign & rrsign);
03133 result.exp = 0;
03134 result.frac = 0;
03135 }
03136
03137 return ( result );
03138 }
03139
03140
03141
03142
03143
03144 if ( rrexp < prdexp - 130 )
03145 rrexp = prdexp - 130;
03146
03147 if ( prdexp < rrexp - 66 )
03148 prdexp = rrexp - 66;
03149
03150
03151
03152 if ( (prdexp > rrexp) ||
03153 ((prdexp == rrexp) && (prdfrac[0] >= rrfrac))
03154 )
03155 {
03156 sfrac[0] = prdfrac[0];
03157 sfrac[1] = prdfrac[1];
03158 sfrac[2] = 0ull;
03159 sfrac[3] = 0ull;
03160
03161 sumsign = prdsign;
03162 sumexp = prdexp;
03163
03164 tfrac[0] = rrfrac;
03165 tfrac[1] = 0ull;
03166 tfrac[2] = 0ull;
03167 tfrac[3] = 0ull;
03168
03169 shift_count = prdexp - rrexp;
03170 }
03171 else
03172 {
03173 sfrac[0] = rrfrac;
03174 sfrac[1] = 0ull;
03175 sfrac[2] = 0ull;
03176 sfrac[3] = 0ull;
03177
03178 sumsign = rrsign;
03179 sumexp = rrexp;
03180
03181 tfrac[0] = prdfrac[0];
03182 tfrac[1] = prdfrac[1];
03183 tfrac[2] = 0ull;
03184 tfrac[3] = 0ull;
03185
03186 shift_count = rrexp - prdexp;
03187 }
03188
03189 #ifdef FP_DEBUG
03190 fprintf(stderr, "sumsign = %x\n", sumsign);
03191 fprintf(stderr, "sumexp = %x\n", sumexp);
03192 fprintf(stderr, "sfrac[0] = %016llx\n", sfrac[0]);
03193 fprintf(stderr, "sfrac[1] = %016llx\n", sfrac[1]);
03194 fprintf(stderr, "sfrac[2] = %016llx\n", sfrac[2]);
03195 fprintf(stderr, "sfrac[3] = %016llx\n", sfrac[3]);
03196 fprintf(stderr, "tfrac[0] = %016llx\n", tfrac[0]);
03197 fprintf(stderr, "tfrac[1] = %016llx\n", tfrac[1]);
03198 fprintf(stderr, "tfrac[2] = %016llx\n", tfrac[2]);
03199 fprintf(stderr, "tfrac[3] = %016llx\n\n", tfrac[3]);
03200 #endif
03201
03202
03203
03204
03205
03206
03207 if ( shift_count >= 128 )
03208 {
03209 tfrac[3] = tfrac[1];
03210 tfrac[2] = tfrac[0];
03211 tfrac[1] = 0ull;
03212 tfrac[0] = 0ull;
03213
03214 shift_count -= 128;
03215 }
03216 else if ( shift_count >= 64 )
03217 {
03218 tfrac[2] = tfrac[1];
03219 tfrac[1] = tfrac[0];
03220 tfrac[0] = 0ull;
03221
03222 shift_count -= 64;
03223 }
03224
03225 if ( shift_count > 0 )
03226 {
03227 tfrac[3] >>= shift_count;
03228 tfrac[3] |= (tfrac[2] << (64 - shift_count));
03229 tfrac[2] >>= shift_count;
03230 tfrac[2] |= (tfrac[1] << (64 - shift_count));
03231 tfrac[1] >>= shift_count;
03232 tfrac[1] |= (tfrac[0] << (64 - shift_count));
03233 tfrac[0] >>= shift_count;
03234 }
03235
03236 #ifdef FP_DEBUG
03237 fprintf(stderr, "sfrac[0] = %016llx\n", sfrac[0]);
03238 fprintf(stderr, "sfrac[1] = %016llx\n", sfrac[1]);
03239 fprintf(stderr, "sfrac[2] = %016llx\n", sfrac[2]);
03240 fprintf(stderr, "sfrac[3] = %016llx\n", sfrac[3]);
03241 fprintf(stderr, "tfrac[0] = %016llx\n", tfrac[0]);
03242 fprintf(stderr, "tfrac[1] = %016llx\n", tfrac[1]);
03243 fprintf(stderr, "tfrac[2] = %016llx\n", tfrac[2]);
03244 fprintf(stderr, "tfrac[3] = %016llx\n\n", tfrac[3]);
03245 #endif
03246
03247 neg = 0;
03248
03249 if ( prdsign != rrsign )
03250 {
03251
03252
03253 neg = 1;
03254
03255 carry = 0;
03256
03257 if ( (tfrac[1] == 0ull) && (tfrac[2] == 0ull) && (tfrac[3] == 0ull) )
03258 carry = 1;
03259
03260 tfrac[0] = ~tfrac[0] + carry;
03261
03262 carry = 0;
03263
03264 if ( (tfrac[2] == 0ull) && (tfrac[3] == 0ull) )
03265 carry = 1;
03266
03267 tfrac[1] = ~tfrac[1] + carry;
03268
03269 carry = 0;
03270
03271 if ( tfrac[3] == 0ull )
03272 carry = 1;
03273
03274 tfrac[2] = ~tfrac[2] + carry;
03275
03276 tfrac[3] = ~tfrac[3] + 1ull;
03277 }
03278
03279 #ifdef FP_DEBUG
03280 fprintf(stderr, "sfrac[0] = %016llx\n", sfrac[0]);
03281 fprintf(stderr, "sfrac[1] = %016llx\n", sfrac[1]);
03282 fprintf(stderr, "sfrac[2] = %016llx\n", sfrac[2]);
03283 fprintf(stderr, "sfrac[3] = %016llx\n", sfrac[3]);
03284 fprintf(stderr, "tfrac[0] = %016llx\n", tfrac[0]);
03285 fprintf(stderr, "tfrac[1] = %016llx\n", tfrac[1]);
03286 fprintf(stderr, "tfrac[2] = %016llx\n", tfrac[2]);
03287 fprintf(stderr, "tfrac[3] = %016llx\n\n", tfrac[3]);
03288 #endif
03289
03290
03291
03292 carry_out = 0;
03293
03294 if ( sfrac[3] > ~tfrac[3] )
03295 carry_out = 1;
03296
03297 tfrac[3] += sfrac[3];
03298
03299 carry_in = carry_out;
03300
03301 carry_out = 0;
03302
03303 if ( (tfrac[2] == ULONGLONG_MAX) && (carry_in != 0ull) )
03304 carry_out = 1;
03305
03306 tfrac[2] += carry_in;
03307
03308 if ( sfrac[2] > ~tfrac[2] )
03309 carry_out += 1;
03310
03311 tfrac[2] += sfrac[2];
03312
03313 carry_in = carry_out;
03314
03315 carry_out = 0;
03316
03317 if ( (tfrac[1] == ULONGLONG_MAX) && (carry_in != 0ull) )
03318 carry_out = 1;
03319
03320 tfrac[1] += carry_in;
03321
03322 if ( sfrac[1] > ~tfrac[1] )
03323 carry_out += 1;
03324
03325 tfrac[1] += sfrac[1];
03326
03327 carry_in = carry_out;
03328
03329 carry_out = 0;
03330
03331 if ( (tfrac[0] == ULONGLONG_MAX) && (carry_in != 0ull) )
03332 carry_out = 1;
03333
03334 tfrac[0] += carry_in;
03335
03336 if ( sfrac[0] > ~tfrac[0] )
03337 carry_out += 1;
03338
03339 tfrac[0] += sfrac[0];
03340
03341 #ifdef FP_DEBUG
03342 fprintf(stderr, "neg = %x\n", neg);
03343 fprintf(stderr, "carry_out = %x\n\n", carry_out);
03344 #endif
03345
03346 carry_out -= neg;
03347
03348 if ( carry_out == 1 )
03349 {
03350 tfrac[3] >>= 1;
03351 tfrac[3] |= (tfrac[2] << 63);
03352 tfrac[2] >>= 1;
03353 tfrac[2] |= (tfrac[1] << 63);
03354 tfrac[1] >>= 1;
03355 tfrac[1] |= (tfrac[0] << 63);
03356 tfrac[0] >>= 1;
03357 tfrac[0] |= (1ull << 63);
03358
03359 sumexp++;
03360 }
03361
03362 #ifdef FP_DEBUG
03363 fprintf(stderr, "sumexp = %x\n", sumexp);
03364 fprintf(stderr, "sfrac[0] = %016llx\n", sfrac[0]);
03365 fprintf(stderr, "sfrac[1] = %016llx\n", sfrac[1]);
03366 fprintf(stderr, "sfrac[2] = %016llx\n", sfrac[2]);
03367 fprintf(stderr, "sfrac[3] = %016llx\n", sfrac[3]);
03368 fprintf(stderr, "tfrac[0] = %016llx\n", tfrac[0]);
03369 fprintf(stderr, "tfrac[1] = %016llx\n", tfrac[1]);
03370 fprintf(stderr, "tfrac[2] = %016llx\n", tfrac[2]);
03371 fprintf(stderr, "tfrac[3] = %016llx\n\n", tfrac[3]);
03372 #endif
03373
03374
03375
03376 if ( tfrac[0] == 0 )
03377 {
03378 tfrac[0] = tfrac[1];
03379 tfrac[1] = tfrac[2];
03380 tfrac[2] = tfrac[3];
03381 tfrac[3] = 0;
03382
03383 sumexp -= 64;
03384 }
03385
03386 shift_count = renorm( &tfrac[0] );
03387
03388 if ( shift_count != 0 )
03389 {
03390 tfrac[0] |= (tfrac[1] >> (64 - shift_count));
03391 tfrac[1] <<= shift_count;
03392 tfrac[1] |= (tfrac[2] >> (64 - shift_count));
03393 tfrac[2] <<= shift_count;
03394 tfrac[2] |= (tfrac[3] >> (64 - shift_count));
03395 tfrac[3] <<= shift_count;
03396
03397 sumexp -= shift_count;
03398 }
03399
03400 #ifdef FP_DEBUG
03401 fprintf(stderr, "sumexp = %x\n", sumexp);
03402 fprintf(stderr, "sfrac[0] = %016llx\n", sfrac[0]);
03403 fprintf(stderr, "sfrac[1] = %016llx\n", sfrac[1]);
03404 fprintf(stderr, "sfrac[2] = %016llx\n", sfrac[2]);
03405 fprintf(stderr, "sfrac[3] = %016llx\n", sfrac[3]);
03406 fprintf(stderr, "tfrac[0] = %016llx\n", tfrac[0]);
03407 fprintf(stderr, "tfrac[1] = %016llx\n", tfrac[1]);
03408 fprintf(stderr, "tfrac[2] = %016llx\n", tfrac[2]);
03409 fprintf(stderr, "tfrac[3] = %016llx\n\n", tfrac[3]);
03410 #endif
03411
03412
03413
03414 guard_bits = tfrac[1];
03415
03416 if ( tfrac[2] != 0 )
03417 guard_bits |= STICKY_BIT;
03418
03419 if ( tfrac[3] != 0 )
03420 guard_bits |= STICKY_BIT;
03421
03422 result = round(sumsign, sumexp, tfrac[0], guard_bits, sf);
03423
03424 return ( result );
03425 }
03426
03427
03428
03429
03430
03431
03432
03433
03434
03435
03436
03437
03438
03439
03440
03441
03442
03443
03444
03445
03446
03447
03448
03449
03450
03451
03452
03453
03454
03455
03456
03457
03458
03459
03460 #ident "$Revision: 1.1.1.1 $"
03461
03462 #include <stdio.h>
03463
03464 #if !defined(linux)
03465 #include <inttypes.h>
03466 #else
03467 #include <sys/types.h>
03468 #endif
03469
03470
03471
03472
03473
03474
03475
03476
03477
03478
03479
03480
03481
03482
03483
03484
03485
03486
03487
03488
03489
03490
03491
03492
03493
03494
03495
03496
03497
03498
03499
03500
03501
03502
03503
03504
03505
03506
03507
03508
03509
03510
03511
03512
03513
03514
03515
03516
03517
03518
03519
03520
03521
03522
03523
03524
03525
03526
03527
03528
03529
03530
03531
03532
03533
03534
03535
03536
03537
03538
03539
03540
03541
03542
03543
03544
03545
03546
03547
03548
03549
03550
03551
03552
03553
03554
03555
03556
03557
03558
03559
03560
03561
03562
03563
03564
03565
03566
03567
03568
03569
03570
03571 static const int8_t carry_bit[4][2][2][2][2] = {
03572 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1,
03573 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1,
03574 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
03575 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
03576 };
03577
03578
03579
03580
03581 static int64_t overflow_result[4][2] =
03582 {
03583 INFINITY, MINFINITY,
03584 MAXVAL, MINFINITY,
03585 INFINITY, MMAXVAL,
03586 MAXVAL, MMAXVAL
03587 };
03588
03589
03590
03591
03592
03593
03594
03595
03596
03597
03598
03599
03600
03601
03602
03603
03604
03605
03606 float_rf
03607 round_l( uint32_t sign, int64_t rs, uint64_t guard_bits, status_field *sf )
03608 {
03609 int32_t rm, rb, gb, sb;
03610 int32_t carry;
03611 float_rf result_rf;
03612
03613
03614
03615 if ( (guard_bits & STICKY_MASK) != 0 )
03616 {
03617 guard_bits &= ~STICKY_MASK;
03618 guard_bits |= STICKY_BIT;
03619 }
03620
03621 rm = sf->b.rc;
03622 rb = rs & 1;
03623 gb = (guard_bits >> 63);
03624 sb = (guard_bits >> 62) & 1;
03625
03626 carry = carry_bit[rm][sign][rb][gb][sb];
03627
03628 rs += carry;
03629
03630
03631
03632
03633
03634
03635
03636 if ( sign )
03637 rs = -rs;
03638
03639 result_rf.sign = 0;
03640 result_rf.exp = 0x1003e;
03641 result_rf.frac = rs;
03642
03643 if ( guard_bits )
03644 {
03645
03646
03647 sf->b.inexact_flag = 1;
03648 }
03649
03650 return ( result_rf );
03651 }
03652
03653
03654
03655
03656
03657
03658
03659
03660
03661
03662
03663
03664
03665
03666
03667
03668
03669
03670 float_rf
03671 round( uint32_t rssign, int32_t rsexp, uint64_t rsfrac,
03672 uint64_t guard_bits, status_field *sf )
03673 {
03674 int32_t precision;
03675 int32_t rm, rb, gb, sb;
03676 int32_t shift;
03677 uint32_t rtsign;
03678 int32_t rtexp;
03679 uint64_t rtfrac;
03680 int32_t shift_count;
03681 uint32_t carry;
03682 uint64_t sticky;
03683 int32_t tininess;
03684 int32_t inexact;
03685 uint64_t guard_bits2;
03686 int64_t return_value;
03687 float_rf biased_result_rf;
03688 int32_t carry_out;
03689 int32_t ftz;
03690 int32_t wre;
03691 int32_t exp_min;
03692 int32_t exp_max;
03693 float_rf result_rf;
03694
03695 #ifdef FP_DEBUG
03696 fprintf(stderr, "round: rssign = %08x\n", rssign);
03697 fprintf(stderr, "rsexp = %08x\n", rsexp);
03698 fprintf(stderr, "rsfrac = %016llx\n", rsfrac);
03699 fprintf(stderr, "guard_bits = %016llx\n\n", guard_bits);
03700 #endif
03701
03702
03703
03704 if ( (guard_bits & STICKY_MASK) != 0 )
03705 {
03706 guard_bits &= ~STICKY_MASK;
03707 guard_bits |= STICKY_BIT;
03708 }
03709
03710 precision = sf->b.pc;
03711
03712 rm = sf->b.rc;
03713
03714 ftz = sf->b.ftz;
03715
03716 wre = sf->b.wre;
03717
03718
03719
03720 rtsign = rssign;
03721 rtexp = rsexp;
03722 rtfrac = rsfrac;
03723 guard_bits2 = guard_bits;
03724
03725 tininess = FALSE;
03726 inexact = FALSE;
03727
03728
03729 int inexact_fix = 0;
03730
03731
03732
03733 if ( precision == SNGL )
03734 {
03735 shift = 40;
03736 exp_min = (wre) ? WEXP_MIN : SEXP_MIN;
03737 exp_max = (wre) ? WEXP_MAX : SEXP_MAX;
03738 guard_bits >>= 40;
03739 guard_bits |= (rsfrac << 24);
03740 rsfrac >>= 40;
03741
03742 if ( (guard_bits & STICKY_MASK) != 0 )
03743 {
03744 guard_bits &= ~STICKY_MASK;
03745 guard_bits |= STICKY_BIT;
03746 }
03747
03748 if ( rsexp < (exp_min - 24) )
03749 {
03750
03751
03752
03753
03754 guard_bits = STICKY_BIT;
03755 rsfrac = 0;
03756 rsexp = exp_min;
03757 }
03758 else if ( rsexp < exp_min )
03759 {
03760 shift_count = exp_min - rsexp;
03761 guard_bits >>= shift_count;
03762 guard_bits |= (rsfrac << (64 - shift_count));
03763 rsfrac >>= shift_count;
03764 rsexp = exp_min;
03765 }
03766 }
03767 else if ( precision == DBL )
03768 {
03769 shift = 11;
03770 exp_min = (wre) ? WEXP_MIN : DEXP_MIN;
03771 exp_max = (wre) ? WEXP_MAX : DEXP_MAX;
03772 guard_bits >>= 11;
03773 guard_bits |= (rsfrac << 53);
03774 rsfrac >>= 11;
03775
03776 if ( (guard_bits & STICKY_MASK) != 0 )
03777 {
03778 guard_bits &= ~STICKY_MASK;
03779 guard_bits |= STICKY_BIT;
03780 }
03781
03782 if ( rsexp < (exp_min - 53) )
03783 {
03784
03785
03786
03787
03788 guard_bits = STICKY_BIT;
03789 rsfrac = 0;
03790 rsexp = exp_min;
03791 }
03792 else if ( rsexp < exp_min )
03793 {
03794 shift_count = exp_min - rsexp;
03795 guard_bits >>= shift_count;
03796 guard_bits |= (rsfrac << (64 - shift_count));
03797 rsfrac >>= shift_count;
03798 rsexp = exp_min;
03799 }
03800 }
03801 else
03802 {
03803 shift = 0;
03804 exp_min = (wre) ? WEXP_MIN : DEEXP_MIN;
03805 exp_max = (wre) ? WEXP_MAX : DEEXP_MAX;
03806
03807 if ( (guard_bits & STICKY_MASK) != 0 )
03808 {
03809 guard_bits &= ~STICKY_MASK;
03810 guard_bits |= STICKY_BIT;
03811 }
03812
03813 if ( rsexp < (exp_min - 64) )
03814 {
03815
03816
03817
03818
03819
03820
03821
03822
03823 if(rsfrac == 0x8000000000000000ull){
03824 inexact_fix = 1;
03825 }
03826
03827 guard_bits = STICKY_BIT;
03828 rsfrac = 0;
03829 rsexp = exp_min;
03830 }
03831 else if ( rsexp == (exp_min - 64) )
03832 {
03833
03834
03835 if ( guard_bits != 0 )
03836 rsfrac |= 1;
03837
03838 guard_bits = rsfrac;
03839 rsfrac = 0;
03840 rsexp = exp_min;
03841 }
03842 else if ( rsexp < exp_min )
03843 {
03844
03845
03846 shift_count = exp_min - rsexp;
03847 sticky = (guard_bits & STICKY_MASK);
03848 guard_bits >>= shift_count;
03849 guard_bits |= (rsfrac << (64 - shift_count));
03850 if ( sticky )
03851 guard_bits |= STICKY_BIT;
03852
03853 rsfrac >>= shift_count;
03854 rsexp = exp_min;
03855 }
03856 }
03857
03858
03859
03860
03861
03862
03863
03864 if((guard_bits) && !inexact_fix){
03865 inexact = TRUE;
03866 }
03867
03868 #ifdef FP_DEBUG
03869 fprintf(stderr, "inexact = %x\n", inexact);
03870 #endif
03871
03872
03873
03874 if ( (guard_bits & STICKY_MASK) != 0ull )
03875 {
03876 guard_bits &= ~STICKY_MASK;
03877 guard_bits |= STICKY_BIT;
03878 }
03879
03880 #ifdef FP_DEBUG
03881 fprintf(stderr, "round: rssign = %08x\n", rssign);
03882 fprintf(stderr, "rsexp = %08x\n", rsexp);
03883 fprintf(stderr, "rsfrac = %016llx\n", rsfrac);
03884 fprintf(stderr, "guard_bits = %016llx\n\n", guard_bits);
03885 #endif
03886
03887 rb = rsfrac & 1;
03888 gb = (guard_bits >> 63);
03889 sb = (guard_bits >> 62) & 1;
03890
03891 carry = carry_bit[rm][rssign][rb][gb][sb];
03892
03893 #ifdef FP_DEBUG
03894 fprintf(stderr, "carry = %x\n\n", carry);
03895 #endif
03896
03897 carry_out = 0;
03898
03899 if ( precision == SNGL )
03900 {
03901 rsfrac += carry;
03902
03903 if ( rsfrac == (1ull << 24) )
03904 {
03905 rsexp += 1;
03906 rsfrac >>= 1;
03907 }
03908 }
03909 else if ( precision == DBL )
03910 {
03911 rsfrac += carry;
03912
03913 if ( rsfrac == (1ull << 53) )
03914 {
03915 rsexp += 1;
03916 rsfrac >>= 1;
03917 }
03918 }
03919 else
03920 {
03921 if ( (rsfrac == ULONGLONG_MAX) && (carry == 1) )
03922 carry_out = 1;
03923
03924 rsfrac += carry;
03925
03926 if ( carry_out == 1 )
03927 {
03928 rsexp += 1;
03929 rsfrac = (1ull << 63);
03930 }
03931 }
03932
03933 #ifdef FP_DEBUG
03934 fprintf(stderr, "round: rssign = %08x\n", rssign);
03935 fprintf(stderr, "rsexp = %08x\n", rsexp);
03936 fprintf(stderr, "rsfrac = %016llx\n\n", rsfrac);
03937 #endif
03938
03939 if ( rsexp > exp_max )
03940 {
03941 #ifdef FP_DEBUG
03942 fprintf(stderr, "overflow\n\n");
03943 #endif
03944
03945
03946 return_value = overflow_result[rm][rssign];
03947
03948 sf->b.overflow_flag = 1;
03949
03950 if ( sf->b.overflow_trap_disabled == 0 )
03951 {
03952
03953
03954
03955
03956
03957
03958 rsexp += EXP_BIAS;
03959 biased_result_rf.sign = rssign;
03960 biased_result_rf.exp = (rsexp & 0x1ffff);
03961 biased_result_rf.frac = (rsfrac << shift);
03962
03963
03964
03965 if ( rsexp != (rsexp & 0x1ffff) )
03966 sf->b.ISR_ebc = 1;
03967
03968
03969
03970
03971
03972 if ( carry == 1 )
03973 sf->b.ISR_fpa = 1;
03974
03975
03976
03977 if ( guard_bits || (rsexp != (rsexp & 0x1ffff)) )
03978 sf->b.inexact_flag = 1;
03979
03980 return ( biased_result_rf );
03981 }
03982
03983
03984
03985 sf->b.inexact_flag = 1;
03986
03987
03988
03989
03990 #ifdef FP_DEBUG
03991 fprintf(stderr, "return_value = %016llx\n", return_value);
03992 #endif
03993
03994 if ( return_value == INFINITY )
03995 {
03996 result_rf.sign = 0;
03997 result_rf.exp = EXP_INF;
03998 result_rf.frac = (1ull << 63);
03999 }
04000 else if ( return_value == MINFINITY )
04001 {
04002 result_rf.sign = 1;
04003 result_rf.exp = EXP_INF;
04004 result_rf.frac = (1ull << 63);
04005 }
04006 else if ( return_value == MAXVAL )
04007 {
04008 result_rf.sign = 0;
04009 result_rf.exp = exp_max;
04010 result_rf.frac = (1ull << 63);
04011 }
04012 else
04013 {
04014 result_rf.sign = 1;
04015 result_rf.exp = exp_max;
04016 result_rf.frac = (1ull << 63);
04017 }
04018
04019 return ( result_rf );
04020 }
04021
04022
04023
04024 tininess = FALSE;
04025
04026 if ( rsexp == exp_min )
04027 {
04028 if ( (precision == SNGL) && ((rsfrac & BIT23) == 0) )
04029 tininess = TRUE;
04030 else if ( (precision == DBL) && ((rsfrac & BIT52) == 0) )
04031 tininess = TRUE;
04032 else if ( (rsfrac & HIGH_BIT) == 0 )
04033 tininess = TRUE;
04034 }
04035
04036 #ifdef FP_DEBUG
04037 fprintf(stderr, "tininess = %x\n\n", tininess);
04038 #endif
04039
04040
04041
04042 if ( ftz )
04043 {
04044
04045
04046 if ( tininess == TRUE )
04047 {
04048 result_rf.sign = rssign;
04049 result_rf.exp = 0;
04050 result_rf.frac = 0ull;
04051
04052 sf->b.inexact_flag = 1;
04053 sf->b.underflow_flag = 1;
04054
04055 return ( result_rf );
04056 }
04057 }
04058
04059 if ( tininess == FALSE )
04060 {
04061
04062
04063 if ( inexact == TRUE )
04064 sf->b.inexact_flag = 1;
04065
04066 rsexp += EXP_BIAS;
04067
04068 if ( precision == SNGL )
04069 {
04070 rsfrac <<= 40;
04071 }
04072 else if ( precision == DBL )
04073 {
04074 rsfrac <<= 11;
04075 }
04076
04077 result_rf.sign = rssign;
04078 result_rf.exp = rsexp;
04079 result_rf.frac = rsfrac;
04080
04081 return ( result_rf );
04082 }
04083
04084
04085
04086 if ( sf->b.underflow_trap_disabled == 0 )
04087 {
04088
04089
04090 sf->b.underflow_flag = 1;
04091
04092
04093
04094 if ( precision == SNGL )
04095 {
04096 guard_bits2 >>= 40;
04097 guard_bits2 |= (rtfrac << 24);
04098 rtfrac >>= 40;
04099
04100 }
04101 else if ( precision == DBL )
04102 {
04103 guard_bits2 >>= 11;
04104 guard_bits2 |= (rtfrac << 53);
04105 rtfrac >>= 11;
04106 }
04107
04108
04109
04110 if ( (guard_bits2 & STICKY_MASK) != 0 )
04111 {
04112 guard_bits2 &= ~STICKY_MASK;
04113 guard_bits2 |= STICKY_BIT;
04114 }
04115
04116 rb = rtfrac & 1;
04117 gb = (guard_bits2 >> 63);
04118 sb = (guard_bits2 >> 62) & 1;
04119
04120 carry = carry_bit[rm][rtsign][rb][gb][sb];
04121
04122
04123
04124 carry_out = 0;
04125
04126 if ( precision == SNGL )
04127 {
04128 rtfrac += carry;
04129
04130 if ( rtfrac == (1ull << 24) )
04131 {
04132 rtexp += 1;
04133 rtfrac >>= 1;
04134 }
04135 }
04136 else if ( precision == DBL )
04137 {
04138 rtfrac += carry;
04139
04140 if ( rtfrac == (1ull << 53) )
04141 {
04142 rtexp += 1;
04143 rtfrac >>= 1;
04144 }
04145 }
04146 else
04147 {
04148 carry_out = 0;
04149
04150 if ( (rtfrac == ULONGLONG_MAX) && (carry == 1) )
04151 carry_out = 1;
04152
04153 rtfrac += carry;
04154
04155 if ( carry_out == 1 )
04156 {
04157 rtexp += 1;
04158 rtfrac = (1ull << 63);
04159 }
04160 }
04161
04162 rtexp += EXP_BIAS;
04163 biased_result_rf.sign = rtsign;
04164 biased_result_rf.exp = (rtexp & 0x1ffff);
04165 biased_result_rf.frac = (rtfrac << shift);
04166
04167
04168
04169 if ( rtexp != (rtexp & 0x1ffff) )
04170 sf->b.ISR_ebc = 1;
04171
04172
04173
04174
04175 if ( carry == 1 )
04176 sf->b.ISR_fpa = 1;
04177
04178
04179
04180
04181 if (( guard_bits || (rtexp != (rtexp & 0x1ffff))) && !inexact_fix)
04182 sf->b.inexact_flag = 1;
04183
04184 return ( biased_result_rf );
04185
04186 }
04187 else
04188 {
04189 if ( inexact == TRUE )
04190 {
04191 sf->b.underflow_flag = 1;
04192
04193 sf->b.inexact_flag = 1;
04194 }
04195 }
04196
04197 if ( rsfrac == 0 )
04198 {
04199 rsexp = 0;
04200 }
04201 else
04202 {
04203 rsexp += EXP_BIAS;
04204
04205 rsfrac <<= shift;
04206
04207 if ( precision == DBL_EXT )
04208 {
04209 if ( rsexp == 0x0c001 )
04210 rsexp = 0;
04211 }
04212 }
04213
04214 result_rf.sign = rssign;
04215 result_rf.exp = rsexp;
04216 result_rf.frac = rsfrac;
04217
04218 return ( result_rf );
04219 }
04220
04221
04222
04223
04224
04225
04226
04227
04228
04229
04230
04231
04232
04233
04234
04235
04236
04237
04238
04239
04240 #ifndef _FPSWA_H_
04241 #endif
04242
04243 #ifdef BARF
04244 inline int
04245 fp_is_natval(const float_rf *freg){
04246
04247 if((freg->sign == 0)
04248 && (freg->exp == 0x1fffe)
04249 && (freg->frac == 0)) {
04250 return(1);
04251 }
04252 else {
04253 return(0);
04254 }
04255 }
04256
04257 inline int
04258 fp_is_inf(const float_rf *freg){
04259
04260 if((freg->exp == 0x1ffff) && (freg->frac == 0x8000000000000000ull)) {
04261 return(1);
04262 }
04263 else {
04264 return(0);
04265 }
04266 }
04267
04268
04269 inline int
04270 fp_is_nan(const float_rf *freg){
04271
04272 if((freg->exp == 0x1ffff)
04273 && ((freg->frac & 0x8000000000000000ull) != 0)
04274 && ((freg->frac & 0x7fffffffffffffffull) != 0)) {
04275 return(1);
04276 }
04277 else {
04278 return(0);
04279 }
04280 }
04281
04282 inline int
04283 fp_is_snan(const float_rf *freg){
04284
04285 if((freg->exp == 0x1ffff)
04286 && ((freg->frac & 0xc000000000000000ull) == 0xc000000000000000ull)
04287 && ((freg->frac & 0x3fffffffffffffffull) != 0)){
04288 return(1);
04289 }
04290 else {
04291 return(0);
04292 }
04293 }
04294
04295 inline int
04296 fp_is_qnan(const float_rf *freg){
04297
04298 if((freg->exp == 0x1ffff)
04299 && ((freg->frac & 0xc000000000000000ull) == 0xc000000000000000ull)){
04300 return(1);
04301 }
04302 else {
04303 return(0);
04304 }
04305 }
04306
04307 inline int
04308 fp_is_neg_inf(const float_rf *freg){
04309
04310 if((freg->sign == 1)
04311 && (freg->exp == 0x1ffff)
04312 && (freg->frac == 0x8000000000000000ull)) {
04313 return(1);
04314 }
04315 else {
04316 return(0);
04317 }
04318 }
04319
04320 inline int
04321 fp_is_neg_non_zero(const float_rf *freg){
04322
04323 if((freg->sign == 1) && !fp_is_zero(freg)) {
04324 return(1);
04325 }
04326 else {
04327 return(0);
04328 }
04329 }
04330
04331 inline int
04332 fp_is_normal(const float_rf *freg){
04333
04334 if((freg->exp != 0)
04335 && (freg->exp != 0x1ffff)
04336 && ((freg->frac & 0x8000000000000000ull) != 0)) {
04337 return(1);
04338 }
04339 else {
04340 return(0);
04341 }
04342 }
04343
04344 inline int
04345 fp_is_pos_inf(const float_rf *freg){
04346
04347 if((freg->sign == 0)
04348 && (freg->exp == 0x1ffff)
04349 && (freg->frac == 0x8000000000000000ull)) {
04350 return(1);
04351 }
04352 else {
04353 return(0);
04354 }
04355 }
04356
04357 inline int
04358 fp_is_pos_non_zero(const float_rf *freg){
04359
04360 if((freg->sign == 0) && !fp_is_zero(freg)) {
04361 return(1);
04362 }
04363 else {
04364 return(0);
04365 }
04366 }
04367
04368 inline int
04369 fp_is_pseudo_zero(const float_rf *freg){
04370
04371 if((freg->exp != 0)
04372 && (freg->exp != 0x1ffff)
04373 && (freg->frac == 0)
04374 && (!fp_is_natval(freg))) {
04375 return(1);
04376 }
04377 else {
04378 return(0);
04379 }
04380 }
04381
04382 inline int
04383 fp_is_unorm(const float_rf *freg){
04384
04385 if((((freg->exp != 0)
04386 && (freg->exp != 0x1ffff)
04387 && ((freg->frac & 0x8000000000000000ull) == 0))
04388 && (!fp_is_natval(freg)))
04389
04390 || ((freg->exp == 0) && (freg->frac != 0))) {
04391 return(1);
04392 }
04393 else {
04394 return(0);
04395 }
04396 }
04397
04398
04399 inline int
04400 fp_is_unorm_not_pseudo_denorm(const float_rf *freg){
04401
04402 if(((freg->exp != 0)
04403 && (freg->exp != 0x1ffff)
04404 &&((freg->frac & 0x8000000000000000ull) == 0))
04405
04406 || ((freg->exp == 0) &&
04407 (freg->frac & 0x8000000000000000ull) == 0)) {
04408 return(1);
04409 }
04410 else {
04411 return(0);
04412 }
04413 }
04414
04415
04416 inline int
04417 fp_is_unsupported(const float_rf *freg){
04418
04419 if(fp_is_natval(freg) || fp_is_nan(freg) || fp_is_inf(freg)
04420 || fp_is_normal(freg) || fp_is_unorm(freg) || fp_is_zero(freg)) {
04421 return(0);
04422 }
04423 else {
04424 return(1);
04425 }
04426 }
04427
04428
04429 inline int
04430 fp_is_zero(const float_rf *freg){
04431
04432 if((freg->exp == 0) && (freg->frac == 0)) {
04433 return(1);
04434 }
04435 else {
04436 return(0);
04437 }
04438 }
04439
04440 #endif
04441
04442 int
04443 fp_software_assistance_required(fp_op_type opcode,const float_rf *fr2,
04444 const float_rf *fr3, const float_rf *fr4,
04445 int sf_dd){
04446
04447 int do_swa_fault=0;
04448
04449
04450
04451
04452
04453
04454 switch (opcode) {
04455 case op_fcmp:
04456 if((fp_is_unsupported(fr2) || fp_is_unsupported(fr3)) ||
04457 (fp_is_nan(fr2) || fp_is_nan(fr3))){
04458 do_swa_fault = 0;
04459 }
04460 else if(fp_is_unorm(fr2) || fp_is_unorm(fr3)) {
04461 do_swa_fault = 1;
04462 }
04463 break;
04464
04465 case op_fpcmp:
04466 if(fp_is_nan(fr2) || fp_is_nan(fr3)) {
04467 do_swa_fault = 0;
04468 }
04469 else if(fp_is_unorm(fr2) || fp_is_unorm(fr3)) {
04470 do_swa_fault = 1;
04471 }
04472 break;
04473
04474 case op_fcvt_fx:
04475 if(fp_is_unsupported(fr2) || fp_is_nan(fr2)) {
04476 do_swa_fault = 0;
04477 }
04478 else if(fp_is_unorm(fr2)) {
04479 do_swa_fault = 1;
04480 }
04481 break;
04482
04483 case op_fpcvt_fx:
04484 if(fp_is_nan(fr2)) {
04485 do_swa_fault = 0;
04486 }
04487 else if(fp_is_unorm(fr2)) {
04488 do_swa_fault = 1;
04489 }
04490 break;
04491
04492 case op_fcvt_fxu:
04493 if(fp_is_unsupported(fr2) || fp_is_nan(fr2)) {
04494 do_swa_fault = 0;
04495 }
04496 else if(fp_is_unorm(fr2)) {
04497 do_swa_fault = 1;
04498 }
04499 break;
04500
04501 case op_fpcvt_fxu:
04502 if(fp_is_nan(fr2)) {
04503 do_swa_fault = 0;
04504 }
04505 else if(fp_is_unorm(fr2)) {
04506 do_swa_fault = 1;
04507 }
04508 break;
04509
04510 case op_fma:
04511 if(
04512 (fp_is_unsupported(fr2) || fp_is_unsupported(fr3) || fp_is_unsupported(fr4)) ||
04513 (fp_is_nan(fr2) || fp_is_nan(fr3) || fp_is_nan(fr4)) ||
04514
04515 ((fp_is_pos_inf(fr3) && fp_is_pos_non_zero(fr4) && fp_is_neg_inf(fr2))
04516 || (fp_is_pos_inf(fr3) && fp_is_neg_non_zero(fr4) && fp_is_pos_inf(fr2))
04517
04518 || (fp_is_neg_inf(fr3) && fp_is_pos_non_zero(fr4) && fp_is_pos_inf(fr2))
04519 || (fp_is_neg_inf(fr3) && fp_is_neg_non_zero(fr4) && fp_is_neg_inf(fr2))
04520
04521 || (fp_is_pos_non_zero(fr3) && fp_is_pos_inf(fr4) && fp_is_neg_inf(fr2))
04522 || (fp_is_pos_non_zero(fr3) && fp_is_neg_inf(fr4) && fp_is_pos_inf(fr2))
04523
04524 || (fp_is_neg_non_zero(fr3) && fp_is_pos_inf(fr4) && fp_is_pos_inf(fr2))
04525 || (fp_is_neg_non_zero(fr3) && fp_is_neg_inf(fr4) && fp_is_neg_inf(fr2))) ||
04526
04527 ((fp_is_inf(fr3) && fp_is_zero(fr4)) || (fp_is_zero(fr3) && fp_is_inf(fr4)))) {
04528 do_swa_fault = 0;
04529 }
04530 else if(fp_is_unorm(fr2) || fp_is_unorm(fr3) || fp_is_unorm(fr4)) {
04531 do_swa_fault = 1;
04532 }
04533 break;
04534
04535 case op_fpma:
04536 if(
04537 (fp_is_nan(fr2) || fp_is_nan(fr3) || fp_is_nan(fr4)) ||
04538
04539 ((fp_is_pos_inf(fr3) && fp_is_pos_non_zero(fr4)
04540 && fp_is_neg_inf(fr2))
04541 || (fp_is_pos_inf(fr3) && fp_is_neg_non_zero(fr4)
04542 && fp_is_pos_inf(fr2))
04543
04544 || (fp_is_neg_inf(fr3) && fp_is_pos_non_zero(fr4)
04545 && fp_is_pos_inf(fr2))
04546 || (fp_is_neg_inf(fr3) && fp_is_neg_non_zero(fr4)
04547 && fp_is_neg_inf(fr2))
04548
04549 || (fp_is_pos_non_zero(fr3) && fp_is_pos_inf(fr4)
04550 && fp_is_neg_inf(fr2))
04551 || (fp_is_pos_non_zero(fr3) && fp_is_neg_inf(fr4)
04552 && fp_is_pos_inf(fr2))
04553
04554 || (fp_is_neg_non_zero(fr3) && fp_is_pos_inf(fr4)
04555 && fp_is_pos_inf(fr2))
04556 || (fp_is_neg_non_zero(fr3) && fp_is_neg_inf(fr4)
04557 && fp_is_neg_inf(fr2))) ||
04558
04559 ((fp_is_inf(fr3) && fp_is_zero(fr4))
04560 || (fp_is_zero(fr3) && fp_is_inf(fr4)))) {
04561 do_swa_fault = 0;
04562 }
04563 else if(fp_is_unorm(fr2) || fp_is_unorm(fr3) || fp_is_unorm(fr4)) {
04564 do_swa_fault = 1;
04565 }
04566 break;
04567
04568 case op_fminmax:
04569 if((fp_is_unsupported(fr2) || fp_is_unsupported(fr3)) ||
04570 (fp_is_nan(fr2) || fp_is_nan(fr3)) ){
04571 do_swa_fault = 0;
04572 }
04573 else if(fp_is_unorm(fr2) || fp_is_unorm(fr3)) {
04574 do_swa_fault = 1;
04575 }
04576 break;
04577
04578 case op_fpminmax:
04579 if(fp_is_nan(fr2) || fp_is_nan(fr3)) {
04580 do_swa_fault = 0;
04581 }
04582 else if(fp_is_unorm(fr2) || fp_is_unorm(fr3)) {
04583 do_swa_fault = 1;
04584 }
04585 break;
04586
04587 case op_fms_fnma:
04588 if(
04589 (fp_is_unsupported(fr2) || fp_is_unsupported(fr3) || fp_is_unsupported(fr4)) ||
04590 (fp_is_nan(fr2) || fp_is_nan(fr3) || fp_is_nan(fr4)) ||
04591
04592 ((fp_is_pos_inf(fr3) && fp_is_pos_non_zero(fr4) && fp_is_pos_inf(fr2))
04593 || (fp_is_pos_inf(fr3) && fp_is_neg_non_zero(fr4) && fp_is_neg_inf(fr2))
04594 || (fp_is_neg_inf(fr3) && fp_is_pos_non_zero(fr4) && fp_is_neg_inf(fr2))
04595 || (fp_is_neg_inf(fr3) && fp_is_neg_non_zero(fr4) && fp_is_pos_inf(fr2))
04596 || (fp_is_pos_non_zero(fr3) && fp_is_pos_inf(fr4) && fp_is_pos_inf(fr2))
04597 || (fp_is_pos_non_zero(fr3) && fp_is_neg_inf(fr4) && fp_is_neg_inf(fr2))
04598 || (fp_is_neg_non_zero(fr3) && fp_is_pos_inf(fr4) && fp_is_neg_inf(fr2))
04599 || (fp_is_neg_non_zero(fr3) && fp_is_neg_inf(fr4) && fp_is_pos_inf(fr2))) ||
04600
04601 ((fp_is_inf(fr3) && fp_is_zero(fr4)) || (fp_is_zero(fr3) && fp_is_inf(fr4)))) {
04602 do_swa_fault = 0;
04603 }
04604 else if(fp_is_unorm(fr2) || fp_is_unorm(fr3) || fp_is_unorm(fr4)) {
04605 do_swa_fault = 1;
04606 }
04607 break;
04608
04609 case op_fpms_fpnma:
04610 if(
04611 (fp_is_unsupported(fr2) || fp_is_unsupported(fr3) || fp_is_unsupported(fr4)) ||
04612 (fp_is_nan(fr2) || fp_is_nan(fr3) || fp_is_nan(fr4)) ||
04613
04614 ((fp_is_pos_inf(fr3) && fp_is_pos_non_zero(fr4)
04615 && fp_is_pos_inf(fr2))
04616 || (fp_is_pos_inf(fr3) && fp_is_neg_non_zero(fr4)
04617 && fp_is_neg_inf(fr2))
04618 || (fp_is_neg_inf(fr3) && fp_is_pos_non_zero(fr4)
04619 && fp_is_neg_inf(fr2))
04620 || (fp_is_neg_inf(fr3) && fp_is_neg_non_zero(fr4)
04621 && fp_is_pos_inf(fr2))
04622 || (fp_is_pos_non_zero(fr3) && fp_is_pos_inf(fr4)
04623 && fp_is_pos_inf(fr2))
04624 || (fp_is_pos_non_zero(fr3) && fp_is_neg_inf(fr4)
04625 && fp_is_neg_inf(fr2))
04626 || (fp_is_neg_non_zero(fr3) && fp_is_pos_inf(fr4)
04627 && fp_is_neg_inf(fr2))
04628 || (fp_is_neg_non_zero(fr3) && fp_is_neg_inf(fr4)
04629 && fp_is_pos_inf(fr2))) ||
04630
04631 ((fp_is_inf(fr3) && fp_is_zero(fr4))
04632 || (fp_is_zero(fr3) && fp_is_inf(fr4)) )) {
04633 do_swa_fault = 0;
04634 }
04635 else if(fp_is_unorm(fr2) || fp_is_unorm(fr3) || fp_is_unorm(fr4)) {
04636 do_swa_fault = 1;
04637 }
04638 break;
04639
04640 case op_fnorm:
04641 if(fp_is_unsupported(fr3) || fp_is_nan(fr3)) {
04642 do_swa_fault = 0;
04643 }
04644 else if(fp_is_unorm(fr3)) {
04645 if(((fr3->exp > 0) && (fr3->exp < 0x1ffff)) &&
04646 (sf_dd == 1)) {
04647 do_swa_fault = 0;
04648 }
04649 else {
04650 do_swa_fault = 1;
04651 }
04652 }
04653 break;
04654
04655 case op_frcpa:
04656 if(
04657 (fp_is_unsupported(fr2) || fp_is_unsupported(fr3)) ||
04658 (fp_is_nan(fr2) || fp_is_nan(fr3)) ||
04659
04660 ((fp_is_inf(fr2) && fp_is_inf(fr3))
04661 || ((fp_is_zero(fr2) || fp_is_pseudo_zero(fr2))
04662 && (fp_is_zero(fr3) || fp_is_pseudo_zero(fr3)))) ||
04663
04664 (((fp_is_normal(fr2) && !fp_is_zero(fr2))
04665 || (fp_is_unorm(fr2) && !fp_is_pseudo_zero(fr2)))
04666 && (fp_is_zero(fr3) || fp_is_pseudo_zero(fr3)))) {
04667 do_swa_fault = 0;
04668 }
04669 else if(fp_is_unorm(fr2) || fp_is_unorm(fr3)) {
04670 do_swa_fault = 1;
04671 }
04672 break;
04673
04674 case op_fprcpa:
04675 if((fp_is_nan(fr2) || fp_is_nan(fr3)) ||
04676 ((fp_is_inf(fr2) && fp_is_inf(fr3))
04677 || (fp_is_zero(fr2) && fp_is_zero(fr3))) ||
04678 (!fp_is_zero(fr2) && fp_is_zero(fr3))) {
04679 do_swa_fault = 0;
04680 }
04681 else if(fp_is_unorm(fr2) || fp_is_unorm(fr3)) {
04682 do_swa_fault = 1;
04683 }
04684
04685 break;
04686
04687 case op_frsqrta:
04688 if(fp_is_unsupported(fr2) ||
04689 fp_is_nan(fr2) ||
04690 fp_is_neg_inf(fr2) ||
04691 (fp_is_neg_non_zero(fr2) && !fp_is_pseudo_zero(fr2) &&
04692 !fp_is_unorm_not_pseudo_denorm(fr2))) {
04693 do_swa_fault = 0;
04694 }
04695 else if(fp_is_unorm(fr2)) {
04696 do_swa_fault = 1;
04697 }
04698 break;
04699
04700 case op_fprsqrta:
04701 if(fp_is_nan(fr2) || fp_is_neg_inf(fr2) ||
04702 (fp_is_neg_non_zero(fr2) && !fp_is_unorm(fr2))) {
04703 do_swa_fault = 0;
04704 }
04705 else if(fp_is_unorm(fr2)) {
04706 do_swa_fault = 1;
04707 }
04708
04709 break;
04710 }
04711
04712 return(do_swa_fault);
04713
04714 }
04715
04716
04717
04718
04719
04720 #include <stdio.h>
04721 #include <inttypes.h>
04722 #include <stdlib.h>
04723
04724 static int8_t shift_count[16] =
04725 {
04726 0, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
04727 };
04728
04729
04730
04731
04732
04733
04734 int32_t
04735 renorm( uint64_t *p_val )
04736 {
04737 int32_t count;
04738 int32_t index;
04739
04740 if ( (*p_val) == 0ull )
04741 {
04742
04743
04744 fprintf(stderr, "renorm: mantissa is zero, aborting\n");
04745 abort();
04746
04747 return ( 0 );
04748 }
04749
04750 if ( (*p_val) & (1ull << 63) )
04751 return ( 0 );
04752
04753 count = 0;
04754
04755 while ( ((*p_val) & 0xfff0000000000000ull) == 0ull )
04756 {
04757 *p_val <<= 12;
04758 count += 12;
04759 }
04760
04761 while ( ((*p_val) & 0xf000000000000000ull) == 0ull )
04762 {
04763 *p_val <<= 4;
04764 count += 4;
04765 }
04766
04767 index = ((*p_val >> 60) & 0xf);
04768
04769 *p_val <<= shift_count[index];
04770 count += shift_count[index];
04771
04772 return ( count );
04773 }
04774
04775 void
04776 breakout( const float_rf *rs, uint32_t *rssign, int32_t *rsexp,
04777 uint64_t *rsfrac, status_field *sf )
04778 {
04779 int32_t shift_count;
04780
04781 *rssign = rs->sign;
04782 *rsexp = rs->exp;
04783 *rsfrac = rs->frac;
04784
04785 if ( ((*rsexp) == 0) && ((*rsfrac) == 0ull) )
04786 return;
04787
04788 if ( ((*rsexp) == 0) && (((*rsfrac) & HIGH_BIT) == 0) )
04789 {
04790
04791
04792
04793
04794 (*rsexp) = 0x0c001;
04795 }
04796
04797
04798
04799 if ( (0x00001 <= (*rsexp)) && ((*rsexp) <= 0x1fffe) &&
04800 (*rsfrac == 0)
04801 )
04802 {
04803 (*rsexp) = 0;
04804
04805 return;
04806 }
04807
04808
04809
04810 if ( ((*rsexp) == 0x1ffff) && (*rsfrac == 0) )
04811 {
04812 (*rsfrac) = HIGH_BIT;
04813 }
04814 else if ( ((*rsexp) == 0x1ffff) && (((*rsfrac) & HIGH_BIT) == 0) )
04815 {
04816
04817
04818 (*rsfrac) = (3ull << 62);
04819 }
04820 else if ( ((*rsfrac) & HIGH_BIT) == 0 )
04821 {
04822
04823
04824 shift_count = renorm( rsfrac );
04825 *rsexp -= shift_count;
04826
04827 sf->b.den_unn_op_flag = 1;
04828 }
04829
04830 return;
04831 }
04832
04833 int32_t
04834 breakout_and_test( const float_rf *rs, uint32_t *rssign, int32_t *rsexp,
04835 uint64_t *rsfrac, status_field *sf )
04836 {
04837 int32_t result;
04838
04839 breakout(rs, rssign, rsexp, rsfrac, sf);
04840
04841 if ( (*rsexp == EXP_NATVAL) && (*rsfrac == (1ull << 61)) )
04842 {
04843 result = NATVAL;
04844 return ( result );
04845 }
04846
04847 if ( (*rsexp == EXP_NAN) && (*rsfrac > (1ull << 63)) &&
04848 (*rsfrac < (0x3ull << 62))
04849 )
04850 {
04851 result = SIGNALING_NAN;
04852 return ( result );
04853 }
04854
04855 if ( (*rsexp == EXP_NAN) && (*rsfrac >= (0x3ull << 62)) )
04856 {
04857 result = QUIET_NAN;
04858 return ( result );
04859 }
04860
04861 return ( 0 );
04862 }
04863
04864 int32_t
04865 breakout_and_test2( const float_rf *rs, uint32_t *rssign, int32_t *rsexp, uint64_t *rsfrac,
04866 const float_rf *rt, uint32_t *rtsign, int32_t *rtexp, uint64_t *rtfrac,
04867 status_field *sf )
04868 {
04869 int32_t result;
04870
04871 breakout(rs, rssign, rsexp, rsfrac, sf);
04872
04873 breakout(rt, rtsign, rtexp, rtfrac, sf);
04874
04875 if ( (*rsexp == EXP_NATVAL) && (*rsfrac == (1ull << 61)) ||
04876 (*rtexp == EXP_NATVAL) && (*rtfrac == (1ull << 61))
04877 )
04878 {
04879 result = NATVAL;
04880 return ( result );
04881 }
04882
04883 if ( (*rsexp == EXP_NAN) && (*rsfrac > (1ull << 63)) &&
04884 (*rsfrac < (0x3ull << 62))
04885 )
04886 {
04887 result = SIGNALING_NAN;
04888 return ( result );
04889 }
04890
04891 if ( (*rtexp == EXP_NAN) && (*rtfrac > (1ull << 63)) &&
04892 (*rtfrac < (0x3ull << 62))
04893 )
04894 {
04895 result = SIGNALING_NAN;
04896 return ( result );
04897 }
04898
04899 if ( (*rsexp == EXP_NAN) && (*rsfrac >= (0x3ull << 62)) )
04900 {
04901 result = QUIET_NAN;
04902 return ( result );
04903 }
04904
04905 if ( (*rtexp == EXP_NAN) && (*rtfrac >= (0x3ull << 62)) )
04906 {
04907 result = QUIET_NAN;
04908 return ( result );
04909 }
04910
04911 return ( 0 );
04912 }
04913
04914 int32_t
04915 breakout_and_test3( const float_rf *rs, uint32_t *rssign, int32_t *rsexp, uint64_t *rsfrac,
04916 const float_rf *rt, uint32_t *rtsign, int32_t *rtexp, uint64_t *rtfrac,
04917 const float_rf *rr, uint32_t *rrsign, int32_t *rrexp, uint64_t *rrfrac,
04918 status_field *sf )
04919 {
04920 int32_t result;
04921
04922 breakout(rs, rssign, rsexp, rsfrac, sf);
04923
04924 breakout(rt, rtsign, rtexp, rtfrac, sf);
04925
04926 breakout(rr, rrsign, rrexp, rrfrac, sf);
04927
04928 if ( (*rsexp == EXP_NATVAL) && (*rsfrac == (1ull << 61)) ||
04929 (*rtexp == EXP_NATVAL) && (*rtfrac == (1ull << 61)) ||
04930 (*rrexp == EXP_NATVAL) && (*rrfrac == (1ull << 61))
04931 )
04932 {
04933 result = NATVAL;
04934 return ( result );
04935 }
04936
04937 if ( (*rsexp == EXP_NAN) && (*rsfrac > (1ull << 63)) &&
04938 (*rsfrac < (0x3ull << 62))
04939 )
04940 {
04941 result = SIGNALING_NAN;
04942 return ( result );
04943 }
04944
04945 if ( (*rtexp == EXP_NAN) && (*rtfrac > (1ull << 63)) &&
04946 (*rtfrac < (0x3ull << 62))
04947 )
04948 {
04949 result = SIGNALING_NAN;
04950 return ( result );
04951 }
04952
04953 if ( (*rrexp == EXP_NAN) && (*rrfrac > (1ull << 63)) &&
04954 (*rrfrac < (0x3ull << 62))
04955 )
04956 {
04957 result = SIGNALING_NAN;
04958 return ( result );
04959 }
04960
04961 if ( (*rsexp == EXP_NAN) && (*rsfrac >= (0x3ull << 62)) )
04962 {
04963 result = QUIET_NAN;
04964 return ( result );
04965 }
04966
04967 if ( (*rtexp == EXP_NAN) && (*rtfrac >= (0x3ull << 62)) )
04968 {
04969 result = QUIET_NAN;
04970 return ( result );
04971 }
04972
04973 if ( (*rrexp == EXP_NAN) && (*rrfrac >= (0x3ull << 62)) )
04974 {
04975 result = QUIET_NAN;
04976 return ( result );
04977 }
04978
04979 return ( 0 );
04980 }
04981
04982
04983
04984
04985
04986 #ifdef _MUL64_DEBUG
04987 #include <stdio.h>
04988 #endif
04989
04990 #ifndef _LP64
04991 typedef unsigned long long uint64_t;
04992 #endif
04993
04994 #define LOW32BITS 0xffffffffull
04995
04996
04997
04998
04999
05000
05001
05002 uint64_t
05003 mul64( uint64_t x, uint64_t y, uint64_t *low_bits )
05004 {
05005 int i, j;
05006 uint64_t u[2], v[2], w[4];
05007 uint64_t t, k;
05008 uint64_t z[2];
05009
05010 #ifdef _MUL64_DEBUG
05011
05012 printf("mul64: x = %016llx\n", x);
05013 printf("mul64: y = %016llx\n", y);
05014
05015 #endif
05016
05017
05018
05019 u[0] = (x & LOW32BITS);
05020 x >>= 32;
05021
05022 u[1] = (x & LOW32BITS);
05023
05024 v[0] = (y & LOW32BITS);
05025 y >>= 32;
05026
05027 v[1] = (y & LOW32BITS);
05028
05029 #ifdef _MUL64_DEBUG
05030
05031 printf("u[0] = %016llx\n", u[0]);
05032 printf("u[1] = %016llx\n", u[1]);
05033 printf("v[0] = %016llx\n", v[0]);
05034 printf("v[1] = %016llx\n\n", v[1]);
05035
05036 #endif
05037
05038
05039
05040
05041
05042 w[0] = w[1] = w[2] = w[3] = 0;
05043
05044 for ( j=0; j<2; j++ )
05045 {
05046 if ( v[j] == 0 )
05047 {
05048 w[j+2] = 0;
05049 continue;
05050 }
05051
05052 k = 0;
05053
05054 for ( i=0; i<2; i++ )
05055 {
05056 t = u[i]*v[j] + w[i+j] + k;
05057 w[i+j] = (t & LOW32BITS);
05058 k = (t >> 32);
05059 }
05060
05061 w[j+2] = k;
05062 }
05063
05064 #ifdef _MUL64_DEBUG
05065
05066 printf("w[0] = %016llx\n", w[0]);
05067 printf("w[1] = %016llx\n", w[1]);
05068 printf("w[2] = %016llx\n", w[2]);
05069 printf("w[3] = %016llx\n\n", w[3]);
05070
05071 #endif
05072
05073
05074
05075 z[0] = (w[0] | (w[1] << 32));
05076 z[1] = (w[2] | (w[3] << 32));
05077
05078 #ifdef _MUL64_DEBUG
05079
05080 printf("z[0] = %016llx\n", z[0]);
05081 printf("z[1] = %016llx\n", z[1]);
05082
05083 #endif
05084 *low_bits = z[0];
05085 return ( z[1] );
05086
05087 }
05088
05089
05090
05091