diff options
Diffstat (limited to 'soft-fp')
85 files changed, 3777 insertions, 3286 deletions
diff --git a/soft-fp/adddf3.c b/soft-fp/adddf3.c index 55df554..2f11c9c 100644 --- a/soft-fp/adddf3.c +++ b/soft-fp/adddf3.c @@ -31,10 +31,13 @@ #include "soft-fp.h" #include "double.h" -DFtype __adddf3(DFtype a, DFtype b) +DFtype +__adddf3(DFtype a, DFtype b) { FP_DECL_EX; - FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R); + FP_DECL_D(A); + FP_DECL_D(B); + FP_DECL_D(R); DFtype r; FP_INIT_ROUNDMODE; diff --git a/soft-fp/addsf3.c b/soft-fp/addsf3.c index 8a31449..abd8dfa 100644 --- a/soft-fp/addsf3.c +++ b/soft-fp/addsf3.c @@ -31,10 +31,13 @@ #include "soft-fp.h" #include "single.h" -SFtype __addsf3(SFtype a, SFtype b) +SFtype +__addsf3(SFtype a, SFtype b) { FP_DECL_EX; - FP_DECL_S(A); FP_DECL_S(B); FP_DECL_S(R); + FP_DECL_S(A); + FP_DECL_S(B); + FP_DECL_S(R); SFtype r; FP_INIT_ROUNDMODE; diff --git a/soft-fp/addtf3.c b/soft-fp/addtf3.c index 7a27325..819b7d1 100644 --- a/soft-fp/addtf3.c +++ b/soft-fp/addtf3.c @@ -31,10 +31,13 @@ #include "soft-fp.h" #include "quad.h" -TFtype __addtf3(TFtype a, TFtype b) +TFtype +__addtf3(TFtype a, TFtype b) { FP_DECL_EX; - FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(R); + FP_DECL_Q(A); + FP_DECL_Q(B); + FP_DECL_Q(R); TFtype r; FP_INIT_ROUNDMODE; diff --git a/soft-fp/divdf3.c b/soft-fp/divdf3.c index c3dcf80..4e7d28f 100644 --- a/soft-fp/divdf3.c +++ b/soft-fp/divdf3.c @@ -31,10 +31,13 @@ #include "soft-fp.h" #include "double.h" -DFtype __divdf3(DFtype a, DFtype b) +DFtype +__divdf3(DFtype a, DFtype b) { FP_DECL_EX; - FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R); + FP_DECL_D(A); + FP_DECL_D(B); + FP_DECL_D(R); DFtype r; FP_INIT_ROUNDMODE; diff --git a/soft-fp/divsf3.c b/soft-fp/divsf3.c index 063462f..0ed726b 100644 --- a/soft-fp/divsf3.c +++ b/soft-fp/divsf3.c @@ -31,10 +31,13 @@ #include "soft-fp.h" #include "single.h" -SFtype __divsf3(SFtype a, SFtype b) +SFtype +__divsf3(SFtype a, SFtype b) { FP_DECL_EX; - FP_DECL_S(A); FP_DECL_S(B); FP_DECL_S(R); + FP_DECL_S(A); + FP_DECL_S(B); + FP_DECL_S(R); SFtype r; FP_INIT_ROUNDMODE; diff --git a/soft-fp/divtf3.c b/soft-fp/divtf3.c index 03d017d..a255f68 100644 --- a/soft-fp/divtf3.c +++ b/soft-fp/divtf3.c @@ -31,10 +31,13 @@ #include "soft-fp.h" #include "quad.h" -TFtype __divtf3(TFtype a, TFtype b) +TFtype +__divtf3(TFtype a, TFtype b) { FP_DECL_EX; - FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(R); + FP_DECL_Q(A); + FP_DECL_Q(B); + FP_DECL_Q(R); TFtype r; FP_INIT_ROUNDMODE; diff --git a/soft-fp/double.h b/soft-fp/double.h index 3824276..4975ff4 100644 --- a/soft-fp/double.h +++ b/soft-fp/double.h @@ -73,7 +73,8 @@ typedef float DFtype __attribute__((mode(DF))); union _FP_UNION_D { DFtype flt; - struct _FP_STRUCT_LAYOUT { + struct _FP_STRUCT_LAYOUT + { # if __BYTE_ORDER == __BIG_ENDIAN unsigned sign : 1; unsigned exp : _FP_EXPBITS_D; @@ -92,61 +93,79 @@ union _FP_UNION_D # define FP_UNPACK_RAW_D(X,val) _FP_UNPACK_RAW_2(D,X,val) # define FP_UNPACK_RAW_DP(X,val) _FP_UNPACK_RAW_2_P(D,X,val) # define FP_PACK_RAW_D(val,X) _FP_PACK_RAW_2(D,val,X) -# define FP_PACK_RAW_DP(val,X) \ - do { \ - if (!FP_INHIBIT_RESULTS) \ - _FP_PACK_RAW_2_P(D,val,X); \ - } while (0) - -# define FP_UNPACK_D(X,val) \ - do { \ - _FP_UNPACK_RAW_2(D,X,val); \ - _FP_UNPACK_CANONICAL(D,2,X); \ - } while (0) - -# define FP_UNPACK_DP(X,val) \ - do { \ - _FP_UNPACK_RAW_2_P(D,X,val); \ - _FP_UNPACK_CANONICAL(D,2,X); \ - } while (0) - -# define FP_UNPACK_SEMIRAW_D(X,val) \ - do { \ - _FP_UNPACK_RAW_2(D,X,val); \ - _FP_UNPACK_SEMIRAW(D,2,X); \ - } while (0) - -# define FP_UNPACK_SEMIRAW_DP(X,val) \ - do { \ - _FP_UNPACK_RAW_2_P(D,X,val); \ - _FP_UNPACK_SEMIRAW(D,2,X); \ - } while (0) - -# define FP_PACK_D(val,X) \ - do { \ - _FP_PACK_CANONICAL(D,2,X); \ - _FP_PACK_RAW_2(D,val,X); \ - } while (0) - -# define FP_PACK_DP(val,X) \ - do { \ - _FP_PACK_CANONICAL(D,2,X); \ - if (!FP_INHIBIT_RESULTS) \ - _FP_PACK_RAW_2_P(D,val,X); \ - } while (0) - -# define FP_PACK_SEMIRAW_D(val,X) \ - do { \ - _FP_PACK_SEMIRAW(D,2,X); \ - _FP_PACK_RAW_2(D,val,X); \ - } while (0) - -# define FP_PACK_SEMIRAW_DP(val,X) \ - do { \ - _FP_PACK_SEMIRAW(D,2,X); \ - if (!FP_INHIBIT_RESULTS) \ - _FP_PACK_RAW_2_P(D,val,X); \ - } while (0) +# define FP_PACK_RAW_DP(val,X) \ + do \ + { \ + if (!FP_INHIBIT_RESULTS) \ + _FP_PACK_RAW_2_P(D,val,X); \ + } \ + while (0) + +# define FP_UNPACK_D(X,val) \ + do \ + { \ + _FP_UNPACK_RAW_2(D,X,val); \ + _FP_UNPACK_CANONICAL(D,2,X); \ + } \ + while (0) + +# define FP_UNPACK_DP(X,val) \ + do \ + { \ + _FP_UNPACK_RAW_2_P(D,X,val); \ + _FP_UNPACK_CANONICAL(D,2,X); \ + } \ + while (0) + +# define FP_UNPACK_SEMIRAW_D(X,val) \ + do \ + { \ + _FP_UNPACK_RAW_2(D,X,val); \ + _FP_UNPACK_SEMIRAW(D,2,X); \ + } \ + while (0) + +# define FP_UNPACK_SEMIRAW_DP(X,val) \ + do \ + { \ + _FP_UNPACK_RAW_2_P(D,X,val); \ + _FP_UNPACK_SEMIRAW(D,2,X); \ + } \ + while (0) + +# define FP_PACK_D(val,X) \ + do \ + { \ + _FP_PACK_CANONICAL(D,2,X); \ + _FP_PACK_RAW_2(D,val,X); \ + } \ + while (0) + +# define FP_PACK_DP(val,X) \ + do \ + { \ + _FP_PACK_CANONICAL(D,2,X); \ + if (!FP_INHIBIT_RESULTS) \ + _FP_PACK_RAW_2_P(D,val,X); \ + } \ + while (0) + +# define FP_PACK_SEMIRAW_D(val,X) \ + do \ + { \ + _FP_PACK_SEMIRAW(D,2,X); \ + _FP_PACK_RAW_2(D,val,X); \ + } \ + while (0) + +# define FP_PACK_SEMIRAW_DP(val,X) \ + do \ + { \ + _FP_PACK_SEMIRAW(D,2,X); \ + if (!FP_INHIBIT_RESULTS) \ + _FP_PACK_RAW_2_P(D,val,X); \ + } \ + while (0) # define FP_ISSIGNAN_D(X) _FP_ISSIGNAN(D,2,X) # define FP_NEG_D(R,X) _FP_NEG(D,2,R,X) @@ -175,7 +194,8 @@ union _FP_UNION_D union _FP_UNION_D { DFtype flt; - struct _FP_STRUCT_LAYOUT { + struct _FP_STRUCT_LAYOUT + { # if __BYTE_ORDER == __BIG_ENDIAN unsigned sign : 1; unsigned exp : _FP_EXPBITS_D; @@ -192,61 +212,79 @@ union _FP_UNION_D # define FP_UNPACK_RAW_D(X,val) _FP_UNPACK_RAW_1(D,X,val) # define FP_UNPACK_RAW_DP(X,val) _FP_UNPACK_RAW_1_P(D,X,val) # define FP_PACK_RAW_D(val,X) _FP_PACK_RAW_1(D,val,X) -# define FP_PACK_RAW_DP(val,X) \ - do { \ - if (!FP_INHIBIT_RESULTS) \ - _FP_PACK_RAW_1_P(D,val,X); \ - } while (0) - -# define FP_UNPACK_D(X,val) \ - do { \ - _FP_UNPACK_RAW_1(D,X,val); \ - _FP_UNPACK_CANONICAL(D,1,X); \ - } while (0) - -# define FP_UNPACK_DP(X,val) \ - do { \ - _FP_UNPACK_RAW_1_P(D,X,val); \ - _FP_UNPACK_CANONICAL(D,1,X); \ - } while (0) - -# define FP_UNPACK_SEMIRAW_D(X,val) \ - do { \ - _FP_UNPACK_RAW_1(D,X,val); \ - _FP_UNPACK_SEMIRAW(D,1,X); \ - } while (0) - -# define FP_UNPACK_SEMIRAW_DP(X,val) \ - do { \ - _FP_UNPACK_RAW_1_P(D,X,val); \ - _FP_UNPACK_SEMIRAW(D,1,X); \ - } while (0) - -# define FP_PACK_D(val,X) \ - do { \ - _FP_PACK_CANONICAL(D,1,X); \ - _FP_PACK_RAW_1(D,val,X); \ - } while (0) - -# define FP_PACK_DP(val,X) \ - do { \ - _FP_PACK_CANONICAL(D,1,X); \ - if (!FP_INHIBIT_RESULTS) \ - _FP_PACK_RAW_1_P(D,val,X); \ - } while (0) - -# define FP_PACK_SEMIRAW_D(val,X) \ - do { \ - _FP_PACK_SEMIRAW(D,1,X); \ - _FP_PACK_RAW_1(D,val,X); \ - } while (0) - -# define FP_PACK_SEMIRAW_DP(val,X) \ - do { \ - _FP_PACK_SEMIRAW(D,1,X); \ - if (!FP_INHIBIT_RESULTS) \ - _FP_PACK_RAW_1_P(D,val,X); \ - } while (0) +# define FP_PACK_RAW_DP(val,X) \ + do \ + { \ + if (!FP_INHIBIT_RESULTS) \ + _FP_PACK_RAW_1_P(D,val,X); \ + } \ + while (0) + +# define FP_UNPACK_D(X,val) \ + do \ + { \ + _FP_UNPACK_RAW_1(D,X,val); \ + _FP_UNPACK_CANONICAL(D,1,X); \ + } \ + while (0) + +# define FP_UNPACK_DP(X,val) \ + do \ + { \ + _FP_UNPACK_RAW_1_P(D,X,val); \ + _FP_UNPACK_CANONICAL(D,1,X); \ + } \ + while (0) + +# define FP_UNPACK_SEMIRAW_D(X,val) \ + do \ + { \ + _FP_UNPACK_RAW_1(D,X,val); \ + _FP_UNPACK_SEMIRAW(D,1,X); \ + } \ + while (0) + +# define FP_UNPACK_SEMIRAW_DP(X,val) \ + do \ + { \ + _FP_UNPACK_RAW_1_P(D,X,val); \ + _FP_UNPACK_SEMIRAW(D,1,X); \ + } \ + while (0) + +# define FP_PACK_D(val,X) \ + do \ + { \ + _FP_PACK_CANONICAL(D,1,X); \ + _FP_PACK_RAW_1(D,val,X); \ + } \ + while (0) + +# define FP_PACK_DP(val,X) \ + do \ + { \ + _FP_PACK_CANONICAL(D,1,X); \ + if (!FP_INHIBIT_RESULTS) \ + _FP_PACK_RAW_1_P(D,val,X); \ + } \ + while (0) + +# define FP_PACK_SEMIRAW_D(val,X) \ + do \ + { \ + _FP_PACK_SEMIRAW(D,1,X); \ + _FP_PACK_RAW_1(D,val,X); \ + } \ + while (0) + +# define FP_PACK_SEMIRAW_DP(val,X) \ + do \ + { \ + _FP_PACK_SEMIRAW(D,1,X); \ + if (!FP_INHIBIT_RESULTS) \ + _FP_PACK_RAW_1_P(D,val,X); \ + } \ + while (0) # define FP_ISSIGNAN_D(X) _FP_ISSIGNAN(D,1,X) # define FP_NEG_D(R,X) _FP_NEG(D,1,R,X) diff --git a/soft-fp/eqdf2.c b/soft-fp/eqdf2.c index 8e9408a..cc193ee 100644 --- a/soft-fp/eqdf2.c +++ b/soft-fp/eqdf2.c @@ -31,10 +31,12 @@ #include "soft-fp.h" #include "double.h" -CMPtype __eqdf2(DFtype a, DFtype b) +CMPtype +__eqdf2(DFtype a, DFtype b) { FP_DECL_EX; - FP_DECL_D(A); FP_DECL_D(B); + FP_DECL_D(A); + FP_DECL_D(B); CMPtype r; FP_INIT_EXCEPTIONS; diff --git a/soft-fp/eqsf2.c b/soft-fp/eqsf2.c index 3884b00..39901d1 100644 --- a/soft-fp/eqsf2.c +++ b/soft-fp/eqsf2.c @@ -31,10 +31,12 @@ #include "soft-fp.h" #include "single.h" -CMPtype __eqsf2(SFtype a, SFtype b) +CMPtype +__eqsf2(SFtype a, SFtype b) { FP_DECL_EX; - FP_DECL_S(A); FP_DECL_S(B); + FP_DECL_S(A); + FP_DECL_S(B); CMPtype r; FP_INIT_EXCEPTIONS; diff --git a/soft-fp/eqtf2.c b/soft-fp/eqtf2.c index 4a80375..e4ef829 100644 --- a/soft-fp/eqtf2.c +++ b/soft-fp/eqtf2.c @@ -31,10 +31,12 @@ #include "soft-fp.h" #include "quad.h" -CMPtype __eqtf2(TFtype a, TFtype b) +CMPtype +__eqtf2(TFtype a, TFtype b) { FP_DECL_EX; - FP_DECL_Q(A); FP_DECL_Q(B); + FP_DECL_Q(A); + FP_DECL_Q(B); CMPtype r; FP_INIT_EXCEPTIONS; diff --git a/soft-fp/extenddftf2.c b/soft-fp/extenddftf2.c index fd4f9dd..a57e984 100644 --- a/soft-fp/extenddftf2.c +++ b/soft-fp/extenddftf2.c @@ -32,7 +32,8 @@ #include "double.h" #include "quad.h" -TFtype __extenddftf2(DFtype a) +TFtype +__extenddftf2(DFtype a) { FP_DECL_EX; FP_DECL_D(A); diff --git a/soft-fp/extended.h b/soft-fp/extended.h index de8c20c..e030b6b 100644 --- a/soft-fp/extended.h +++ b/soft-fp/extended.h @@ -69,128 +69,157 @@ typedef float XFtype __attribute__((mode(XF))); union _FP_UNION_E { - XFtype flt; - struct _FP_STRUCT_LAYOUT - { + XFtype flt; + struct _FP_STRUCT_LAYOUT + { # if __BYTE_ORDER == __BIG_ENDIAN - unsigned long pad1 : _FP_W_TYPE_SIZE; - unsigned long pad2 : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E); - unsigned long sign : 1; - unsigned long exp : _FP_EXPBITS_E; - unsigned long frac1 : _FP_W_TYPE_SIZE; - unsigned long frac0 : _FP_W_TYPE_SIZE; + unsigned long pad1 : _FP_W_TYPE_SIZE; + unsigned long pad2 : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E); + unsigned long sign : 1; + unsigned long exp : _FP_EXPBITS_E; + unsigned long frac1 : _FP_W_TYPE_SIZE; + unsigned long frac0 : _FP_W_TYPE_SIZE; # else - unsigned long frac0 : _FP_W_TYPE_SIZE; - unsigned long frac1 : _FP_W_TYPE_SIZE; - unsigned exp : _FP_EXPBITS_E; - unsigned sign : 1; + unsigned long frac0 : _FP_W_TYPE_SIZE; + unsigned long frac1 : _FP_W_TYPE_SIZE; + unsigned exp : _FP_EXPBITS_E; + unsigned sign : 1; # endif /* not bigendian */ - } bits __attribute__((packed)); + } bits __attribute__((packed)); }; # define FP_DECL_E(X) _FP_DECL(4,X) -# define FP_UNPACK_RAW_E(X, val) \ - do { \ - union _FP_UNION_E _flo; _flo.flt = (val); \ - \ - X##_f[2] = 0; X##_f[3] = 0; \ - X##_f[0] = _flo.bits.frac0; \ - X##_f[1] = _flo.bits.frac1; \ - X##_e = _flo.bits.exp; \ - X##_s = _flo.bits.sign; \ - } while (0) - -# define FP_UNPACK_RAW_EP(X, val) \ - do { \ - union _FP_UNION_E *_flo = \ - (union _FP_UNION_E *)(val); \ - \ - X##_f[2] = 0; X##_f[3] = 0; \ - X##_f[0] = _flo->bits.frac0; \ - X##_f[1] = _flo->bits.frac1; \ - X##_e = _flo->bits.exp; \ - X##_s = _flo->bits.sign; \ - } while (0) - -# define FP_PACK_RAW_E(val, X) \ - do { \ - union _FP_UNION_E _flo; \ - \ - if (X##_e) X##_f[1] |= _FP_IMPLBIT_E; \ - else X##_f[1] &= ~(_FP_IMPLBIT_E); \ - _flo.bits.frac0 = X##_f[0]; \ - _flo.bits.frac1 = X##_f[1]; \ - _flo.bits.exp = X##_e; \ - _flo.bits.sign = X##_s; \ - \ - (val) = _flo.flt; \ - } while (0) - -# define FP_PACK_RAW_EP(val, X) \ - do { \ - if (!FP_INHIBIT_RESULTS) \ - { \ - union _FP_UNION_E *_flo = \ - (union _FP_UNION_E *)(val); \ - \ - if (X##_e) X##_f[1] |= _FP_IMPLBIT_E; \ - else X##_f[1] &= ~(_FP_IMPLBIT_E); \ - _flo->bits.frac0 = X##_f[0]; \ - _flo->bits.frac1 = X##_f[1]; \ - _flo->bits.exp = X##_e; \ - _flo->bits.sign = X##_s; \ - } \ - } while (0) - -# define FP_UNPACK_E(X,val) \ - do { \ - FP_UNPACK_RAW_E(X,val); \ - _FP_UNPACK_CANONICAL(E,4,X); \ - } while (0) - -# define FP_UNPACK_EP(X,val) \ - do { \ - FP_UNPACK_RAW_EP(X,val); \ - _FP_UNPACK_CANONICAL(E,4,X); \ - } while (0) - -# define FP_UNPACK_SEMIRAW_E(X,val) \ - do { \ - FP_UNPACK_RAW_E(X,val); \ - _FP_UNPACK_SEMIRAW(E,4,X); \ - } while (0) - -# define FP_UNPACK_SEMIRAW_EP(X,val) \ - do { \ - FP_UNPACK_RAW_EP(X,val); \ - _FP_UNPACK_SEMIRAW(E,4,X); \ - } while (0) - -# define FP_PACK_E(val,X) \ - do { \ - _FP_PACK_CANONICAL(E,4,X); \ - FP_PACK_RAW_E(val,X); \ - } while (0) - -# define FP_PACK_EP(val,X) \ - do { \ - _FP_PACK_CANONICAL(E,4,X); \ - FP_PACK_RAW_EP(val,X); \ - } while (0) - -# define FP_PACK_SEMIRAW_E(val,X) \ - do { \ - _FP_PACK_SEMIRAW(E,4,X); \ - FP_PACK_RAW_E(val,X); \ - } while (0) - -# define FP_PACK_SEMIRAW_EP(val,X) \ - do { \ - _FP_PACK_SEMIRAW(E,4,X); \ - FP_PACK_RAW_EP(val,X); \ - } while (0) +# define FP_UNPACK_RAW_E(X, val) \ + do \ + { \ + union _FP_UNION_E _flo; \ + _flo.flt = (val); \ + \ + X##_f[2] = 0; \ + X##_f[3] = 0; \ + X##_f[0] = _flo.bits.frac0; \ + X##_f[1] = _flo.bits.frac1; \ + X##_e = _flo.bits.exp; \ + X##_s = _flo.bits.sign; \ + } \ + while (0) + +# define FP_UNPACK_RAW_EP(X, val) \ + do \ + { \ + union _FP_UNION_E *_flo = (union _FP_UNION_E *)(val); \ + \ + X##_f[2] = 0; \ + X##_f[3] = 0; \ + X##_f[0] = _flo->bits.frac0; \ + X##_f[1] = _flo->bits.frac1; \ + X##_e = _flo->bits.exp; \ + X##_s = _flo->bits.sign; \ + } \ + while (0) + +# define FP_PACK_RAW_E(val, X) \ + do \ + { \ + union _FP_UNION_E _flo; \ + \ + if (X##_e) \ + X##_f[1] |= _FP_IMPLBIT_E; \ + else \ + X##_f[1] &= ~(_FP_IMPLBIT_E); \ + _flo.bits.frac0 = X##_f[0]; \ + _flo.bits.frac1 = X##_f[1]; \ + _flo.bits.exp = X##_e; \ + _flo.bits.sign = X##_s; \ + \ + (val) = _flo.flt; \ + } \ + while (0) + +# define FP_PACK_RAW_EP(val, X) \ + do \ + { \ + if (!FP_INHIBIT_RESULTS) \ + { \ + union _FP_UNION_E *_flo = (union _FP_UNION_E *)(val); \ + \ + if (X##_e) \ + X##_f[1] |= _FP_IMPLBIT_E; \ + else \ + X##_f[1] &= ~(_FP_IMPLBIT_E); \ + _flo->bits.frac0 = X##_f[0]; \ + _flo->bits.frac1 = X##_f[1]; \ + _flo->bits.exp = X##_e; \ + _flo->bits.sign = X##_s; \ + } \ + } \ + while (0) + +# define FP_UNPACK_E(X,val) \ + do \ + { \ + FP_UNPACK_RAW_E(X,val); \ + _FP_UNPACK_CANONICAL(E,4,X); \ + } \ + while (0) + +# define FP_UNPACK_EP(X,val) \ + do \ + { \ + FP_UNPACK_RAW_EP(X,val); \ + _FP_UNPACK_CANONICAL(E,4,X); \ + } \ + while (0) + +# define FP_UNPACK_SEMIRAW_E(X,val) \ + do \ + { \ + FP_UNPACK_RAW_E(X,val); \ + _FP_UNPACK_SEMIRAW(E,4,X); \ + } \ + while (0) + +# define FP_UNPACK_SEMIRAW_EP(X,val) \ + do \ + { \ + FP_UNPACK_RAW_EP(X,val); \ + _FP_UNPACK_SEMIRAW(E,4,X); \ + } \ + while (0) + +# define FP_PACK_E(val,X) \ + do \ + { \ + _FP_PACK_CANONICAL(E,4,X); \ + FP_PACK_RAW_E(val,X); \ + } \ + while (0) + +# define FP_PACK_EP(val,X) \ + do \ + { \ + _FP_PACK_CANONICAL(E,4,X); \ + FP_PACK_RAW_EP(val,X); \ + } \ + while (0) + +# define FP_PACK_SEMIRAW_E(val,X) \ + do \ + { \ + _FP_PACK_SEMIRAW(E,4,X); \ + FP_PACK_RAW_E(val,X); \ + } \ + while (0) + +# define FP_PACK_SEMIRAW_EP(val,X) \ + do \ + { \ + _FP_PACK_SEMIRAW(E,4,X); \ + FP_PACK_RAW_EP(val,X); \ + } \ + while (0) # define FP_ISSIGNAN_E(X) _FP_ISSIGNAN(E,4,X) # define FP_NEG_E(R,X) _FP_NEG(E,4,R,X) @@ -213,48 +242,50 @@ union _FP_UNION_E */ # define _FP_SQRT_MEAT_E(R, S, T, X, q) \ - do { \ - q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ - _FP_FRAC_SRL_4(X, (_FP_WORKBITS)); \ - while (q) \ - { \ - T##_f[1] = S##_f[1] + q; \ - if (T##_f[1] <= X##_f[1]) \ - { \ - S##_f[1] = T##_f[1] + q; \ - X##_f[1] -= T##_f[1]; \ - R##_f[1] += q; \ - } \ - _FP_FRAC_SLL_2(X, 1); \ - q >>= 1; \ - } \ - q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ - while (q) \ - { \ - T##_f[0] = S##_f[0] + q; \ - T##_f[1] = S##_f[1]; \ - if (T##_f[1] < X##_f[1] || \ - (T##_f[1] == X##_f[1] && \ - T##_f[0] <= X##_f[0])) \ - { \ - S##_f[0] = T##_f[0] + q; \ - S##_f[1] += (T##_f[0] > S##_f[0]); \ - _FP_FRAC_DEC_2(X, T); \ - R##_f[0] += q; \ - } \ - _FP_FRAC_SLL_2(X, 1); \ - q >>= 1; \ - } \ - _FP_FRAC_SLL_4(R, (_FP_WORKBITS)); \ - if (X##_f[0] | X##_f[1]) \ - { \ - if (S##_f[1] < X##_f[1] || \ - (S##_f[1] == X##_f[1] && \ - S##_f[0] < X##_f[0])) \ - R##_f[0] |= _FP_WORK_ROUND; \ - R##_f[0] |= _FP_WORK_STICKY; \ - } \ - } while (0) + do \ + { \ + q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ + _FP_FRAC_SRL_4(X, (_FP_WORKBITS)); \ + while (q) \ + { \ + T##_f[1] = S##_f[1] + q; \ + if (T##_f[1] <= X##_f[1]) \ + { \ + S##_f[1] = T##_f[1] + q; \ + X##_f[1] -= T##_f[1]; \ + R##_f[1] += q; \ + } \ + _FP_FRAC_SLL_2(X, 1); \ + q >>= 1; \ + } \ + q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ + while (q) \ + { \ + T##_f[0] = S##_f[0] + q; \ + T##_f[1] = S##_f[1]; \ + if (T##_f[1] < X##_f[1] \ + || (T##_f[1] == X##_f[1] \ + && T##_f[0] <= X##_f[0])) \ + { \ + S##_f[0] = T##_f[0] + q; \ + S##_f[1] += (T##_f[0] > S##_f[0]); \ + _FP_FRAC_DEC_2(X, T); \ + R##_f[0] += q; \ + } \ + _FP_FRAC_SLL_2(X, 1); \ + q >>= 1; \ + } \ + _FP_FRAC_SLL_4(R, (_FP_WORKBITS)); \ + if (X##_f[0] | X##_f[1]) \ + { \ + if (S##_f[1] < X##_f[1] \ + || (S##_f[1] == X##_f[1] \ + && S##_f[0] < X##_f[0])) \ + R##_f[0] |= _FP_WORK_ROUND; \ + R##_f[0] |= _FP_WORK_STICKY; \ + } \ + } \ + while (0) # define FP_CMP_E(r,X,Y,un) _FP_CMP(E,4,r,X,Y,un) # define FP_CMP_EQ_E(r,X,Y) _FP_CMP_EQ(E,4,r,X,Y) @@ -272,7 +303,8 @@ union _FP_UNION_E union _FP_UNION_E { XFtype flt; - struct _FP_STRUCT_LAYOUT { + struct _FP_STRUCT_LAYOUT + { # if __BYTE_ORDER == __BIG_ENDIAN _FP_W_TYPE pad : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E); unsigned sign : 1; @@ -288,103 +320,130 @@ union _FP_UNION_E # define FP_DECL_E(X) _FP_DECL(2,X) -# define FP_UNPACK_RAW_E(X, val) \ - do { \ - union _FP_UNION_E _flo; _flo.flt = (val); \ - \ - X##_f0 = _flo.bits.frac; \ - X##_f1 = 0; \ - X##_e = _flo.bits.exp; \ - X##_s = _flo.bits.sign; \ - } while (0) +# define FP_UNPACK_RAW_E(X, val) \ + do \ + { \ + union _FP_UNION_E _flo; \ + _flo.flt = (val); \ + \ + X##_f0 = _flo.bits.frac; \ + X##_f1 = 0; \ + X##_e = _flo.bits.exp; \ + X##_s = _flo.bits.sign; \ + } \ + while (0) # define FP_UNPACK_RAW_EP(X, val) \ - do { \ - union _FP_UNION_E *_flo = \ - (union _FP_UNION_E *)(val); \ - \ - X##_f0 = _flo->bits.frac; \ - X##_f1 = 0; \ - X##_e = _flo->bits.exp; \ - X##_s = _flo->bits.sign; \ - } while (0) - -# define FP_PACK_RAW_E(val, X) \ - do { \ - union _FP_UNION_E _flo; \ - \ - if (X##_e) X##_f0 |= _FP_IMPLBIT_E; \ - else X##_f0 &= ~(_FP_IMPLBIT_E); \ - _flo.bits.frac = X##_f0; \ - _flo.bits.exp = X##_e; \ - _flo.bits.sign = X##_s; \ + do \ + { \ + union _FP_UNION_E *_flo = (union _FP_UNION_E *)(val); \ \ - (val) = _flo.flt; \ - } while (0) + X##_f0 = _flo->bits.frac; \ + X##_f1 = 0; \ + X##_e = _flo->bits.exp; \ + X##_s = _flo->bits.sign; \ + } \ + while (0) + +# define FP_PACK_RAW_E(val, X) \ + do \ + { \ + union _FP_UNION_E _flo; \ + \ + if (X##_e) \ + X##_f0 |= _FP_IMPLBIT_E; \ + else \ + X##_f0 &= ~(_FP_IMPLBIT_E); \ + _flo.bits.frac = X##_f0; \ + _flo.bits.exp = X##_e; \ + _flo.bits.sign = X##_s; \ + \ + (val) = _flo.flt; \ + } \ + while (0) # define FP_PACK_RAW_EP(fs, val, X) \ - do { \ - if (!FP_INHIBIT_RESULTS) \ - { \ - union _FP_UNION_E *_flo = \ - (union _FP_UNION_E *)(val); \ + do \ + { \ + if (!FP_INHIBIT_RESULTS) \ + { \ + union _FP_UNION_E *_flo = (union _FP_UNION_E *)(val); \ \ - if (X##_e) X##_f0 |= _FP_IMPLBIT_E; \ - else X##_f0 &= ~(_FP_IMPLBIT_E); \ - _flo->bits.frac = X##_f0; \ - _flo->bits.exp = X##_e; \ - _flo->bits.sign = X##_s; \ - } \ - } while (0) - - -# define FP_UNPACK_E(X,val) \ - do { \ - FP_UNPACK_RAW_E(X,val); \ - _FP_UNPACK_CANONICAL(E,2,X); \ - } while (0) - -# define FP_UNPACK_EP(X,val) \ - do { \ - FP_UNPACK_RAW_EP(X,val); \ - _FP_UNPACK_CANONICAL(E,2,X); \ - } while (0) - -# define FP_UNPACK_SEMIRAW_E(X,val) \ - do { \ - FP_UNPACK_RAW_E(X,val); \ - _FP_UNPACK_SEMIRAW(E,2,X); \ - } while (0) - -# define FP_UNPACK_SEMIRAW_EP(X,val) \ - do { \ - FP_UNPACK_RAW_EP(X,val); \ - _FP_UNPACK_SEMIRAW(E,2,X); \ - } while (0) - -# define FP_PACK_E(val,X) \ - do { \ - _FP_PACK_CANONICAL(E,2,X); \ - FP_PACK_RAW_E(val,X); \ - } while (0) - -# define FP_PACK_EP(val,X) \ - do { \ - _FP_PACK_CANONICAL(E,2,X); \ - FP_PACK_RAW_EP(val,X); \ - } while (0) - -# define FP_PACK_SEMIRAW_E(val,X) \ - do { \ - _FP_PACK_SEMIRAW(E,2,X); \ - FP_PACK_RAW_E(val,X); \ - } while (0) - -# define FP_PACK_SEMIRAW_EP(val,X) \ - do { \ - _FP_PACK_SEMIRAW(E,2,X); \ - FP_PACK_RAW_EP(val,X); \ - } while (0) + if (X##_e) \ + X##_f0 |= _FP_IMPLBIT_E; \ + else \ + X##_f0 &= ~(_FP_IMPLBIT_E); \ + _flo->bits.frac = X##_f0; \ + _flo->bits.exp = X##_e; \ + _flo->bits.sign = X##_s; \ + } \ + } \ + while (0) + + +# define FP_UNPACK_E(X,val) \ + do \ + { \ + FP_UNPACK_RAW_E(X,val); \ + _FP_UNPACK_CANONICAL(E,2,X); \ + } \ + while (0) + +# define FP_UNPACK_EP(X,val) \ + do \ + { \ + FP_UNPACK_RAW_EP(X,val); \ + _FP_UNPACK_CANONICAL(E,2,X); \ + } \ + while (0) + +# define FP_UNPACK_SEMIRAW_E(X,val) \ + do \ + { \ + FP_UNPACK_RAW_E(X,val); \ + _FP_UNPACK_SEMIRAW(E,2,X); \ + } \ + while (0) + +# define FP_UNPACK_SEMIRAW_EP(X,val) \ + do \ + { \ + FP_UNPACK_RAW_EP(X,val); \ + _FP_UNPACK_SEMIRAW(E,2,X); \ + } \ + while (0) + +# define FP_PACK_E(val,X) \ + do \ + { \ + _FP_PACK_CANONICAL(E,2,X); \ + FP_PACK_RAW_E(val,X); \ + } \ + while (0) + +# define FP_PACK_EP(val,X) \ + do \ + { \ + _FP_PACK_CANONICAL(E,2,X); \ + FP_PACK_RAW_EP(val,X); \ + } \ + while (0) + +# define FP_PACK_SEMIRAW_E(val,X) \ + do \ + { \ + _FP_PACK_SEMIRAW(E,2,X); \ + FP_PACK_RAW_E(val,X); \ + } \ + while (0) + +# define FP_PACK_SEMIRAW_EP(val,X) \ + do \ + { \ + _FP_PACK_SEMIRAW(E,2,X); \ + FP_PACK_RAW_EP(val,X); \ + } \ + while (0) # define FP_ISSIGNAN_E(X) _FP_ISSIGNAN(E,2,X) # define FP_NEG_E(R,X) _FP_NEG(E,2,R,X) @@ -404,29 +463,31 @@ union _FP_UNION_E * have to. */ # define _FP_SQRT_MEAT_E(R, S, T, X, q) \ - do { \ - q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ - _FP_FRAC_SRL_2(X, (_FP_WORKBITS)); \ - while (q) \ - { \ - T##_f0 = S##_f0 + q; \ - if (T##_f0 <= X##_f0) \ - { \ - S##_f0 = T##_f0 + q; \ - X##_f0 -= T##_f0; \ - R##_f0 += q; \ - } \ - _FP_FRAC_SLL_1(X, 1); \ - q >>= 1; \ - } \ - _FP_FRAC_SLL_2(R, (_FP_WORKBITS)); \ - if (X##_f0) \ - { \ - if (S##_f0 < X##_f0) \ - R##_f0 |= _FP_WORK_ROUND; \ - R##_f0 |= _FP_WORK_STICKY; \ - } \ - } while (0) + do \ + { \ + q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ + _FP_FRAC_SRL_2(X, (_FP_WORKBITS)); \ + while (q) \ + { \ + T##_f0 = S##_f0 + q; \ + if (T##_f0 <= X##_f0) \ + { \ + S##_f0 = T##_f0 + q; \ + X##_f0 -= T##_f0; \ + R##_f0 += q; \ + } \ + _FP_FRAC_SLL_1(X, 1); \ + q >>= 1; \ + } \ + _FP_FRAC_SLL_2(R, (_FP_WORKBITS)); \ + if (X##_f0) \ + { \ + if (S##_f0 < X##_f0) \ + R##_f0 |= _FP_WORK_ROUND; \ + R##_f0 |= _FP_WORK_STICKY; \ + } \ + } \ + while (0) # define FP_CMP_E(r,X,Y,un) _FP_CMP(E,2,r,X,Y,un) # define FP_CMP_EQ_E(r,X,Y) _FP_CMP_EQ(E,2,r,X,Y) diff --git a/soft-fp/extendsfdf2.c b/soft-fp/extendsfdf2.c index 614da79..08affea 100644 --- a/soft-fp/extendsfdf2.c +++ b/soft-fp/extendsfdf2.c @@ -32,7 +32,8 @@ #include "single.h" #include "double.h" -DFtype __extendsfdf2(SFtype a) +DFtype +__extendsfdf2(SFtype a) { FP_DECL_EX; FP_DECL_S(A); diff --git a/soft-fp/extendsftf2.c b/soft-fp/extendsftf2.c index b1ab593..b5dafe8 100644 --- a/soft-fp/extendsftf2.c +++ b/soft-fp/extendsftf2.c @@ -32,7 +32,8 @@ #include "single.h" #include "quad.h" -TFtype __extendsftf2(SFtype a) +TFtype +__extendsftf2(SFtype a) { FP_DECL_EX; FP_DECL_S(A); diff --git a/soft-fp/extendxftf2.c b/soft-fp/extendxftf2.c index a389636..40eaaec 100644 --- a/soft-fp/extendxftf2.c +++ b/soft-fp/extendxftf2.c @@ -31,7 +31,8 @@ #include "extended.h" #include "quad.h" -TFtype __extendxftf2(XFtype a) +TFtype +__extendxftf2(XFtype a) { FP_DECL_EX; FP_DECL_E(A); diff --git a/soft-fp/fixdfdi.c b/soft-fp/fixdfdi.c index c426018..617c2c9 100644 --- a/soft-fp/fixdfdi.c +++ b/soft-fp/fixdfdi.c @@ -31,7 +31,8 @@ #include "soft-fp.h" #include "double.h" -DItype __fixdfdi(DFtype a) +DItype +__fixdfdi(DFtype a) { FP_DECL_EX; FP_DECL_D(A); diff --git a/soft-fp/fixdfsi.c b/soft-fp/fixdfsi.c index 97f9afe..78f8afa 100644 --- a/soft-fp/fixdfsi.c +++ b/soft-fp/fixdfsi.c @@ -31,7 +31,8 @@ #include "soft-fp.h" #include "double.h" -SItype __fixdfsi(DFtype a) +SItype +__fixdfsi(DFtype a) { FP_DECL_EX; FP_DECL_D(A); diff --git a/soft-fp/fixdfti.c b/soft-fp/fixdfti.c index 0b82377..8d27cd5 100644 --- a/soft-fp/fixdfti.c +++ b/soft-fp/fixdfti.c @@ -30,7 +30,8 @@ #include "soft-fp.h" #include "double.h" -TItype __fixdfti(DFtype a) +TItype +__fixdfti(DFtype a) { FP_DECL_EX; FP_DECL_D(A); diff --git a/soft-fp/fixsfdi.c b/soft-fp/fixsfdi.c index 564b96c..c34bec5 100644 --- a/soft-fp/fixsfdi.c +++ b/soft-fp/fixsfdi.c @@ -31,7 +31,8 @@ #include "soft-fp.h" #include "single.h" -DItype __fixsfdi(SFtype a) +DItype +__fixsfdi(SFtype a) { FP_DECL_EX; FP_DECL_S(A); diff --git a/soft-fp/fixsfsi.c b/soft-fp/fixsfsi.c index a82bdf3..2e28794 100644 --- a/soft-fp/fixsfsi.c +++ b/soft-fp/fixsfsi.c @@ -31,7 +31,8 @@ #include "soft-fp.h" #include "single.h" -SItype __fixsfsi(SFtype a) +SItype +__fixsfsi(SFtype a) { FP_DECL_EX; FP_DECL_S(A); diff --git a/soft-fp/fixsfti.c b/soft-fp/fixsfti.c index 84f898b..91efb52 100644 --- a/soft-fp/fixsfti.c +++ b/soft-fp/fixsfti.c @@ -30,7 +30,8 @@ #include "soft-fp.h" #include "single.h" -TItype __fixsfti(SFtype a) +TItype +__fixsfti(SFtype a) { FP_DECL_EX; FP_DECL_S(A); diff --git a/soft-fp/fixtfdi.c b/soft-fp/fixtfdi.c index 0b3711a..2a6814e 100644 --- a/soft-fp/fixtfdi.c +++ b/soft-fp/fixtfdi.c @@ -31,7 +31,8 @@ #include "soft-fp.h" #include "quad.h" -DItype __fixtfdi(TFtype a) +DItype +__fixtfdi(TFtype a) { FP_DECL_EX; FP_DECL_Q(A); diff --git a/soft-fp/fixtfsi.c b/soft-fp/fixtfsi.c index 320c066..e2096cb 100644 --- a/soft-fp/fixtfsi.c +++ b/soft-fp/fixtfsi.c @@ -31,7 +31,8 @@ #include "soft-fp.h" #include "quad.h" -SItype __fixtfsi(TFtype a) +SItype +__fixtfsi(TFtype a) { FP_DECL_EX; FP_DECL_Q(A); diff --git a/soft-fp/fixtfti.c b/soft-fp/fixtfti.c index f65d739..2fd65a0 100644 --- a/soft-fp/fixtfti.c +++ b/soft-fp/fixtfti.c @@ -30,7 +30,8 @@ #include "soft-fp.h" #include "quad.h" -TItype __fixtfti(TFtype a) +TItype +__fixtfti(TFtype a) { FP_DECL_EX; FP_DECL_Q(A); diff --git a/soft-fp/fixunsdfdi.c b/soft-fp/fixunsdfdi.c index 22f9739..ae4e5f5 100644 --- a/soft-fp/fixunsdfdi.c +++ b/soft-fp/fixunsdfdi.c @@ -31,7 +31,8 @@ #include "soft-fp.h" #include "double.h" -UDItype __fixunsdfdi(DFtype a) +UDItype +__fixunsdfdi(DFtype a) { FP_DECL_EX; FP_DECL_D(A); diff --git a/soft-fp/fixunsdfsi.c b/soft-fp/fixunsdfsi.c index fad5e35..09a0c76 100644 --- a/soft-fp/fixunsdfsi.c +++ b/soft-fp/fixunsdfsi.c @@ -31,7 +31,8 @@ #include "soft-fp.h" #include "double.h" -USItype __fixunsdfsi(DFtype a) +USItype +__fixunsdfsi(DFtype a) { FP_DECL_EX; FP_DECL_D(A); diff --git a/soft-fp/fixunsdfti.c b/soft-fp/fixunsdfti.c index 653f3ee..f3370c6 100644 --- a/soft-fp/fixunsdfti.c +++ b/soft-fp/fixunsdfti.c @@ -30,7 +30,8 @@ #include "soft-fp.h" #include "double.h" -UTItype __fixunsdfti(DFtype a) +UTItype +__fixunsdfti(DFtype a) { FP_DECL_EX; FP_DECL_D(A); diff --git a/soft-fp/fixunssfdi.c b/soft-fp/fixunssfdi.c index 4d6b91c..9560767 100644 --- a/soft-fp/fixunssfdi.c +++ b/soft-fp/fixunssfdi.c @@ -31,7 +31,8 @@ #include "soft-fp.h" #include "single.h" -UDItype __fixunssfdi(SFtype a) +UDItype +__fixunssfdi(SFtype a) { FP_DECL_EX; FP_DECL_S(A); diff --git a/soft-fp/fixunssfsi.c b/soft-fp/fixunssfsi.c index 8d4ed89..3e56d54 100644 --- a/soft-fp/fixunssfsi.c +++ b/soft-fp/fixunssfsi.c @@ -31,7 +31,8 @@ #include "soft-fp.h" #include "single.h" -USItype __fixunssfsi(SFtype a) +USItype +__fixunssfsi(SFtype a) { FP_DECL_EX; FP_DECL_S(A); diff --git a/soft-fp/fixunssfti.c b/soft-fp/fixunssfti.c index 20b07e9..694f7e4 100644 --- a/soft-fp/fixunssfti.c +++ b/soft-fp/fixunssfti.c @@ -30,7 +30,8 @@ #include "soft-fp.h" #include "single.h" -UTItype __fixunssfti(SFtype a) +UTItype +__fixunssfti(SFtype a) { FP_DECL_EX; FP_DECL_S(A); diff --git a/soft-fp/fixunstfdi.c b/soft-fp/fixunstfdi.c index 4f6c2f8..d4a0b7d 100644 --- a/soft-fp/fixunstfdi.c +++ b/soft-fp/fixunstfdi.c @@ -31,7 +31,8 @@ #include "soft-fp.h" #include "quad.h" -UDItype __fixunstfdi(TFtype a) +UDItype +__fixunstfdi(TFtype a) { FP_DECL_EX; FP_DECL_Q(A); diff --git a/soft-fp/fixunstfsi.c b/soft-fp/fixunstfsi.c index 801009c..47d51b0 100644 --- a/soft-fp/fixunstfsi.c +++ b/soft-fp/fixunstfsi.c @@ -31,7 +31,8 @@ #include "soft-fp.h" #include "quad.h" -USItype __fixunstfsi(TFtype a) +USItype +__fixunstfsi(TFtype a) { FP_DECL_EX; FP_DECL_Q(A); diff --git a/soft-fp/fixunstfti.c b/soft-fp/fixunstfti.c index 1a959aa..6dd8697 100644 --- a/soft-fp/fixunstfti.c +++ b/soft-fp/fixunstfti.c @@ -30,7 +30,8 @@ #include "soft-fp.h" #include "quad.h" -UTItype __fixunstfti(TFtype a) +UTItype +__fixunstfti(TFtype a) { FP_DECL_EX; FP_DECL_Q(A); diff --git a/soft-fp/floatdidf.c b/soft-fp/floatdidf.c index 70082e1..4413e68 100644 --- a/soft-fp/floatdidf.c +++ b/soft-fp/floatdidf.c @@ -31,7 +31,8 @@ #include "soft-fp.h" #include "double.h" -DFtype __floatdidf(DItype i) +DFtype +__floatdidf(DItype i) { FP_DECL_EX; FP_DECL_D(A); diff --git a/soft-fp/floatdisf.c b/soft-fp/floatdisf.c index 4a93793..2b54d1f 100644 --- a/soft-fp/floatdisf.c +++ b/soft-fp/floatdisf.c @@ -31,7 +31,8 @@ #include "soft-fp.h" #include "single.h" -SFtype __floatdisf(DItype i) +SFtype +__floatdisf(DItype i) { FP_DECL_EX; FP_DECL_S(A); diff --git a/soft-fp/floatditf.c b/soft-fp/floatditf.c index 7f5e3b0..760183f 100644 --- a/soft-fp/floatditf.c +++ b/soft-fp/floatditf.c @@ -32,7 +32,8 @@ #include "soft-fp.h" #include "quad.h" -TFtype __floatditf(DItype i) +TFtype +__floatditf(DItype i) { FP_DECL_Q(A); TFtype a; diff --git a/soft-fp/floatsidf.c b/soft-fp/floatsidf.c index 967a83f..04cc2e2 100644 --- a/soft-fp/floatsidf.c +++ b/soft-fp/floatsidf.c @@ -32,7 +32,8 @@ #include "soft-fp.h" #include "double.h" -DFtype __floatsidf(SItype i) +DFtype +__floatsidf(SItype i) { FP_DECL_D(A); DFtype a; diff --git a/soft-fp/floatsisf.c b/soft-fp/floatsisf.c index b4afb9f..d22c733 100644 --- a/soft-fp/floatsisf.c +++ b/soft-fp/floatsisf.c @@ -31,7 +31,8 @@ #include "soft-fp.h" #include "single.h" -SFtype __floatsisf(SItype i) +SFtype +__floatsisf(SItype i) { FP_DECL_EX; FP_DECL_S(A); diff --git a/soft-fp/floatsitf.c b/soft-fp/floatsitf.c index a2c3451..d5f107f 100644 --- a/soft-fp/floatsitf.c +++ b/soft-fp/floatsitf.c @@ -32,7 +32,8 @@ #include "soft-fp.h" #include "quad.h" -TFtype __floatsitf(SItype i) +TFtype +__floatsitf(SItype i) { FP_DECL_Q(A); TFtype a; diff --git a/soft-fp/floattidf.c b/soft-fp/floattidf.c index aad11cb..004fab4 100644 --- a/soft-fp/floattidf.c +++ b/soft-fp/floattidf.c @@ -30,7 +30,8 @@ #include "soft-fp.h" #include "double.h" -DFtype __floattidf(TItype i) +DFtype +__floattidf(TItype i) { FP_DECL_EX; FP_DECL_D(A); diff --git a/soft-fp/floattisf.c b/soft-fp/floattisf.c index dd932af..929da42 100644 --- a/soft-fp/floattisf.c +++ b/soft-fp/floattisf.c @@ -30,7 +30,8 @@ #include "soft-fp.h" #include "single.h" -SFtype __floattisf(TItype i) +SFtype +__floattisf(TItype i) { FP_DECL_EX; FP_DECL_S(A); diff --git a/soft-fp/floattitf.c b/soft-fp/floattitf.c index 40e66b3..1952a85 100644 --- a/soft-fp/floattitf.c +++ b/soft-fp/floattitf.c @@ -30,7 +30,8 @@ #include "soft-fp.h" #include "quad.h" -TFtype __floattitf(TItype i) +TFtype +__floattitf(TItype i) { FP_DECL_EX; FP_DECL_Q(A); diff --git a/soft-fp/floatundidf.c b/soft-fp/floatundidf.c index 53877c2..f40457b 100644 --- a/soft-fp/floatundidf.c +++ b/soft-fp/floatundidf.c @@ -31,7 +31,8 @@ #include "soft-fp.h" #include "double.h" -DFtype __floatundidf(UDItype i) +DFtype +__floatundidf(UDItype i) { FP_DECL_EX; FP_DECL_D(A); diff --git a/soft-fp/floatundisf.c b/soft-fp/floatundisf.c index cec4b0d..51b69e6 100644 --- a/soft-fp/floatundisf.c +++ b/soft-fp/floatundisf.c @@ -31,7 +31,8 @@ #include "soft-fp.h" #include "single.h" -SFtype __floatundisf(UDItype i) +SFtype +__floatundisf(UDItype i) { FP_DECL_EX; FP_DECL_S(A); diff --git a/soft-fp/floatunsidf.c b/soft-fp/floatunsidf.c index 3d9656f..d9d3b5b 100644 --- a/soft-fp/floatunsidf.c +++ b/soft-fp/floatunsidf.c @@ -32,7 +32,8 @@ #include "soft-fp.h" #include "double.h" -DFtype __floatunsidf(USItype i) +DFtype +__floatunsidf(USItype i) { FP_DECL_D(A); DFtype a; diff --git a/soft-fp/floatunsisf.c b/soft-fp/floatunsisf.c index 0a694f6..eb81ea0 100644 --- a/soft-fp/floatunsisf.c +++ b/soft-fp/floatunsisf.c @@ -31,7 +31,8 @@ #include "soft-fp.h" #include "single.h" -SFtype __floatunsisf(USItype i) +SFtype +__floatunsisf(USItype i) { FP_DECL_EX; FP_DECL_S(A); diff --git a/soft-fp/floatuntidf.c b/soft-fp/floatuntidf.c index ec9a41c..f9654ba 100644 --- a/soft-fp/floatuntidf.c +++ b/soft-fp/floatuntidf.c @@ -30,7 +30,8 @@ #include "soft-fp.h" #include "double.h" -DFtype __floatuntidf(UTItype i) +DFtype +__floatuntidf(UTItype i) { FP_DECL_EX; FP_DECL_D(A); diff --git a/soft-fp/floatuntisf.c b/soft-fp/floatuntisf.c index d70b025..d690e73 100644 --- a/soft-fp/floatuntisf.c +++ b/soft-fp/floatuntisf.c @@ -30,7 +30,8 @@ #include "soft-fp.h" #include "single.h" -SFtype __floatuntisf(UTItype i) +SFtype +__floatuntisf(UTItype i) { FP_DECL_EX; FP_DECL_S(A); diff --git a/soft-fp/floatuntitf.c b/soft-fp/floatuntitf.c index ee278eb..0c04b05 100644 --- a/soft-fp/floatuntitf.c +++ b/soft-fp/floatuntitf.c @@ -30,7 +30,8 @@ #include "soft-fp.h" #include "quad.h" -TFtype __floatuntitf(UTItype i) +TFtype +__floatuntitf(UTItype i) { FP_DECL_EX; FP_DECL_Q(A); diff --git a/soft-fp/fmadf4.c b/soft-fp/fmadf4.c index ebdc2b1..bc02756 100644 --- a/soft-fp/fmadf4.c +++ b/soft-fp/fmadf4.c @@ -33,7 +33,10 @@ double __fma (double a, double b, double c) { FP_DECL_EX; - FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(C); FP_DECL_D(R); + FP_DECL_D(A); + FP_DECL_D(B); + FP_DECL_D(C); + FP_DECL_D(R); double r; FP_INIT_ROUNDMODE; diff --git a/soft-fp/fmasf4.c b/soft-fp/fmasf4.c index e8d60fb..fbf7e78 100644 --- a/soft-fp/fmasf4.c +++ b/soft-fp/fmasf4.c @@ -33,7 +33,10 @@ float __fmaf (float a, float b, float c) { FP_DECL_EX; - FP_DECL_S(A); FP_DECL_S(B); FP_DECL_S(C); FP_DECL_S(R); + FP_DECL_S(A); + FP_DECL_S(B); + FP_DECL_S(C); + FP_DECL_S(R); float r; FP_INIT_ROUNDMODE; diff --git a/soft-fp/fmatf4.c b/soft-fp/fmatf4.c index cf48988..c96ab65 100644 --- a/soft-fp/fmatf4.c +++ b/soft-fp/fmatf4.c @@ -33,7 +33,10 @@ long double __fmal (long double a, long double b, long double c) { FP_DECL_EX; - FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C); FP_DECL_Q(R); + FP_DECL_Q(A); + FP_DECL_Q(B); + FP_DECL_Q(C); + FP_DECL_Q(R); long double r; FP_INIT_ROUNDMODE; diff --git a/soft-fp/gedf2.c b/soft-fp/gedf2.c index fa2b525..6445c15 100644 --- a/soft-fp/gedf2.c +++ b/soft-fp/gedf2.c @@ -31,10 +31,12 @@ #include "soft-fp.h" #include "double.h" -CMPtype __gedf2(DFtype a, DFtype b) +CMPtype +__gedf2(DFtype a, DFtype b) { FP_DECL_EX; - FP_DECL_D(A); FP_DECL_D(B); + FP_DECL_D(A); + FP_DECL_D(B); CMPtype r; FP_INIT_EXCEPTIONS; diff --git a/soft-fp/gesf2.c b/soft-fp/gesf2.c index 4778937..96a06e9 100644 --- a/soft-fp/gesf2.c +++ b/soft-fp/gesf2.c @@ -31,10 +31,12 @@ #include "soft-fp.h" #include "single.h" -CMPtype __gesf2(SFtype a, SFtype b) +CMPtype +__gesf2(SFtype a, SFtype b) { FP_DECL_EX; - FP_DECL_S(A); FP_DECL_S(B); + FP_DECL_S(A); + FP_DECL_S(B); CMPtype r; FP_INIT_EXCEPTIONS; diff --git a/soft-fp/getf2.c b/soft-fp/getf2.c index 4c544d4..579ce64 100644 --- a/soft-fp/getf2.c +++ b/soft-fp/getf2.c @@ -31,10 +31,12 @@ #include "soft-fp.h" #include "quad.h" -CMPtype __getf2(TFtype a, TFtype b) +CMPtype +__getf2(TFtype a, TFtype b) { FP_DECL_EX; - FP_DECL_Q(A); FP_DECL_Q(B); + FP_DECL_Q(A); + FP_DECL_Q(B); CMPtype r; FP_INIT_EXCEPTIONS; diff --git a/soft-fp/ledf2.c b/soft-fp/ledf2.c index 7d54e98..abf53d9 100644 --- a/soft-fp/ledf2.c +++ b/soft-fp/ledf2.c @@ -31,10 +31,12 @@ #include "soft-fp.h" #include "double.h" -CMPtype __ledf2(DFtype a, DFtype b) +CMPtype +__ledf2(DFtype a, DFtype b) { FP_DECL_EX; - FP_DECL_D(A); FP_DECL_D(B); + FP_DECL_D(A); + FP_DECL_D(B); CMPtype r; FP_INIT_EXCEPTIONS; diff --git a/soft-fp/lesf2.c b/soft-fp/lesf2.c index 954a418..9f18e69 100644 --- a/soft-fp/lesf2.c +++ b/soft-fp/lesf2.c @@ -31,10 +31,12 @@ #include "soft-fp.h" #include "single.h" -CMPtype __lesf2(SFtype a, SFtype b) +CMPtype +__lesf2(SFtype a, SFtype b) { FP_DECL_EX; - FP_DECL_S(A); FP_DECL_S(B); + FP_DECL_S(A); + FP_DECL_S(B); CMPtype r; FP_INIT_EXCEPTIONS; diff --git a/soft-fp/letf2.c b/soft-fp/letf2.c index 76d6119..028bdd2 100644 --- a/soft-fp/letf2.c +++ b/soft-fp/letf2.c @@ -31,10 +31,12 @@ #include "soft-fp.h" #include "quad.h" -CMPtype __letf2(TFtype a, TFtype b) +CMPtype +__letf2(TFtype a, TFtype b) { FP_DECL_EX; - FP_DECL_Q(A); FP_DECL_Q(B); + FP_DECL_Q(A); + FP_DECL_Q(B); CMPtype r; FP_INIT_EXCEPTIONS; diff --git a/soft-fp/muldf3.c b/soft-fp/muldf3.c index 8c08281..96e6a3b 100644 --- a/soft-fp/muldf3.c +++ b/soft-fp/muldf3.c @@ -31,10 +31,13 @@ #include "soft-fp.h" #include "double.h" -DFtype __muldf3(DFtype a, DFtype b) +DFtype +__muldf3(DFtype a, DFtype b) { FP_DECL_EX; - FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R); + FP_DECL_D(A); + FP_DECL_D(B); + FP_DECL_D(R); DFtype r; FP_INIT_ROUNDMODE; diff --git a/soft-fp/mulsf3.c b/soft-fp/mulsf3.c index f0341a5..b602f21 100644 --- a/soft-fp/mulsf3.c +++ b/soft-fp/mulsf3.c @@ -31,10 +31,13 @@ #include "soft-fp.h" #include "single.h" -SFtype __mulsf3(SFtype a, SFtype b) +SFtype +__mulsf3(SFtype a, SFtype b) { FP_DECL_EX; - FP_DECL_S(A); FP_DECL_S(B); FP_DECL_S(R); + FP_DECL_S(A); + FP_DECL_S(B); + FP_DECL_S(R); SFtype r; FP_INIT_ROUNDMODE; diff --git a/soft-fp/multf3.c b/soft-fp/multf3.c index 35badf2..9b898e2 100644 --- a/soft-fp/multf3.c +++ b/soft-fp/multf3.c @@ -31,10 +31,13 @@ #include "soft-fp.h" #include "quad.h" -TFtype __multf3(TFtype a, TFtype b) +TFtype +__multf3(TFtype a, TFtype b) { FP_DECL_EX; - FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(R); + FP_DECL_Q(A); + FP_DECL_Q(B); + FP_DECL_Q(R); TFtype r; FP_INIT_ROUNDMODE; diff --git a/soft-fp/negdf2.c b/soft-fp/negdf2.c index 1dedc71..c1b858b 100644 --- a/soft-fp/negdf2.c +++ b/soft-fp/negdf2.c @@ -31,9 +31,11 @@ #include "soft-fp.h" #include "double.h" -DFtype __negdf2(DFtype a) +DFtype +__negdf2(DFtype a) { - FP_DECL_D(A); FP_DECL_D(R); + FP_DECL_D(A); + FP_DECL_D(R); DFtype r; FP_UNPACK_RAW_D(A, a); diff --git a/soft-fp/negsf2.c b/soft-fp/negsf2.c index 35ece56..1a08d34 100644 --- a/soft-fp/negsf2.c +++ b/soft-fp/negsf2.c @@ -31,9 +31,11 @@ #include "soft-fp.h" #include "single.h" -SFtype __negsf2(SFtype a) +SFtype +__negsf2(SFtype a) { - FP_DECL_S(A); FP_DECL_S(R); + FP_DECL_S(A); + FP_DECL_S(R); SFtype r; FP_UNPACK_RAW_S(A, a); diff --git a/soft-fp/negtf2.c b/soft-fp/negtf2.c index f51a621..eb28eba 100644 --- a/soft-fp/negtf2.c +++ b/soft-fp/negtf2.c @@ -31,9 +31,11 @@ #include "soft-fp.h" #include "quad.h" -TFtype __negtf2(TFtype a) +TFtype +__negtf2(TFtype a) { - FP_DECL_Q(A); FP_DECL_Q(R); + FP_DECL_Q(A); + FP_DECL_Q(R); TFtype r; FP_UNPACK_RAW_Q(A, a); diff --git a/soft-fp/op-1.h b/soft-fp/op-1.h index a9ad0d6..e4d84bf 100644 --- a/soft-fp/op-1.h +++ b/soft-fp/op-1.h @@ -39,12 +39,14 @@ #define _FP_FRAC_ADDI_1(X,I) (X##_f += I) #define _FP_FRAC_SLL_1(X,N) \ - do { \ - if (__builtin_constant_p(N) && (N) == 1) \ - X##_f += X##_f; \ - else \ - X##_f <<= (N); \ - } while (0) + do \ + { \ + if (__builtin_constant_p(N) && (N) == 1) \ + X##_f += X##_f; \ + else \ + X##_f <<= (N); \ + } \ + while (0) #define _FP_FRAC_SRL_1(X,N) (X##_f >>= N) /* Right shift with sticky-lsb. */ @@ -52,15 +54,19 @@ #define _FP_FRAC_SRS_1(X,N,sz) __FP_FRAC_SRS_1(X##_f, N, sz) #define __FP_FRAC_SRST_1(X,S,N,sz) \ -do { \ - S = (__builtin_constant_p(N) && (N) == 1 \ - ? X & 1 : (X << (_FP_W_TYPE_SIZE - (N))) != 0); \ - X = X >> (N); \ -} while (0) - -#define __FP_FRAC_SRS_1(X,N,sz) \ - (X = (X >> (N) | (__builtin_constant_p(N) && (N) == 1 \ - ? X & 1 : (X << (_FP_W_TYPE_SIZE - (N))) != 0))) + do \ + { \ + S = (__builtin_constant_p(N) && (N) == 1 \ + ? X & 1 \ + : (X << (_FP_W_TYPE_SIZE - (N))) != 0); \ + X = X >> (N); \ + } \ + while (0) + +#define __FP_FRAC_SRS_1(X,N,sz) \ + (X = (X >> (N) | (__builtin_constant_p(N) && (N) == 1 \ + ? X & 1 \ + : (X << (_FP_W_TYPE_SIZE - (N))) != 0))) #define _FP_FRAC_ADD_1(R,X,Y) (R##_f = X##_f + Y##_f) #define _FP_FRAC_SUB_1(R,X,Y) (R##_f = X##_f - Y##_f) @@ -86,49 +92,56 @@ do { \ * normalize the data. */ -#define _FP_UNPACK_RAW_1(fs, X, val) \ - do { \ - union _FP_UNION_##fs _flo; _flo.flt = (val); \ - \ - X##_f = _flo.bits.frac; \ - X##_e = _flo.bits.exp; \ - X##_s = _flo.bits.sign; \ - } while (0) - -#define _FP_UNPACK_RAW_1_P(fs, X, val) \ - do { \ - union _FP_UNION_##fs *_flo = \ - (union _FP_UNION_##fs *)(val); \ - \ - X##_f = _flo->bits.frac; \ - X##_e = _flo->bits.exp; \ - X##_s = _flo->bits.sign; \ - } while (0) +#define _FP_UNPACK_RAW_1(fs, X, val) \ + do \ + { \ + union _FP_UNION_##fs _flo; \ + _flo.flt = (val); \ + \ + X##_f = _flo.bits.frac; \ + X##_e = _flo.bits.exp; \ + X##_s = _flo.bits.sign; \ + } \ + while (0) + +#define _FP_UNPACK_RAW_1_P(fs, X, val) \ + do \ + { \ + union _FP_UNION_##fs *_flo = (union _FP_UNION_##fs *)(val); \ + \ + X##_f = _flo->bits.frac; \ + X##_e = _flo->bits.exp; \ + X##_s = _flo->bits.sign; \ + } \ + while (0) /* * Repack the raw bits of a native fp value. */ -#define _FP_PACK_RAW_1(fs, val, X) \ - do { \ - union _FP_UNION_##fs _flo; \ - \ - _flo.bits.frac = X##_f; \ - _flo.bits.exp = X##_e; \ - _flo.bits.sign = X##_s; \ - \ - (val) = _flo.flt; \ - } while (0) - -#define _FP_PACK_RAW_1_P(fs, val, X) \ - do { \ - union _FP_UNION_##fs *_flo = \ - (union _FP_UNION_##fs *)(val); \ - \ - _flo->bits.frac = X##_f; \ - _flo->bits.exp = X##_e; \ - _flo->bits.sign = X##_s; \ - } while (0) +#define _FP_PACK_RAW_1(fs, val, X) \ + do \ + { \ + union _FP_UNION_##fs _flo; \ + \ + _flo.bits.frac = X##_f; \ + _flo.bits.exp = X##_e; \ + _flo.bits.sign = X##_s; \ + \ + (val) = _flo.flt; \ + } \ + while (0) + +#define _FP_PACK_RAW_1_P(fs, val, X) \ + do \ + { \ + union _FP_UNION_##fs *_flo = (union _FP_UNION_##fs *)(val); \ + \ + _flo->bits.frac = X##_f; \ + _flo->bits.exp = X##_e; \ + _flo->bits.sign = X##_s; \ + } \ + while (0) /* @@ -138,74 +151,86 @@ do { \ /* Basic. Assuming the host word size is >= 2*FRACBITS, we can do the multiplication immediately. */ -#define _FP_MUL_MEAT_DW_1_imm(wfracbits, R, X, Y) \ - do { \ - R##_f = X##_f * Y##_f; \ - } while (0) +#define _FP_MUL_MEAT_DW_1_imm(wfracbits, R, X, Y) \ + do \ + { \ + R##_f = X##_f * Y##_f; \ + } \ + while (0) #define _FP_MUL_MEAT_1_imm(wfracbits, R, X, Y) \ - do { \ - _FP_MUL_MEAT_DW_1_imm(wfracbits, R, X, Y); \ - /* Normalize since we know where the msb of the multiplicands \ - were (bit B), we know that the msb of the of the product is \ - at either 2B or 2B-1. */ \ - _FP_FRAC_SRS_1(R, wfracbits-1, 2*wfracbits); \ - } while (0) + do \ + { \ + _FP_MUL_MEAT_DW_1_imm(wfracbits, R, X, Y); \ + /* Normalize since we know where the msb of the multiplicands \ + were (bit B), we know that the msb of the of the product is \ + at either 2B or 2B-1. */ \ + _FP_FRAC_SRS_1(R, wfracbits-1, 2*wfracbits); \ + } \ + while (0) /* Given a 1W * 1W => 2W primitive, do the extended multiplication. */ -#define _FP_MUL_MEAT_DW_1_wide(wfracbits, R, X, Y, doit) \ - do { \ - doit(R##_f1, R##_f0, X##_f, Y##_f); \ - } while (0) +#define _FP_MUL_MEAT_DW_1_wide(wfracbits, R, X, Y, doit) \ + do \ + { \ + doit(R##_f1, R##_f0, X##_f, Y##_f); \ + } \ + while (0) #define _FP_MUL_MEAT_1_wide(wfracbits, R, X, Y, doit) \ - do { \ - _FP_FRAC_DECL_2(_Z); \ - _FP_MUL_MEAT_DW_1_wide(wfracbits, _Z, X, Y, doit); \ - /* Normalize since we know where the msb of the multiplicands \ - were (bit B), we know that the msb of the of the product is \ - at either 2B or 2B-1. */ \ - _FP_FRAC_SRS_2(_Z, wfracbits-1, 2*wfracbits); \ - R##_f = _Z_f0; \ - } while (0) + do \ + { \ + _FP_FRAC_DECL_2(_Z); \ + _FP_MUL_MEAT_DW_1_wide(wfracbits, _Z, X, Y, doit); \ + /* Normalize since we know where the msb of the multiplicands \ + were (bit B), we know that the msb of the of the product is \ + at either 2B or 2B-1. */ \ + _FP_FRAC_SRS_2(_Z, wfracbits-1, 2*wfracbits); \ + R##_f = _Z_f0; \ + } \ + while (0) /* Finally, a simple widening multiply algorithm. What fun! */ #define _FP_MUL_MEAT_DW_1_hard(wfracbits, R, X, Y) \ - do { \ - _FP_W_TYPE _xh, _xl, _yh, _yl; \ - _FP_FRAC_DECL_2(_a); \ - \ - /* split the words in half */ \ - _xh = X##_f >> (_FP_W_TYPE_SIZE/2); \ - _xl = X##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1); \ - _yh = Y##_f >> (_FP_W_TYPE_SIZE/2); \ - _yl = Y##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1); \ + do \ + { \ + _FP_W_TYPE _xh, _xl, _yh, _yl; \ + _FP_FRAC_DECL_2(_a); \ \ - /* multiply the pieces */ \ - R##_f0 = _xl * _yl; \ - _a_f0 = _xh * _yl; \ - _a_f1 = _xl * _yh; \ - R##_f1 = _xh * _yh; \ + /* split the words in half */ \ + _xh = X##_f >> (_FP_W_TYPE_SIZE/2); \ + _xl = X##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1); \ + _yh = Y##_f >> (_FP_W_TYPE_SIZE/2); \ + _yl = Y##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1); \ \ - /* reassemble into two full words */ \ - if ((_a_f0 += _a_f1) < _a_f1) \ - R##_f1 += (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2); \ - _a_f1 = _a_f0 >> (_FP_W_TYPE_SIZE/2); \ - _a_f0 = _a_f0 << (_FP_W_TYPE_SIZE/2); \ - _FP_FRAC_ADD_2(R, R, _a); \ - } while (0) - -#define _FP_MUL_MEAT_1_hard(wfracbits, R, X, Y) \ - do { \ - _FP_FRAC_DECL_2(_z); \ - _FP_MUL_MEAT_DW_1_hard(wfracbits, _z, X, Y); \ + /* multiply the pieces */ \ + R##_f0 = _xl * _yl; \ + _a_f0 = _xh * _yl; \ + _a_f1 = _xl * _yh; \ + R##_f1 = _xh * _yh; \ \ - /* normalize */ \ - _FP_FRAC_SRS_2(_z, wfracbits - 1, 2*wfracbits); \ - R##_f = _z_f0; \ - } while (0) + /* reassemble into two full words */ \ + if ((_a_f0 += _a_f1) < _a_f1) \ + R##_f1 += (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2); \ + _a_f1 = _a_f0 >> (_FP_W_TYPE_SIZE/2); \ + _a_f0 = _a_f0 << (_FP_W_TYPE_SIZE/2); \ + _FP_FRAC_ADD_2(R, R, _a); \ + } \ + while (0) + +#define _FP_MUL_MEAT_1_hard(wfracbits, R, X, Y) \ + do \ + { \ + _FP_FRAC_DECL_2(_z); \ + _FP_MUL_MEAT_DW_1_hard(wfracbits, _z, X, Y); \ + \ + /* normalize */ \ + _FP_FRAC_SRS_2(_z, wfracbits - 1, 2*wfracbits); \ + R##_f = _z_f0; \ + } \ + while (0) /* @@ -217,15 +242,17 @@ do { \ C primitives or _FP_DIV_HELP_ldiv for the ISO function. Which you choose will depend on what the compiler does with divrem4. */ -#define _FP_DIV_MEAT_1_imm(fs, R, X, Y, doit) \ - do { \ - _FP_W_TYPE _q, _r; \ - X##_f <<= (X##_f < Y##_f \ - ? R##_e--, _FP_WFRACBITS_##fs \ - : _FP_WFRACBITS_##fs - 1); \ - doit(_q, _r, X##_f, Y##_f); \ - R##_f = _q | (_r != 0); \ - } while (0) +#define _FP_DIV_MEAT_1_imm(fs, R, X, Y, doit) \ + do \ + { \ + _FP_W_TYPE _q, _r; \ + X##_f <<= (X##_f < Y##_f \ + ? R##_e--, _FP_WFRACBITS_##fs \ + : _FP_WFRACBITS_##fs - 1); \ + doit(_q, _r, X##_f, Y##_f); \ + R##_f = _q | (_r != 0); \ + } \ + while (0) /* GCC's longlong.h defines a 2W / 1W => (1W,1W) primitive udiv_qrnnd that may be useful in this situation. This first is for a primitive @@ -233,46 +260,50 @@ do { \ for UDIV_NEEDS_NORMALIZATION to tell which your machine needs. */ #define _FP_DIV_MEAT_1_udiv_norm(fs, R, X, Y) \ - do { \ - _FP_W_TYPE _nh, _nl, _q, _r, _y; \ + do \ + { \ + _FP_W_TYPE _nh, _nl, _q, _r, _y; \ \ - /* Normalize Y -- i.e. make the most significant bit set. */ \ - _y = Y##_f << _FP_WFRACXBITS_##fs; \ + /* Normalize Y -- i.e. make the most significant bit set. */ \ + _y = Y##_f << _FP_WFRACXBITS_##fs; \ \ - /* Shift X op correspondingly high, that is, up one full word. */ \ - if (X##_f < Y##_f) \ - { \ - R##_e--; \ - _nl = 0; \ - _nh = X##_f; \ - } \ - else \ - { \ - _nl = X##_f << (_FP_W_TYPE_SIZE - 1); \ - _nh = X##_f >> 1; \ - } \ + /* Shift X op correspondingly high, that is, up one full word. */ \ + if (X##_f < Y##_f) \ + { \ + R##_e--; \ + _nl = 0; \ + _nh = X##_f; \ + } \ + else \ + { \ + _nl = X##_f << (_FP_W_TYPE_SIZE - 1); \ + _nh = X##_f >> 1; \ + } \ \ - udiv_qrnnd(_q, _r, _nh, _nl, _y); \ - R##_f = _q | (_r != 0); \ - } while (0) + udiv_qrnnd(_q, _r, _nh, _nl, _y); \ + R##_f = _q | (_r != 0); \ + } \ + while (0) #define _FP_DIV_MEAT_1_udiv(fs, R, X, Y) \ - do { \ - _FP_W_TYPE _nh, _nl, _q, _r; \ - if (X##_f < Y##_f) \ - { \ - R##_e--; \ - _nl = X##_f << _FP_WFRACBITS_##fs; \ - _nh = X##_f >> _FP_WFRACXBITS_##fs; \ - } \ - else \ - { \ - _nl = X##_f << (_FP_WFRACBITS_##fs - 1); \ - _nh = X##_f >> (_FP_WFRACXBITS_##fs + 1); \ - } \ - udiv_qrnnd(_q, _r, _nh, _nl, Y##_f); \ - R##_f = _q | (_r != 0); \ - } while (0) + do \ + { \ + _FP_W_TYPE _nh, _nl, _q, _r; \ + if (X##_f < Y##_f) \ + { \ + R##_e--; \ + _nl = X##_f << _FP_WFRACBITS_##fs; \ + _nh = X##_f >> _FP_WFRACXBITS_##fs; \ + } \ + else \ + { \ + _nl = X##_f << (_FP_WFRACBITS_##fs - 1); \ + _nh = X##_f >> (_FP_WFRACXBITS_##fs + 1); \ + } \ + udiv_qrnnd(_q, _r, _nh, _nl, Y##_f); \ + R##_f = _q | (_r != 0); \ + } \ + while (0) /* @@ -281,27 +312,29 @@ do { \ * should be added for those machines where division is fast. */ -#define _FP_SQRT_MEAT_1(R, S, T, X, q) \ - do { \ - while (q != _FP_WORK_ROUND) \ - { \ - T##_f = S##_f + q; \ - if (T##_f <= X##_f) \ - { \ - S##_f = T##_f + q; \ - X##_f -= T##_f; \ - R##_f += q; \ - } \ - _FP_FRAC_SLL_1(X, 1); \ - q >>= 1; \ - } \ - if (X##_f) \ - { \ - if (S##_f < X##_f) \ - R##_f |= _FP_WORK_ROUND; \ - R##_f |= _FP_WORK_STICKY; \ - } \ - } while (0) +#define _FP_SQRT_MEAT_1(R, S, T, X, q) \ + do \ + { \ + while (q != _FP_WORK_ROUND) \ + { \ + T##_f = S##_f + q; \ + if (T##_f <= X##_f) \ + { \ + S##_f = T##_f + q; \ + X##_f -= T##_f; \ + R##_f += q; \ + } \ + _FP_FRAC_SLL_1(X, 1); \ + q >>= 1; \ + } \ + if (X##_f) \ + { \ + if (S##_f < X##_f) \ + R##_f |= _FP_WORK_ROUND; \ + R##_f |= _FP_WORK_STICKY; \ + } \ + } \ + while (0) /* * Assembly/disassembly for converting to/from integral types. diff --git a/soft-fp/op-2.h b/soft-fp/op-2.h index a5275d4..1cbc1fe 100644 --- a/soft-fp/op-2.h +++ b/soft-fp/op-2.h @@ -37,74 +37,74 @@ #define _FP_FRAC_LOW_2(X) (X##_f0) #define _FP_FRAC_WORD_2(X,w) (X##_f##w) -#define _FP_FRAC_SLL_2(X,N) \ -(void)(((N) < _FP_W_TYPE_SIZE) \ - ? ({ \ - if (__builtin_constant_p(N) && (N) == 1) \ - { \ - X##_f1 = X##_f1 + X##_f1 + (((_FP_WS_TYPE)(X##_f0)) < 0); \ - X##_f0 += X##_f0; \ - } \ - else \ - { \ - X##_f1 = X##_f1 << (N) | X##_f0 >> (_FP_W_TYPE_SIZE - (N)); \ - X##_f0 <<= (N); \ - } \ - 0; \ - }) \ - : ({ \ - X##_f1 = X##_f0 << ((N) - _FP_W_TYPE_SIZE); \ - X##_f0 = 0; \ - })) +#define _FP_FRAC_SLL_2(X,N) \ + (void)(((N) < _FP_W_TYPE_SIZE) \ + ? ({ \ + if (__builtin_constant_p(N) && (N) == 1) \ + { \ + X##_f1 = X##_f1 + X##_f1 + (((_FP_WS_TYPE)(X##_f0)) < 0); \ + X##_f0 += X##_f0; \ + } \ + else \ + { \ + X##_f1 = X##_f1 << (N) | X##_f0 >> (_FP_W_TYPE_SIZE - (N)); \ + X##_f0 <<= (N); \ + } \ + 0; \ + }) \ + : ({ \ + X##_f1 = X##_f0 << ((N) - _FP_W_TYPE_SIZE); \ + X##_f0 = 0; \ + })) #define _FP_FRAC_SRL_2(X,N) \ -(void)(((N) < _FP_W_TYPE_SIZE) \ - ? ({ \ - X##_f0 = X##_f0 >> (N) | X##_f1 << (_FP_W_TYPE_SIZE - (N)); \ - X##_f1 >>= (N); \ - }) \ - : ({ \ - X##_f0 = X##_f1 >> ((N) - _FP_W_TYPE_SIZE); \ - X##_f1 = 0; \ - })) + (void)(((N) < _FP_W_TYPE_SIZE) \ + ? ({ \ + X##_f0 = X##_f0 >> (N) | X##_f1 << (_FP_W_TYPE_SIZE - (N)); \ + X##_f1 >>= (N); \ + }) \ + : ({ \ + X##_f0 = X##_f1 >> ((N) - _FP_W_TYPE_SIZE); \ + X##_f1 = 0; \ + })) /* Right shift with sticky-lsb. */ -#define _FP_FRAC_SRST_2(X,S, N,sz) \ -(void)(((N) < _FP_W_TYPE_SIZE) \ - ? ({ \ - S = (__builtin_constant_p(N) && (N) == 1 \ - ? X##_f0 & 1 \ - : (X##_f0 << (_FP_W_TYPE_SIZE - (N))) != 0); \ - X##_f0 = (X##_f1 << (_FP_W_TYPE_SIZE - (N)) | X##_f0 >> (N)); \ - X##_f1 >>= (N); \ - }) \ - : ({ \ - S = ((((N) == _FP_W_TYPE_SIZE \ - ? 0 \ - : (X##_f1 << (2*_FP_W_TYPE_SIZE - (N)))) \ - | X##_f0) != 0); \ - X##_f0 = (X##_f1 >> ((N) - _FP_W_TYPE_SIZE)); \ - X##_f1 = 0; \ - })) - -#define _FP_FRAC_SRS_2(X,N,sz) \ -(void)(((N) < _FP_W_TYPE_SIZE) \ - ? ({ \ - X##_f0 = (X##_f1 << (_FP_W_TYPE_SIZE - (N)) | X##_f0 >> (N) | \ - (__builtin_constant_p(N) && (N) == 1 \ - ? X##_f0 & 1 \ - : (X##_f0 << (_FP_W_TYPE_SIZE - (N))) != 0)); \ - X##_f1 >>= (N); \ - }) \ - : ({ \ - X##_f0 = (X##_f1 >> ((N) - _FP_W_TYPE_SIZE) | \ - ((((N) == _FP_W_TYPE_SIZE \ - ? 0 \ - : (X##_f1 << (2*_FP_W_TYPE_SIZE - (N)))) \ - | X##_f0) != 0)); \ - X##_f1 = 0; \ - })) +#define _FP_FRAC_SRST_2(X,S, N,sz) \ + (void)(((N) < _FP_W_TYPE_SIZE) \ + ? ({ \ + S = (__builtin_constant_p(N) && (N) == 1 \ + ? X##_f0 & 1 \ + : (X##_f0 << (_FP_W_TYPE_SIZE - (N))) != 0); \ + X##_f0 = (X##_f1 << (_FP_W_TYPE_SIZE - (N)) | X##_f0 >> (N)); \ + X##_f1 >>= (N); \ + }) \ + : ({ \ + S = ((((N) == _FP_W_TYPE_SIZE \ + ? 0 \ + : (X##_f1 << (2*_FP_W_TYPE_SIZE - (N)))) \ + | X##_f0) != 0); \ + X##_f0 = (X##_f1 >> ((N) - _FP_W_TYPE_SIZE)); \ + X##_f1 = 0; \ + })) + +#define _FP_FRAC_SRS_2(X,N,sz) \ + (void)(((N) < _FP_W_TYPE_SIZE) \ + ? ({ \ + X##_f0 = (X##_f1 << (_FP_W_TYPE_SIZE - (N)) | X##_f0 >> (N) \ + | (__builtin_constant_p(N) && (N) == 1 \ + ? X##_f0 & 1 \ + : (X##_f0 << (_FP_W_TYPE_SIZE - (N))) != 0)); \ + X##_f1 >>= (N); \ + }) \ + : ({ \ + X##_f0 = (X##_f1 >> ((N) - _FP_W_TYPE_SIZE) \ + | ((((N) == _FP_W_TYPE_SIZE \ + ? 0 \ + : (X##_f1 << (2*_FP_W_TYPE_SIZE - (N)))) \ + | X##_f0) != 0)); \ + X##_f1 = 0; \ + })) #define _FP_FRAC_ADDI_2(X,I) \ __FP_FRAC_ADDI_2(X##_f1, X##_f0, I) @@ -118,16 +118,18 @@ #define _FP_FRAC_DEC_2(X,Y) \ __FP_FRAC_DEC_2(X##_f1, X##_f0, Y##_f1, Y##_f0) -#define _FP_FRAC_CLZ_2(R,X) \ - do { \ - if (X##_f1) \ - __FP_CLZ(R,X##_f1); \ - else \ - { \ - __FP_CLZ(R,X##_f0); \ - R += _FP_W_TYPE_SIZE; \ - } \ - } while(0) +#define _FP_FRAC_CLZ_2(R,X) \ + do \ + { \ + if (X##_f1) \ + __FP_CLZ(R,X##_f1); \ + else \ + { \ + __FP_CLZ(R,X##_f0); \ + R += _FP_W_TYPE_SIZE; \ + } \ + } \ + while(0) /* Predicates */ #define _FP_FRAC_NEGP_2(X) ((_FP_WS_TYPE)X##_f1 < 0) @@ -152,16 +154,18 @@ #define __FP_FRAC_SET_2(X,I1,I0) (X##_f0 = I0, X##_f1 = I1) -#define __FP_CLZ_2(R, xh, xl) \ - do { \ - if (xh) \ - __FP_CLZ(R,xh); \ - else \ - { \ - __FP_CLZ(R,xl); \ - R += _FP_W_TYPE_SIZE; \ - } \ - } while(0) +#define __FP_CLZ_2(R, xh, xl) \ + do \ + { \ + if (xh) \ + __FP_CLZ(R,xh); \ + else \ + { \ + __FP_CLZ(R,xl); \ + R += _FP_W_TYPE_SIZE; \ + } \ + } \ + while(0) #if 0 @@ -179,10 +183,12 @@ # endif # ifndef __FP_FRAC_DEC_2 # define __FP_FRAC_DEC_2(xh, xl, yh, yl) \ - do { \ - UWtype _t = xl; \ - xh -= yh + ((xl -= yl) > _t); \ - } while (0) + do \ + { \ + UWtype _t = xl; \ + xh -= yh + ((xl -= yl) > _t); \ + } \ + while (0) # endif #else @@ -204,54 +210,61 @@ * normalize the data. */ -#define _FP_UNPACK_RAW_2(fs, X, val) \ - do { \ - union _FP_UNION_##fs _flo; _flo.flt = (val); \ - \ - X##_f0 = _flo.bits.frac0; \ - X##_f1 = _flo.bits.frac1; \ - X##_e = _flo.bits.exp; \ - X##_s = _flo.bits.sign; \ - } while (0) - -#define _FP_UNPACK_RAW_2_P(fs, X, val) \ - do { \ - union _FP_UNION_##fs *_flo = \ - (union _FP_UNION_##fs *)(val); \ - \ - X##_f0 = _flo->bits.frac0; \ - X##_f1 = _flo->bits.frac1; \ - X##_e = _flo->bits.exp; \ - X##_s = _flo->bits.sign; \ - } while (0) +#define _FP_UNPACK_RAW_2(fs, X, val) \ + do \ + { \ + union _FP_UNION_##fs _flo; \ + _flo.flt = (val); \ + \ + X##_f0 = _flo.bits.frac0; \ + X##_f1 = _flo.bits.frac1; \ + X##_e = _flo.bits.exp; \ + X##_s = _flo.bits.sign; \ + } \ + while (0) + +#define _FP_UNPACK_RAW_2_P(fs, X, val) \ + do \ + { \ + union _FP_UNION_##fs *_flo = (union _FP_UNION_##fs *)(val); \ + \ + X##_f0 = _flo->bits.frac0; \ + X##_f1 = _flo->bits.frac1; \ + X##_e = _flo->bits.exp; \ + X##_s = _flo->bits.sign; \ + } \ + while (0) /* * Repack the raw bits of a native fp value. */ -#define _FP_PACK_RAW_2(fs, val, X) \ - do { \ - union _FP_UNION_##fs _flo; \ - \ - _flo.bits.frac0 = X##_f0; \ - _flo.bits.frac1 = X##_f1; \ - _flo.bits.exp = X##_e; \ - _flo.bits.sign = X##_s; \ - \ - (val) = _flo.flt; \ - } while (0) - -#define _FP_PACK_RAW_2_P(fs, val, X) \ - do { \ - union _FP_UNION_##fs *_flo = \ - (union _FP_UNION_##fs *)(val); \ - \ - _flo->bits.frac0 = X##_f0; \ - _flo->bits.frac1 = X##_f1; \ - _flo->bits.exp = X##_e; \ - _flo->bits.sign = X##_s; \ - } while (0) +#define _FP_PACK_RAW_2(fs, val, X) \ + do \ + { \ + union _FP_UNION_##fs _flo; \ + \ + _flo.bits.frac0 = X##_f0; \ + _flo.bits.frac1 = X##_f1; \ + _flo.bits.exp = X##_e; \ + _flo.bits.sign = X##_s; \ + \ + (val) = _flo.flt; \ + } \ + while (0) + +#define _FP_PACK_RAW_2_P(fs, val, X) \ + do \ + { \ + union _FP_UNION_##fs *_flo = (union _FP_UNION_##fs *)(val); \ + \ + _flo->bits.frac0 = X##_f0; \ + _flo->bits.frac1 = X##_f1; \ + _flo->bits.exp = X##_e; \ + _flo->bits.sign = X##_s; \ + } \ + while (0) /* @@ -261,111 +274,127 @@ /* Given a 1W * 1W => 2W primitive, do the extended multiplication. */ #define _FP_MUL_MEAT_DW_2_wide(wfracbits, R, X, Y, doit) \ - do { \ - _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c); \ + do \ + { \ + _FP_FRAC_DECL_2(_b); \ + _FP_FRAC_DECL_2(_c); \ \ - doit(_FP_FRAC_WORD_4(R,1), _FP_FRAC_WORD_4(R,0), X##_f0, Y##_f0); \ - doit(_b_f1, _b_f0, X##_f0, Y##_f1); \ - doit(_c_f1, _c_f0, X##_f1, Y##_f0); \ - doit(_FP_FRAC_WORD_4(R,3), _FP_FRAC_WORD_4(R,2), X##_f1, Y##_f1); \ + doit(_FP_FRAC_WORD_4(R,1), _FP_FRAC_WORD_4(R,0), X##_f0, Y##_f0); \ + doit(_b_f1, _b_f0, X##_f0, Y##_f1); \ + doit(_c_f1, _c_f0, X##_f1, Y##_f0); \ + doit(_FP_FRAC_WORD_4(R,3), _FP_FRAC_WORD_4(R,2), X##_f1, Y##_f1); \ \ - __FP_FRAC_ADD_3(_FP_FRAC_WORD_4(R,3),_FP_FRAC_WORD_4(R,2), \ - _FP_FRAC_WORD_4(R,1), 0, _b_f1, _b_f0, \ - _FP_FRAC_WORD_4(R,3),_FP_FRAC_WORD_4(R,2), \ - _FP_FRAC_WORD_4(R,1)); \ - __FP_FRAC_ADD_3(_FP_FRAC_WORD_4(R,3),_FP_FRAC_WORD_4(R,2), \ - _FP_FRAC_WORD_4(R,1), 0, _c_f1, _c_f0, \ - _FP_FRAC_WORD_4(R,3),_FP_FRAC_WORD_4(R,2), \ - _FP_FRAC_WORD_4(R,1)); \ - } while (0) + __FP_FRAC_ADD_3(_FP_FRAC_WORD_4(R,3),_FP_FRAC_WORD_4(R,2), \ + _FP_FRAC_WORD_4(R,1), 0, _b_f1, _b_f0, \ + _FP_FRAC_WORD_4(R,3),_FP_FRAC_WORD_4(R,2), \ + _FP_FRAC_WORD_4(R,1)); \ + __FP_FRAC_ADD_3(_FP_FRAC_WORD_4(R,3),_FP_FRAC_WORD_4(R,2), \ + _FP_FRAC_WORD_4(R,1), 0, _c_f1, _c_f0, \ + _FP_FRAC_WORD_4(R,3),_FP_FRAC_WORD_4(R,2), \ + _FP_FRAC_WORD_4(R,1)); \ + } \ + while (0) #define _FP_MUL_MEAT_2_wide(wfracbits, R, X, Y, doit) \ - do { \ - _FP_FRAC_DECL_4(_z); \ + do \ + { \ + _FP_FRAC_DECL_4(_z); \ \ - _FP_MUL_MEAT_DW_2_wide(wfracbits, _z, X, Y, doit); \ + _FP_MUL_MEAT_DW_2_wide(wfracbits, _z, X, Y, doit); \ \ - /* Normalize since we know where the msb of the multiplicands \ - were (bit B), we know that the msb of the of the product is \ - at either 2B or 2B-1. */ \ - _FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits); \ - R##_f0 = _FP_FRAC_WORD_4(_z,0); \ - R##_f1 = _FP_FRAC_WORD_4(_z,1); \ - } while (0) + /* Normalize since we know where the msb of the multiplicands \ + were (bit B), we know that the msb of the of the product is \ + at either 2B or 2B-1. */ \ + _FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits); \ + R##_f0 = _FP_FRAC_WORD_4(_z,0); \ + R##_f1 = _FP_FRAC_WORD_4(_z,1); \ + } \ + while (0) /* Given a 1W * 1W => 2W primitive, do the extended multiplication. Do only 3 multiplications instead of four. This one is for machines where multiplication is much more expensive than subtraction. */ #define _FP_MUL_MEAT_DW_2_wide_3mul(wfracbits, R, X, Y, doit) \ - do { \ - _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c); \ - _FP_W_TYPE _d; \ - int _c1, _c2; \ + do \ + { \ + _FP_FRAC_DECL_2(_b); \ + _FP_FRAC_DECL_2(_c); \ + _FP_W_TYPE _d; \ + int _c1, _c2; \ \ - _b_f0 = X##_f0 + X##_f1; \ - _c1 = _b_f0 < X##_f0; \ - _b_f1 = Y##_f0 + Y##_f1; \ - _c2 = _b_f1 < Y##_f0; \ - doit(_d, _FP_FRAC_WORD_4(R,0), X##_f0, Y##_f0); \ - doit(_FP_FRAC_WORD_4(R,2), _FP_FRAC_WORD_4(R,1), _b_f0, _b_f1); \ - doit(_c_f1, _c_f0, X##_f1, Y##_f1); \ + _b_f0 = X##_f0 + X##_f1; \ + _c1 = _b_f0 < X##_f0; \ + _b_f1 = Y##_f0 + Y##_f1; \ + _c2 = _b_f1 < Y##_f0; \ + doit(_d, _FP_FRAC_WORD_4(R,0), X##_f0, Y##_f0); \ + doit(_FP_FRAC_WORD_4(R,2), _FP_FRAC_WORD_4(R,1), _b_f0, _b_f1); \ + doit(_c_f1, _c_f0, X##_f1, Y##_f1); \ \ - _b_f0 &= -_c2; \ - _b_f1 &= -_c1; \ - __FP_FRAC_ADD_3(_FP_FRAC_WORD_4(R,3),_FP_FRAC_WORD_4(R,2), \ - _FP_FRAC_WORD_4(R,1), (_c1 & _c2), 0, _d, \ - 0, _FP_FRAC_WORD_4(R,2), _FP_FRAC_WORD_4(R,1)); \ - __FP_FRAC_ADDI_2(_FP_FRAC_WORD_4(R,3),_FP_FRAC_WORD_4(R,2), \ - _b_f0); \ - __FP_FRAC_ADDI_2(_FP_FRAC_WORD_4(R,3),_FP_FRAC_WORD_4(R,2), \ - _b_f1); \ - __FP_FRAC_DEC_3(_FP_FRAC_WORD_4(R,3),_FP_FRAC_WORD_4(R,2), \ - _FP_FRAC_WORD_4(R,1), \ - 0, _d, _FP_FRAC_WORD_4(R,0)); \ - __FP_FRAC_DEC_3(_FP_FRAC_WORD_4(R,3),_FP_FRAC_WORD_4(R,2), \ - _FP_FRAC_WORD_4(R,1), 0, _c_f1, _c_f0); \ - __FP_FRAC_ADD_2(_FP_FRAC_WORD_4(R,3), _FP_FRAC_WORD_4(R,2), \ - _c_f1, _c_f0, \ - _FP_FRAC_WORD_4(R,3), _FP_FRAC_WORD_4(R,2)); \ - } while (0) + _b_f0 &= -_c2; \ + _b_f1 &= -_c1; \ + __FP_FRAC_ADD_3(_FP_FRAC_WORD_4(R,3),_FP_FRAC_WORD_4(R,2), \ + _FP_FRAC_WORD_4(R,1), (_c1 & _c2), 0, _d, \ + 0, _FP_FRAC_WORD_4(R,2), _FP_FRAC_WORD_4(R,1)); \ + __FP_FRAC_ADDI_2(_FP_FRAC_WORD_4(R,3),_FP_FRAC_WORD_4(R,2), \ + _b_f0); \ + __FP_FRAC_ADDI_2(_FP_FRAC_WORD_4(R,3),_FP_FRAC_WORD_4(R,2), \ + _b_f1); \ + __FP_FRAC_DEC_3(_FP_FRAC_WORD_4(R,3),_FP_FRAC_WORD_4(R,2), \ + _FP_FRAC_WORD_4(R,1), \ + 0, _d, _FP_FRAC_WORD_4(R,0)); \ + __FP_FRAC_DEC_3(_FP_FRAC_WORD_4(R,3),_FP_FRAC_WORD_4(R,2), \ + _FP_FRAC_WORD_4(R,1), 0, _c_f1, _c_f0); \ + __FP_FRAC_ADD_2(_FP_FRAC_WORD_4(R,3), _FP_FRAC_WORD_4(R,2), \ + _c_f1, _c_f0, \ + _FP_FRAC_WORD_4(R,3), _FP_FRAC_WORD_4(R,2)); \ + } \ + while (0) #define _FP_MUL_MEAT_2_wide_3mul(wfracbits, R, X, Y, doit) \ - do { \ - _FP_FRAC_DECL_4(_z); \ - \ - _FP_MUL_MEAT_DW_2_wide_3mul(wfracbits, _z, X, Y, doit); \ + do \ + { \ + _FP_FRAC_DECL_4(_z); \ \ - /* Normalize since we know where the msb of the multiplicands \ - were (bit B), we know that the msb of the of the product is \ - at either 2B or 2B-1. */ \ - _FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits); \ - R##_f0 = _FP_FRAC_WORD_4(_z,0); \ - R##_f1 = _FP_FRAC_WORD_4(_z,1); \ - } while (0) - -#define _FP_MUL_MEAT_DW_2_gmp(wfracbits, R, X, Y) \ - do { \ - _FP_W_TYPE _x[2], _y[2]; \ - _x[0] = X##_f0; _x[1] = X##_f1; \ - _y[0] = Y##_f0; _y[1] = Y##_f1; \ + _FP_MUL_MEAT_DW_2_wide_3mul(wfracbits, _z, X, Y, doit); \ \ - mpn_mul_n(R##_f, _x, _y, 2); \ - } while (0) + /* Normalize since we know where the msb of the multiplicands \ + were (bit B), we know that the msb of the of the product is \ + at either 2B or 2B-1. */ \ + _FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits); \ + R##_f0 = _FP_FRAC_WORD_4(_z,0); \ + R##_f1 = _FP_FRAC_WORD_4(_z,1); \ + } \ + while (0) + +#define _FP_MUL_MEAT_DW_2_gmp(wfracbits, R, X, Y) \ + do \ + { \ + _FP_W_TYPE _x[2], _y[2]; \ + _x[0] = X##_f0; \ + _x[1] = X##_f1; \ + _y[0] = Y##_f0; \ + _y[1] = Y##_f1; \ + \ + mpn_mul_n(R##_f, _x, _y, 2); \ + } \ + while (0) #define _FP_MUL_MEAT_2_gmp(wfracbits, R, X, Y) \ - do { \ - _FP_FRAC_DECL_4(_z); \ + do \ + { \ + _FP_FRAC_DECL_4(_z); \ \ - _FP_MUL_MEAT_DW_2_gmp(wfracbits, _z, X, Y); \ + _FP_MUL_MEAT_DW_2_gmp(wfracbits, _z, X, Y); \ \ - /* Normalize since we know where the msb of the multiplicands \ - were (bit B), we know that the msb of the of the product is \ - at either 2B or 2B-1. */ \ - _FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits); \ - R##_f0 = _z_f[0]; \ - R##_f1 = _z_f[1]; \ - } while (0) + /* Normalize since we know where the msb of the multiplicands \ + were (bit B), we know that the msb of the of the product is \ + at either 2B or 2B-1. */ \ + _FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits); \ + R##_f0 = _z_f[0]; \ + R##_f1 = _z_f[1]; \ + } \ + while (0) /* Do at most 120x120=240 bits multiplication using double floating point multiplication. This is useful if floating point @@ -376,190 +405,203 @@ SETFETZ is a macro which will disable all FPU exceptions and set rounding towards zero, RESETFE should optionally reset it back. */ -#define _FP_MUL_MEAT_2_120_240_double(wfracbits, R, X, Y, setfetz, resetfe) \ - do { \ - static const double _const[] = { \ - /* 2^-24 */ 5.9604644775390625e-08, \ - /* 2^-48 */ 3.5527136788005009e-15, \ - /* 2^-72 */ 2.1175823681357508e-22, \ - /* 2^-96 */ 1.2621774483536189e-29, \ - /* 2^28 */ 2.68435456e+08, \ - /* 2^4 */ 1.600000e+01, \ - /* 2^-20 */ 9.5367431640625e-07, \ - /* 2^-44 */ 5.6843418860808015e-14, \ - /* 2^-68 */ 3.3881317890172014e-21, \ - /* 2^-92 */ 2.0194839173657902e-28, \ - /* 2^-116 */ 1.2037062152420224e-35}; \ - double _a240, _b240, _c240, _d240, _e240, _f240, \ - _g240, _h240, _i240, _j240, _k240; \ - union { double d; UDItype i; } _l240, _m240, _n240, _o240, \ - _p240, _q240, _r240, _s240; \ - UDItype _t240, _u240, _v240, _w240, _x240, _y240 = 0; \ - \ - if (wfracbits < 106 || wfracbits > 120) \ - abort(); \ - \ - setfetz; \ - \ - _e240 = (double)(long)(X##_f0 & 0xffffff); \ - _j240 = (double)(long)(Y##_f0 & 0xffffff); \ - _d240 = (double)(long)((X##_f0 >> 24) & 0xffffff); \ - _i240 = (double)(long)((Y##_f0 >> 24) & 0xffffff); \ - _c240 = (double)(long)(((X##_f1 << 16) & 0xffffff) | (X##_f0 >> 48)); \ - _h240 = (double)(long)(((Y##_f1 << 16) & 0xffffff) | (Y##_f0 >> 48)); \ - _b240 = (double)(long)((X##_f1 >> 8) & 0xffffff); \ - _g240 = (double)(long)((Y##_f1 >> 8) & 0xffffff); \ - _a240 = (double)(long)(X##_f1 >> 32); \ - _f240 = (double)(long)(Y##_f1 >> 32); \ - _e240 *= _const[3]; \ - _j240 *= _const[3]; \ - _d240 *= _const[2]; \ - _i240 *= _const[2]; \ - _c240 *= _const[1]; \ - _h240 *= _const[1]; \ - _b240 *= _const[0]; \ - _g240 *= _const[0]; \ - _s240.d = _e240*_j240;\ - _r240.d = _d240*_j240 + _e240*_i240;\ - _q240.d = _c240*_j240 + _d240*_i240 + _e240*_h240;\ - _p240.d = _b240*_j240 + _c240*_i240 + _d240*_h240 + _e240*_g240;\ - _o240.d = _a240*_j240 + _b240*_i240 + _c240*_h240 + _d240*_g240 + _e240*_f240;\ - _n240.d = _a240*_i240 + _b240*_h240 + _c240*_g240 + _d240*_f240; \ - _m240.d = _a240*_h240 + _b240*_g240 + _c240*_f240; \ - _l240.d = _a240*_g240 + _b240*_f240; \ - _k240 = _a240*_f240; \ - _r240.d += _s240.d; \ - _q240.d += _r240.d; \ - _p240.d += _q240.d; \ - _o240.d += _p240.d; \ - _n240.d += _o240.d; \ - _m240.d += _n240.d; \ - _l240.d += _m240.d; \ - _k240 += _l240.d; \ - _s240.d -= ((_const[10]+_s240.d)-_const[10]); \ - _r240.d -= ((_const[9]+_r240.d)-_const[9]); \ - _q240.d -= ((_const[8]+_q240.d)-_const[8]); \ - _p240.d -= ((_const[7]+_p240.d)-_const[7]); \ - _o240.d += _const[7]; \ - _n240.d += _const[6]; \ - _m240.d += _const[5]; \ - _l240.d += _const[4]; \ - if (_s240.d != 0.0) _y240 = 1; \ - if (_r240.d != 0.0) _y240 = 1; \ - if (_q240.d != 0.0) _y240 = 1; \ - if (_p240.d != 0.0) _y240 = 1; \ - _t240 = (DItype)_k240; \ - _u240 = _l240.i; \ - _v240 = _m240.i; \ - _w240 = _n240.i; \ - _x240 = _o240.i; \ - R##_f1 = (_t240 << (128 - (wfracbits - 1))) \ - | ((_u240 & 0xffffff) >> ((wfracbits - 1) - 104)); \ - R##_f0 = ((_u240 & 0xffffff) << (168 - (wfracbits - 1))) \ - | ((_v240 & 0xffffff) << (144 - (wfracbits - 1))) \ - | ((_w240 & 0xffffff) << (120 - (wfracbits - 1))) \ - | ((_x240 & 0xffffff) >> ((wfracbits - 1) - 96)) \ - | _y240; \ - resetfe; \ - } while (0) +#define _FP_MUL_MEAT_2_120_240_double(wfracbits, R, X, Y, setfetz, resetfe) \ + do \ + { \ + static const double _const[] = \ + { \ + /* 2^-24 */ 5.9604644775390625e-08, \ + /* 2^-48 */ 3.5527136788005009e-15, \ + /* 2^-72 */ 2.1175823681357508e-22, \ + /* 2^-96 */ 1.2621774483536189e-29, \ + /* 2^28 */ 2.68435456e+08, \ + /* 2^4 */ 1.600000e+01, \ + /* 2^-20 */ 9.5367431640625e-07, \ + /* 2^-44 */ 5.6843418860808015e-14, \ + /* 2^-68 */ 3.3881317890172014e-21, \ + /* 2^-92 */ 2.0194839173657902e-28, \ + /* 2^-116 */ 1.2037062152420224e-35 \ + }; \ + double _a240, _b240, _c240, _d240, _e240, _f240, \ + _g240, _h240, _i240, _j240, _k240; \ + union { double d; UDItype i; } _l240, _m240, _n240, _o240, \ + _p240, _q240, _r240, _s240; \ + UDItype _t240, _u240, _v240, _w240, _x240, _y240 = 0; \ + \ + if (wfracbits < 106 || wfracbits > 120) \ + abort(); \ + \ + setfetz; \ + \ + _e240 = (double)(long)(X##_f0 & 0xffffff); \ + _j240 = (double)(long)(Y##_f0 & 0xffffff); \ + _d240 = (double)(long)((X##_f0 >> 24) & 0xffffff); \ + _i240 = (double)(long)((Y##_f0 >> 24) & 0xffffff); \ + _c240 = (double)(long)(((X##_f1 << 16) & 0xffffff) | (X##_f0 >> 48)); \ + _h240 = (double)(long)(((Y##_f1 << 16) & 0xffffff) | (Y##_f0 >> 48)); \ + _b240 = (double)(long)((X##_f1 >> 8) & 0xffffff); \ + _g240 = (double)(long)((Y##_f1 >> 8) & 0xffffff); \ + _a240 = (double)(long)(X##_f1 >> 32); \ + _f240 = (double)(long)(Y##_f1 >> 32); \ + _e240 *= _const[3]; \ + _j240 *= _const[3]; \ + _d240 *= _const[2]; \ + _i240 *= _const[2]; \ + _c240 *= _const[1]; \ + _h240 *= _const[1]; \ + _b240 *= _const[0]; \ + _g240 *= _const[0]; \ + _s240.d = _e240*_j240; \ + _r240.d = _d240*_j240 + _e240*_i240; \ + _q240.d = _c240*_j240 + _d240*_i240 + _e240*_h240; \ + _p240.d = _b240*_j240 + _c240*_i240 + _d240*_h240 + _e240*_g240; \ + _o240.d = _a240*_j240 + _b240*_i240 + _c240*_h240 + _d240*_g240 + _e240*_f240; \ + _n240.d = _a240*_i240 + _b240*_h240 + _c240*_g240 + _d240*_f240; \ + _m240.d = _a240*_h240 + _b240*_g240 + _c240*_f240; \ + _l240.d = _a240*_g240 + _b240*_f240; \ + _k240 = _a240*_f240; \ + _r240.d += _s240.d; \ + _q240.d += _r240.d; \ + _p240.d += _q240.d; \ + _o240.d += _p240.d; \ + _n240.d += _o240.d; \ + _m240.d += _n240.d; \ + _l240.d += _m240.d; \ + _k240 += _l240.d; \ + _s240.d -= ((_const[10]+_s240.d)-_const[10]); \ + _r240.d -= ((_const[9]+_r240.d)-_const[9]); \ + _q240.d -= ((_const[8]+_q240.d)-_const[8]); \ + _p240.d -= ((_const[7]+_p240.d)-_const[7]); \ + _o240.d += _const[7]; \ + _n240.d += _const[6]; \ + _m240.d += _const[5]; \ + _l240.d += _const[4]; \ + if (_s240.d != 0.0) \ + _y240 = 1; \ + if (_r240.d != 0.0) \ + _y240 = 1; \ + if (_q240.d != 0.0) \ + _y240 = 1; \ + if (_p240.d != 0.0) \ + _y240 = 1; \ + _t240 = (DItype)_k240; \ + _u240 = _l240.i; \ + _v240 = _m240.i; \ + _w240 = _n240.i; \ + _x240 = _o240.i; \ + R##_f1 = ((_t240 << (128 - (wfracbits - 1))) \ + | ((_u240 & 0xffffff) >> ((wfracbits - 1) - 104))); \ + R##_f0 = (((_u240 & 0xffffff) << (168 - (wfracbits - 1))) \ + | ((_v240 & 0xffffff) << (144 - (wfracbits - 1))) \ + | ((_w240 & 0xffffff) << (120 - (wfracbits - 1))) \ + | ((_x240 & 0xffffff) >> ((wfracbits - 1) - 96)) \ + | _y240); \ + resetfe; \ + } \ + while (0) /* * Division algorithms: */ #define _FP_DIV_MEAT_2_udiv(fs, R, X, Y) \ - do { \ - _FP_W_TYPE _n_f2, _n_f1, _n_f0, _r_f1, _r_f0, _m_f1, _m_f0; \ - if (_FP_FRAC_GE_2(X, Y)) \ - { \ - _n_f2 = X##_f1 >> 1; \ - _n_f1 = X##_f1 << (_FP_W_TYPE_SIZE - 1) | X##_f0 >> 1; \ - _n_f0 = X##_f0 << (_FP_W_TYPE_SIZE - 1); \ - } \ - else \ - { \ - R##_e--; \ - _n_f2 = X##_f1; \ - _n_f1 = X##_f0; \ - _n_f0 = 0; \ - } \ + do \ + { \ + _FP_W_TYPE _n_f2, _n_f1, _n_f0, _r_f1, _r_f0, _m_f1, _m_f0; \ + if (_FP_FRAC_GE_2(X, Y)) \ + { \ + _n_f2 = X##_f1 >> 1; \ + _n_f1 = X##_f1 << (_FP_W_TYPE_SIZE - 1) | X##_f0 >> 1; \ + _n_f0 = X##_f0 << (_FP_W_TYPE_SIZE - 1); \ + } \ + else \ + { \ + R##_e--; \ + _n_f2 = X##_f1; \ + _n_f1 = X##_f0; \ + _n_f0 = 0; \ + } \ \ - /* Normalize, i.e. make the most significant bit of the \ - denominator set. */ \ - _FP_FRAC_SLL_2(Y, _FP_WFRACXBITS_##fs); \ + /* Normalize, i.e. make the most significant bit of the \ + denominator set. */ \ + _FP_FRAC_SLL_2(Y, _FP_WFRACXBITS_##fs); \ \ - udiv_qrnnd(R##_f1, _r_f1, _n_f2, _n_f1, Y##_f1); \ - umul_ppmm(_m_f1, _m_f0, R##_f1, Y##_f0); \ - _r_f0 = _n_f0; \ - if (_FP_FRAC_GT_2(_m, _r)) \ - { \ - R##_f1--; \ - _FP_FRAC_ADD_2(_r, Y, _r); \ - if (_FP_FRAC_GE_2(_r, Y) && _FP_FRAC_GT_2(_m, _r)) \ - { \ - R##_f1--; \ - _FP_FRAC_ADD_2(_r, Y, _r); \ - } \ - } \ - _FP_FRAC_DEC_2(_r, _m); \ + udiv_qrnnd(R##_f1, _r_f1, _n_f2, _n_f1, Y##_f1); \ + umul_ppmm(_m_f1, _m_f0, R##_f1, Y##_f0); \ + _r_f0 = _n_f0; \ + if (_FP_FRAC_GT_2(_m, _r)) \ + { \ + R##_f1--; \ + _FP_FRAC_ADD_2(_r, Y, _r); \ + if (_FP_FRAC_GE_2(_r, Y) && _FP_FRAC_GT_2(_m, _r)) \ + { \ + R##_f1--; \ + _FP_FRAC_ADD_2(_r, Y, _r); \ + } \ + } \ + _FP_FRAC_DEC_2(_r, _m); \ \ - if (_r_f1 == Y##_f1) \ - { \ - /* This is a special case, not an optimization \ - (_r/Y##_f1 would not fit into UWtype). \ - As _r is guaranteed to be < Y, R##_f0 can be either \ - (UWtype)-1 or (UWtype)-2. But as we know what kind \ - of bits it is (sticky, guard, round), we don't care. \ - We also don't care what the reminder is, because the \ - guard bit will be set anyway. -jj */ \ - R##_f0 = -1; \ - } \ - else \ - { \ - udiv_qrnnd(R##_f0, _r_f1, _r_f1, _r_f0, Y##_f1); \ - umul_ppmm(_m_f1, _m_f0, R##_f0, Y##_f0); \ - _r_f0 = 0; \ - if (_FP_FRAC_GT_2(_m, _r)) \ - { \ - R##_f0--; \ - _FP_FRAC_ADD_2(_r, Y, _r); \ - if (_FP_FRAC_GE_2(_r, Y) && _FP_FRAC_GT_2(_m, _r)) \ - { \ - R##_f0--; \ - _FP_FRAC_ADD_2(_r, Y, _r); \ - } \ - } \ - if (!_FP_FRAC_EQ_2(_r, _m)) \ - R##_f0 |= _FP_WORK_STICKY; \ - } \ - } while (0) + if (_r_f1 == Y##_f1) \ + { \ + /* This is a special case, not an optimization \ + (_r/Y##_f1 would not fit into UWtype). \ + As _r is guaranteed to be < Y, R##_f0 can be either \ + (UWtype)-1 or (UWtype)-2. But as we know what kind \ + of bits it is (sticky, guard, round), we don't care. \ + We also don't care what the reminder is, because the \ + guard bit will be set anyway. -jj */ \ + R##_f0 = -1; \ + } \ + else \ + { \ + udiv_qrnnd(R##_f0, _r_f1, _r_f1, _r_f0, Y##_f1); \ + umul_ppmm(_m_f1, _m_f0, R##_f0, Y##_f0); \ + _r_f0 = 0; \ + if (_FP_FRAC_GT_2(_m, _r)) \ + { \ + R##_f0--; \ + _FP_FRAC_ADD_2(_r, Y, _r); \ + if (_FP_FRAC_GE_2(_r, Y) && _FP_FRAC_GT_2(_m, _r)) \ + { \ + R##_f0--; \ + _FP_FRAC_ADD_2(_r, Y, _r); \ + } \ + } \ + if (!_FP_FRAC_EQ_2(_r, _m)) \ + R##_f0 |= _FP_WORK_STICKY; \ + } \ + } \ + while (0) #define _FP_DIV_MEAT_2_gmp(fs, R, X, Y) \ - do { \ - _FP_W_TYPE _x[4], _y[2], _z[4]; \ - _y[0] = Y##_f0; _y[1] = Y##_f1; \ - _x[0] = _x[3] = 0; \ - if (_FP_FRAC_GE_2(X, Y)) \ - { \ - _x[1] = (X##_f0 << (_FP_WFRACBITS_##fs-1 - _FP_W_TYPE_SIZE) | \ - X##_f1 >> (_FP_W_TYPE_SIZE - \ - (_FP_WFRACBITS_##fs-1 - _FP_W_TYPE_SIZE))); \ - _x[2] = X##_f1 << (_FP_WFRACBITS_##fs-1 - _FP_W_TYPE_SIZE); \ - } \ - else \ - { \ - R##_e--; \ - _x[1] = (X##_f0 << (_FP_WFRACBITS_##fs - _FP_W_TYPE_SIZE) | \ - X##_f1 >> (_FP_W_TYPE_SIZE - \ - (_FP_WFRACBITS_##fs - _FP_W_TYPE_SIZE))); \ - _x[2] = X##_f1 << (_FP_WFRACBITS_##fs - _FP_W_TYPE_SIZE); \ - } \ + do \ + { \ + _FP_W_TYPE _x[4], _y[2], _z[4]; \ + _y[0] = Y##_f0; \ + _y[1] = Y##_f1; \ + _x[0] = _x[3] = 0; \ + if (_FP_FRAC_GE_2(X, Y)) \ + { \ + _x[1] = (X##_f0 << (_FP_WFRACBITS_##fs-1 - _FP_W_TYPE_SIZE) \ + | X##_f1 >> (_FP_W_TYPE_SIZE - \ + (_FP_WFRACBITS_##fs-1 - _FP_W_TYPE_SIZE))); \ + _x[2] = X##_f1 << (_FP_WFRACBITS_##fs-1 - _FP_W_TYPE_SIZE); \ + } \ + else \ + { \ + R##_e--; \ + _x[1] = (X##_f0 << (_FP_WFRACBITS_##fs - _FP_W_TYPE_SIZE) \ + | X##_f1 >> (_FP_W_TYPE_SIZE - \ + (_FP_WFRACBITS_##fs - _FP_W_TYPE_SIZE))); \ + _x[2] = X##_f1 << (_FP_WFRACBITS_##fs - _FP_W_TYPE_SIZE); \ + } \ \ - (void) mpn_divrem (_z, 0, _x, 4, _y, 2); \ - R##_f1 = _z[1]; \ - R##_f0 = _z[0] | ((_x[0] | _x[1]) != 0); \ - } while (0) + (void) mpn_divrem (_z, 0, _x, 4, _y, 2); \ + R##_f1 = _z[1]; \ + R##_f0 = _z[0] | ((_x[0] | _x[1]) != 0); \ + } \ + while (0) /* @@ -568,44 +610,46 @@ * should be added for those machines where division is fast. */ -#define _FP_SQRT_MEAT_2(R, S, T, X, q) \ - do { \ - while (q) \ - { \ - T##_f1 = S##_f1 + q; \ - if (T##_f1 <= X##_f1) \ - { \ - S##_f1 = T##_f1 + q; \ - X##_f1 -= T##_f1; \ - R##_f1 += q; \ - } \ - _FP_FRAC_SLL_2(X, 1); \ - q >>= 1; \ - } \ - q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ - while (q != _FP_WORK_ROUND) \ - { \ - T##_f0 = S##_f0 + q; \ - T##_f1 = S##_f1; \ - if (T##_f1 < X##_f1 || \ - (T##_f1 == X##_f1 && T##_f0 <= X##_f0)) \ - { \ - S##_f0 = T##_f0 + q; \ - S##_f1 += (T##_f0 > S##_f0); \ - _FP_FRAC_DEC_2(X, T); \ - R##_f0 += q; \ - } \ - _FP_FRAC_SLL_2(X, 1); \ - q >>= 1; \ - } \ - if (X##_f0 | X##_f1) \ - { \ - if (S##_f1 < X##_f1 || \ - (S##_f1 == X##_f1 && S##_f0 < X##_f0)) \ - R##_f0 |= _FP_WORK_ROUND; \ - R##_f0 |= _FP_WORK_STICKY; \ - } \ - } while (0) +#define _FP_SQRT_MEAT_2(R, S, T, X, q) \ + do \ + { \ + while (q) \ + { \ + T##_f1 = S##_f1 + q; \ + if (T##_f1 <= X##_f1) \ + { \ + S##_f1 = T##_f1 + q; \ + X##_f1 -= T##_f1; \ + R##_f1 += q; \ + } \ + _FP_FRAC_SLL_2(X, 1); \ + q >>= 1; \ + } \ + q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ + while (q != _FP_WORK_ROUND) \ + { \ + T##_f0 = S##_f0 + q; \ + T##_f1 = S##_f1; \ + if (T##_f1 < X##_f1 \ + || (T##_f1 == X##_f1 && T##_f0 <= X##_f0)) \ + { \ + S##_f0 = T##_f0 + q; \ + S##_f1 += (T##_f0 > S##_f0); \ + _FP_FRAC_DEC_2(X, T); \ + R##_f0 += q; \ + } \ + _FP_FRAC_SLL_2(X, 1); \ + q >>= 1; \ + } \ + if (X##_f0 | X##_f1) \ + { \ + if (S##_f1 < X##_f1 \ + || (S##_f1 == X##_f1 && S##_f0 < X##_f0)) \ + R##_f0 |= _FP_WORK_ROUND; \ + R##_f0 |= _FP_WORK_STICKY; \ + } \ + } \ + while (0) /* @@ -614,19 +658,21 @@ */ #define _FP_FRAC_ASSEMBLE_2(r, X, rsize) \ -(void)((rsize <= _FP_W_TYPE_SIZE) \ - ? ({ r = X##_f0; }) \ - : ({ \ - r = X##_f1; \ - r <<= _FP_W_TYPE_SIZE; \ - r += X##_f0; \ - })) + (void)((rsize <= _FP_W_TYPE_SIZE) \ + ? ({ r = X##_f0; }) \ + : ({ \ + r = X##_f1; \ + r <<= _FP_W_TYPE_SIZE; \ + r += X##_f0; \ + })) #define _FP_FRAC_DISASSEMBLE_2(X, r, rsize) \ - do { \ - X##_f0 = r; \ - X##_f1 = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE); \ - } while (0) + do \ + { \ + X##_f0 = r; \ + X##_f1 = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE); \ + } \ + while (0) /* * Convert FP values between word sizes diff --git a/soft-fp/op-4.h b/soft-fp/op-4.h index db4197d..18b7cfd 100644 --- a/soft-fp/op-4.h +++ b/soft-fp/op-4.h @@ -39,46 +39,50 @@ #define _FP_FRAC_LOW_4(X) (X##_f[0]) #define _FP_FRAC_WORD_4(X,w) (X##_f[w]) -#define _FP_FRAC_SLL_4(X,N) \ - do { \ - _FP_I_TYPE _up, _down, _skip, _i; \ - _skip = (N) / _FP_W_TYPE_SIZE; \ - _up = (N) % _FP_W_TYPE_SIZE; \ - _down = _FP_W_TYPE_SIZE - _up; \ - if (!_up) \ - for (_i = 3; _i >= _skip; --_i) \ - X##_f[_i] = X##_f[_i-_skip]; \ - else \ - { \ - for (_i = 3; _i > _skip; --_i) \ - X##_f[_i] = X##_f[_i-_skip] << _up \ - | X##_f[_i-_skip-1] >> _down; \ - X##_f[_i--] = X##_f[0] << _up; \ - } \ - for (; _i >= 0; --_i) \ - X##_f[_i] = 0; \ - } while (0) +#define _FP_FRAC_SLL_4(X,N) \ + do \ + { \ + _FP_I_TYPE _up, _down, _skip, _i; \ + _skip = (N) / _FP_W_TYPE_SIZE; \ + _up = (N) % _FP_W_TYPE_SIZE; \ + _down = _FP_W_TYPE_SIZE - _up; \ + if (!_up) \ + for (_i = 3; _i >= _skip; --_i) \ + X##_f[_i] = X##_f[_i-_skip]; \ + else \ + { \ + for (_i = 3; _i > _skip; --_i) \ + X##_f[_i] = (X##_f[_i-_skip] << _up \ + | X##_f[_i-_skip-1] >> _down); \ + X##_f[_i--] = X##_f[0] << _up; \ + } \ + for (; _i >= 0; --_i) \ + X##_f[_i] = 0; \ + } \ + while (0) /* This one was broken too */ -#define _FP_FRAC_SRL_4(X,N) \ - do { \ - _FP_I_TYPE _up, _down, _skip, _i; \ - _skip = (N) / _FP_W_TYPE_SIZE; \ - _down = (N) % _FP_W_TYPE_SIZE; \ - _up = _FP_W_TYPE_SIZE - _down; \ - if (!_down) \ - for (_i = 0; _i <= 3-_skip; ++_i) \ - X##_f[_i] = X##_f[_i+_skip]; \ - else \ - { \ - for (_i = 0; _i < 3-_skip; ++_i) \ - X##_f[_i] = X##_f[_i+_skip] >> _down \ - | X##_f[_i+_skip+1] << _up; \ - X##_f[_i++] = X##_f[3] >> _down; \ - } \ - for (; _i < 4; ++_i) \ - X##_f[_i] = 0; \ - } while (0) +#define _FP_FRAC_SRL_4(X,N) \ + do \ + { \ + _FP_I_TYPE _up, _down, _skip, _i; \ + _skip = (N) / _FP_W_TYPE_SIZE; \ + _down = (N) % _FP_W_TYPE_SIZE; \ + _up = _FP_W_TYPE_SIZE - _down; \ + if (!_down) \ + for (_i = 0; _i <= 3-_skip; ++_i) \ + X##_f[_i] = X##_f[_i+_skip]; \ + else \ + { \ + for (_i = 0; _i < 3-_skip; ++_i) \ + X##_f[_i] = (X##_f[_i+_skip] >> _down \ + | X##_f[_i+_skip+1] << _up); \ + X##_f[_i++] = X##_f[3] >> _down; \ + } \ + for (; _i < 4; ++_i) \ + X##_f[_i] = 0; \ + } \ + while (0) /* Right shift with sticky-lsb. @@ -87,36 +91,40 @@ * were one then we always set the LSbit. */ #define _FP_FRAC_SRST_4(X,S,N,size) \ - do { \ - _FP_I_TYPE _up, _down, _skip, _i; \ - _FP_W_TYPE _s; \ - _skip = (N) / _FP_W_TYPE_SIZE; \ - _down = (N) % _FP_W_TYPE_SIZE; \ - _up = _FP_W_TYPE_SIZE - _down; \ - for (_s = _i = 0; _i < _skip; ++_i) \ - _s |= X##_f[_i]; \ - if (!_down) \ - for (_i = 0; _i <= 3-_skip; ++_i) \ - X##_f[_i] = X##_f[_i+_skip]; \ - else \ - { \ - _s |= X##_f[_i] << _up; \ - for (_i = 0; _i < 3-_skip; ++_i) \ - X##_f[_i] = X##_f[_i+_skip] >> _down \ - | X##_f[_i+_skip+1] << _up; \ - X##_f[_i++] = X##_f[3] >> _down; \ - } \ - for (; _i < 4; ++_i) \ - X##_f[_i] = 0; \ - S = (_s != 0); \ - } while (0) + do \ + { \ + _FP_I_TYPE _up, _down, _skip, _i; \ + _FP_W_TYPE _s; \ + _skip = (N) / _FP_W_TYPE_SIZE; \ + _down = (N) % _FP_W_TYPE_SIZE; \ + _up = _FP_W_TYPE_SIZE - _down; \ + for (_s = _i = 0; _i < _skip; ++_i) \ + _s |= X##_f[_i]; \ + if (!_down) \ + for (_i = 0; _i <= 3-_skip; ++_i) \ + X##_f[_i] = X##_f[_i+_skip]; \ + else \ + { \ + _s |= X##_f[_i] << _up; \ + for (_i = 0; _i < 3-_skip; ++_i) \ + X##_f[_i] = (X##_f[_i+_skip] >> _down \ + | X##_f[_i+_skip+1] << _up); \ + X##_f[_i++] = X##_f[3] >> _down; \ + } \ + for (; _i < 4; ++_i) \ + X##_f[_i] = 0; \ + S = (_s != 0); \ + } \ + while (0) #define _FP_FRAC_SRS_4(X,N,size) \ - do { \ - int _sticky; \ - _FP_FRAC_SRST_4(X, _sticky, N, size); \ - X##_f[0] |= _sticky; \ - } while (0) + do \ + { \ + int _sticky; \ + _FP_FRAC_SRST_4(X, _sticky, N, size); \ + X##_f[0] |= _sticky; \ + } \ + while (0) #define _FP_FRAC_ADD_4(R,X,Y) \ __FP_FRAC_ADD_4(R##_f[3], R##_f[2], R##_f[1], R##_f[0], \ @@ -147,100 +155,107 @@ #define _FP_FRAC_CLEAR_OVERP_4(fs,X) (_FP_FRAC_HIGH_##fs(X) &= ~_FP_OVERFLOW_##fs) #define _FP_FRAC_EQ_4(X,Y) \ - (X##_f[0] == Y##_f[0] && X##_f[1] == Y##_f[1] \ - && X##_f[2] == Y##_f[2] && X##_f[3] == Y##_f[3]) + (X##_f[0] == Y##_f[0] && X##_f[1] == Y##_f[1] \ + && X##_f[2] == Y##_f[2] && X##_f[3] == Y##_f[3]) #define _FP_FRAC_GT_4(X,Y) \ - (X##_f[3] > Y##_f[3] || \ - (X##_f[3] == Y##_f[3] && (X##_f[2] > Y##_f[2] || \ - (X##_f[2] == Y##_f[2] && (X##_f[1] > Y##_f[1] || \ - (X##_f[1] == Y##_f[1] && X##_f[0] > Y##_f[0]) \ - )) \ - )) \ - ) + (X##_f[3] > Y##_f[3] \ + || (X##_f[3] == Y##_f[3] \ + && (X##_f[2] > Y##_f[2] \ + || (X##_f[2] == Y##_f[2] \ + && (X##_f[1] > Y##_f[1] \ + || (X##_f[1] == Y##_f[1] \ + && X##_f[0] > Y##_f[0])))))) #define _FP_FRAC_GE_4(X,Y) \ - (X##_f[3] > Y##_f[3] || \ - (X##_f[3] == Y##_f[3] && (X##_f[2] > Y##_f[2] || \ - (X##_f[2] == Y##_f[2] && (X##_f[1] > Y##_f[1] || \ - (X##_f[1] == Y##_f[1] && X##_f[0] >= Y##_f[0]) \ - )) \ - )) \ - ) - - -#define _FP_FRAC_CLZ_4(R,X) \ - do { \ - if (X##_f[3]) \ - { \ - __FP_CLZ(R,X##_f[3]); \ - } \ - else if (X##_f[2]) \ - { \ - __FP_CLZ(R,X##_f[2]); \ - R += _FP_W_TYPE_SIZE; \ - } \ - else if (X##_f[1]) \ - { \ - __FP_CLZ(R,X##_f[1]); \ - R += _FP_W_TYPE_SIZE*2; \ - } \ - else \ - { \ - __FP_CLZ(R,X##_f[0]); \ - R += _FP_W_TYPE_SIZE*3; \ - } \ - } while(0) - - -#define _FP_UNPACK_RAW_4(fs, X, val) \ - do { \ - union _FP_UNION_##fs _flo; _flo.flt = (val); \ - X##_f[0] = _flo.bits.frac0; \ - X##_f[1] = _flo.bits.frac1; \ - X##_f[2] = _flo.bits.frac2; \ - X##_f[3] = _flo.bits.frac3; \ - X##_e = _flo.bits.exp; \ - X##_s = _flo.bits.sign; \ - } while (0) - -#define _FP_UNPACK_RAW_4_P(fs, X, val) \ - do { \ - union _FP_UNION_##fs *_flo = \ - (union _FP_UNION_##fs *)(val); \ - \ - X##_f[0] = _flo->bits.frac0; \ - X##_f[1] = _flo->bits.frac1; \ - X##_f[2] = _flo->bits.frac2; \ - X##_f[3] = _flo->bits.frac3; \ - X##_e = _flo->bits.exp; \ - X##_s = _flo->bits.sign; \ - } while (0) - -#define _FP_PACK_RAW_4(fs, val, X) \ - do { \ - union _FP_UNION_##fs _flo; \ - _flo.bits.frac0 = X##_f[0]; \ - _flo.bits.frac1 = X##_f[1]; \ - _flo.bits.frac2 = X##_f[2]; \ - _flo.bits.frac3 = X##_f[3]; \ - _flo.bits.exp = X##_e; \ - _flo.bits.sign = X##_s; \ - (val) = _flo.flt; \ - } while (0) - -#define _FP_PACK_RAW_4_P(fs, val, X) \ - do { \ - union _FP_UNION_##fs *_flo = \ - (union _FP_UNION_##fs *)(val); \ - \ - _flo->bits.frac0 = X##_f[0]; \ - _flo->bits.frac1 = X##_f[1]; \ - _flo->bits.frac2 = X##_f[2]; \ - _flo->bits.frac3 = X##_f[3]; \ - _flo->bits.exp = X##_e; \ - _flo->bits.sign = X##_s; \ - } while (0) + (X##_f[3] > Y##_f[3] \ + || (X##_f[3] == Y##_f[3] \ + && (X##_f[2] > Y##_f[2] \ + || (X##_f[2] == Y##_f[2] \ + && (X##_f[1] > Y##_f[1] \ + || (X##_f[1] == Y##_f[1] \ + && X##_f[0] >= Y##_f[0])))))) + + +#define _FP_FRAC_CLZ_4(R,X) \ + do \ + { \ + if (X##_f[3]) \ + __FP_CLZ(R,X##_f[3]); \ + else if (X##_f[2]) \ + { \ + __FP_CLZ(R,X##_f[2]); \ + R += _FP_W_TYPE_SIZE; \ + } \ + else if (X##_f[1]) \ + { \ + __FP_CLZ(R,X##_f[1]); \ + R += _FP_W_TYPE_SIZE*2; \ + } \ + else \ + { \ + __FP_CLZ(R,X##_f[0]); \ + R += _FP_W_TYPE_SIZE*3; \ + } \ + } \ + while(0) + + +#define _FP_UNPACK_RAW_4(fs, X, val) \ + do \ + { \ + union _FP_UNION_##fs _flo; \ + _flo.flt = (val); \ + X##_f[0] = _flo.bits.frac0; \ + X##_f[1] = _flo.bits.frac1; \ + X##_f[2] = _flo.bits.frac2; \ + X##_f[3] = _flo.bits.frac3; \ + X##_e = _flo.bits.exp; \ + X##_s = _flo.bits.sign; \ + } \ + while (0) + +#define _FP_UNPACK_RAW_4_P(fs, X, val) \ + do \ + { \ + union _FP_UNION_##fs *_flo = (union _FP_UNION_##fs *)(val); \ + \ + X##_f[0] = _flo->bits.frac0; \ + X##_f[1] = _flo->bits.frac1; \ + X##_f[2] = _flo->bits.frac2; \ + X##_f[3] = _flo->bits.frac3; \ + X##_e = _flo->bits.exp; \ + X##_s = _flo->bits.sign; \ + } \ + while (0) + +#define _FP_PACK_RAW_4(fs, val, X) \ + do \ + { \ + union _FP_UNION_##fs _flo; \ + _flo.bits.frac0 = X##_f[0]; \ + _flo.bits.frac1 = X##_f[1]; \ + _flo.bits.frac2 = X##_f[2]; \ + _flo.bits.frac3 = X##_f[3]; \ + _flo.bits.exp = X##_e; \ + _flo.bits.sign = X##_s; \ + (val) = _flo.flt; \ + } \ + while (0) + +#define _FP_PACK_RAW_4_P(fs, val, X) \ + do \ + { \ + union _FP_UNION_##fs *_flo = (union _FP_UNION_##fs *)(val); \ + \ + _flo->bits.frac0 = X##_f[0]; \ + _flo->bits.frac1 = X##_f[1]; \ + _flo->bits.frac2 = X##_f[2]; \ + _flo->bits.frac3 = X##_f[3]; \ + _flo->bits.exp = X##_e; \ + _flo->bits.sign = X##_s; \ + } \ + while (0) /* * Multiplication algorithms: @@ -248,200 +263,216 @@ /* Given a 1W * 1W => 2W primitive, do the extended multiplication. */ -#define _FP_MUL_MEAT_DW_4_wide(wfracbits, R, X, Y, doit) \ - do { \ - _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c); \ - _FP_FRAC_DECL_2(_d); _FP_FRAC_DECL_2(_e); _FP_FRAC_DECL_2(_f); \ - \ - doit(_FP_FRAC_WORD_8(R,1), _FP_FRAC_WORD_8(R,0), X##_f[0], Y##_f[0]); \ - doit(_b_f1, _b_f0, X##_f[0], Y##_f[1]); \ - doit(_c_f1, _c_f0, X##_f[1], Y##_f[0]); \ - doit(_d_f1, _d_f0, X##_f[1], Y##_f[1]); \ - doit(_e_f1, _e_f0, X##_f[0], Y##_f[2]); \ - doit(_f_f1, _f_f0, X##_f[2], Y##_f[0]); \ - __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,3),_FP_FRAC_WORD_8(R,2), \ - _FP_FRAC_WORD_8(R,1), 0,_b_f1,_b_f0, \ - 0,0,_FP_FRAC_WORD_8(R,1)); \ - __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,3),_FP_FRAC_WORD_8(R,2), \ - _FP_FRAC_WORD_8(R,1), 0,_c_f1,_c_f0, \ - _FP_FRAC_WORD_8(R,3),_FP_FRAC_WORD_8(R,2), \ - _FP_FRAC_WORD_8(R,1)); \ - __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,4),_FP_FRAC_WORD_8(R,3), \ - _FP_FRAC_WORD_8(R,2), 0,_d_f1,_d_f0, \ - 0,_FP_FRAC_WORD_8(R,3),_FP_FRAC_WORD_8(R,2)); \ - __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,4),_FP_FRAC_WORD_8(R,3), \ - _FP_FRAC_WORD_8(R,2), 0,_e_f1,_e_f0, \ - _FP_FRAC_WORD_8(R,4),_FP_FRAC_WORD_8(R,3), \ - _FP_FRAC_WORD_8(R,2)); \ - __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,4),_FP_FRAC_WORD_8(R,3), \ - _FP_FRAC_WORD_8(R,2), 0,_f_f1,_f_f0, \ - _FP_FRAC_WORD_8(R,4),_FP_FRAC_WORD_8(R,3), \ - _FP_FRAC_WORD_8(R,2)); \ - doit(_b_f1, _b_f0, X##_f[0], Y##_f[3]); \ - doit(_c_f1, _c_f0, X##_f[3], Y##_f[0]); \ - doit(_d_f1, _d_f0, X##_f[1], Y##_f[2]); \ - doit(_e_f1, _e_f0, X##_f[2], Y##_f[1]); \ - __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,5),_FP_FRAC_WORD_8(R,4), \ - _FP_FRAC_WORD_8(R,3), 0,_b_f1,_b_f0, \ - 0,_FP_FRAC_WORD_8(R,4),_FP_FRAC_WORD_8(R,3)); \ - __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,5),_FP_FRAC_WORD_8(R,4), \ - _FP_FRAC_WORD_8(R,3), 0,_c_f1,_c_f0, \ - _FP_FRAC_WORD_8(R,5),_FP_FRAC_WORD_8(R,4), \ - _FP_FRAC_WORD_8(R,3)); \ - __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,5),_FP_FRAC_WORD_8(R,4), \ - _FP_FRAC_WORD_8(R,3), 0,_d_f1,_d_f0, \ - _FP_FRAC_WORD_8(R,5),_FP_FRAC_WORD_8(R,4), \ - _FP_FRAC_WORD_8(R,3)); \ - __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,5),_FP_FRAC_WORD_8(R,4), \ - _FP_FRAC_WORD_8(R,3), 0,_e_f1,_e_f0, \ - _FP_FRAC_WORD_8(R,5),_FP_FRAC_WORD_8(R,4), \ - _FP_FRAC_WORD_8(R,3)); \ - doit(_b_f1, _b_f0, X##_f[2], Y##_f[2]); \ - doit(_c_f1, _c_f0, X##_f[1], Y##_f[3]); \ - doit(_d_f1, _d_f0, X##_f[3], Y##_f[1]); \ - doit(_e_f1, _e_f0, X##_f[2], Y##_f[3]); \ - doit(_f_f1, _f_f0, X##_f[3], Y##_f[2]); \ - __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,6),_FP_FRAC_WORD_8(R,5), \ - _FP_FRAC_WORD_8(R,4), 0,_b_f1,_b_f0, \ - 0,_FP_FRAC_WORD_8(R,5),_FP_FRAC_WORD_8(R,4)); \ - __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,6),_FP_FRAC_WORD_8(R,5), \ - _FP_FRAC_WORD_8(R,4), 0,_c_f1,_c_f0, \ - _FP_FRAC_WORD_8(R,6),_FP_FRAC_WORD_8(R,5), \ - _FP_FRAC_WORD_8(R,4)); \ - __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,6),_FP_FRAC_WORD_8(R,5), \ - _FP_FRAC_WORD_8(R,4), 0,_d_f1,_d_f0, \ - _FP_FRAC_WORD_8(R,6),_FP_FRAC_WORD_8(R,5), \ - _FP_FRAC_WORD_8(R,4)); \ - __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,7),_FP_FRAC_WORD_8(R,6), \ - _FP_FRAC_WORD_8(R,5), 0,_e_f1,_e_f0, \ - 0,_FP_FRAC_WORD_8(R,6),_FP_FRAC_WORD_8(R,5)); \ - __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,7),_FP_FRAC_WORD_8(R,6), \ - _FP_FRAC_WORD_8(R,5), 0,_f_f1,_f_f0, \ - _FP_FRAC_WORD_8(R,7),_FP_FRAC_WORD_8(R,6), \ - _FP_FRAC_WORD_8(R,5)); \ - doit(_b_f1, _b_f0, X##_f[3], Y##_f[3]); \ - __FP_FRAC_ADD_2(_FP_FRAC_WORD_8(R,7),_FP_FRAC_WORD_8(R,6), \ - _b_f1,_b_f0, \ - _FP_FRAC_WORD_8(R,7),_FP_FRAC_WORD_8(R,6)); \ - } while (0) - -#define _FP_MUL_MEAT_4_wide(wfracbits, R, X, Y, doit) \ - do { \ - _FP_FRAC_DECL_8(_z); \ - \ - _FP_MUL_MEAT_DW_4_wide(wfracbits, _z, X, Y, doit); \ - \ - /* Normalize since we know where the msb of the multiplicands \ - were (bit B), we know that the msb of the of the product is \ - at either 2B or 2B-1. */ \ - _FP_FRAC_SRS_8(_z, wfracbits-1, 2*wfracbits); \ - __FP_FRAC_SET_4(R, _FP_FRAC_WORD_8(_z,3), _FP_FRAC_WORD_8(_z,2), \ - _FP_FRAC_WORD_8(_z,1), _FP_FRAC_WORD_8(_z,0)); \ - } while (0) - -#define _FP_MUL_MEAT_DW_4_gmp(wfracbits, R, X, Y) \ - do { \ - mpn_mul_n(R##_f, _x_f, _y_f, 4); \ - } while (0) - -#define _FP_MUL_MEAT_4_gmp(wfracbits, R, X, Y) \ - do { \ - _FP_FRAC_DECL_8(_z); \ - \ - _FP_MUL_MEAT_DW_4_gmp(wfracbits, _z, X, Y); \ - \ - /* Normalize since we know where the msb of the multiplicands \ - were (bit B), we know that the msb of the of the product is \ - at either 2B or 2B-1. */ \ - _FP_FRAC_SRS_8(_z, wfracbits-1, 2*wfracbits); \ - __FP_FRAC_SET_4(R, _FP_FRAC_WORD_8(_z,3), _FP_FRAC_WORD_8(_z,2), \ - _FP_FRAC_WORD_8(_z,1), _FP_FRAC_WORD_8(_z,0)); \ - } while (0) +#define _FP_MUL_MEAT_DW_4_wide(wfracbits, R, X, Y, doit) \ + do \ + { \ + _FP_FRAC_DECL_2(_b); \ + _FP_FRAC_DECL_2(_c); \ + _FP_FRAC_DECL_2(_d); \ + _FP_FRAC_DECL_2(_e); \ + _FP_FRAC_DECL_2(_f); \ + \ + doit(_FP_FRAC_WORD_8(R,1), _FP_FRAC_WORD_8(R,0), X##_f[0], Y##_f[0]); \ + doit(_b_f1, _b_f0, X##_f[0], Y##_f[1]); \ + doit(_c_f1, _c_f0, X##_f[1], Y##_f[0]); \ + doit(_d_f1, _d_f0, X##_f[1], Y##_f[1]); \ + doit(_e_f1, _e_f0, X##_f[0], Y##_f[2]); \ + doit(_f_f1, _f_f0, X##_f[2], Y##_f[0]); \ + __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,3),_FP_FRAC_WORD_8(R,2), \ + _FP_FRAC_WORD_8(R,1), 0,_b_f1,_b_f0, \ + 0,0,_FP_FRAC_WORD_8(R,1)); \ + __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,3),_FP_FRAC_WORD_8(R,2), \ + _FP_FRAC_WORD_8(R,1), 0,_c_f1,_c_f0, \ + _FP_FRAC_WORD_8(R,3),_FP_FRAC_WORD_8(R,2), \ + _FP_FRAC_WORD_8(R,1)); \ + __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,4),_FP_FRAC_WORD_8(R,3), \ + _FP_FRAC_WORD_8(R,2), 0,_d_f1,_d_f0, \ + 0,_FP_FRAC_WORD_8(R,3),_FP_FRAC_WORD_8(R,2)); \ + __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,4),_FP_FRAC_WORD_8(R,3), \ + _FP_FRAC_WORD_8(R,2), 0,_e_f1,_e_f0, \ + _FP_FRAC_WORD_8(R,4),_FP_FRAC_WORD_8(R,3), \ + _FP_FRAC_WORD_8(R,2)); \ + __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,4),_FP_FRAC_WORD_8(R,3), \ + _FP_FRAC_WORD_8(R,2), 0,_f_f1,_f_f0, \ + _FP_FRAC_WORD_8(R,4),_FP_FRAC_WORD_8(R,3), \ + _FP_FRAC_WORD_8(R,2)); \ + doit(_b_f1, _b_f0, X##_f[0], Y##_f[3]); \ + doit(_c_f1, _c_f0, X##_f[3], Y##_f[0]); \ + doit(_d_f1, _d_f0, X##_f[1], Y##_f[2]); \ + doit(_e_f1, _e_f0, X##_f[2], Y##_f[1]); \ + __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,5),_FP_FRAC_WORD_8(R,4), \ + _FP_FRAC_WORD_8(R,3), 0,_b_f1,_b_f0, \ + 0,_FP_FRAC_WORD_8(R,4),_FP_FRAC_WORD_8(R,3)); \ + __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,5),_FP_FRAC_WORD_8(R,4), \ + _FP_FRAC_WORD_8(R,3), 0,_c_f1,_c_f0, \ + _FP_FRAC_WORD_8(R,5),_FP_FRAC_WORD_8(R,4), \ + _FP_FRAC_WORD_8(R,3)); \ + __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,5),_FP_FRAC_WORD_8(R,4), \ + _FP_FRAC_WORD_8(R,3), 0,_d_f1,_d_f0, \ + _FP_FRAC_WORD_8(R,5),_FP_FRAC_WORD_8(R,4), \ + _FP_FRAC_WORD_8(R,3)); \ + __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,5),_FP_FRAC_WORD_8(R,4), \ + _FP_FRAC_WORD_8(R,3), 0,_e_f1,_e_f0, \ + _FP_FRAC_WORD_8(R,5),_FP_FRAC_WORD_8(R,4), \ + _FP_FRAC_WORD_8(R,3)); \ + doit(_b_f1, _b_f0, X##_f[2], Y##_f[2]); \ + doit(_c_f1, _c_f0, X##_f[1], Y##_f[3]); \ + doit(_d_f1, _d_f0, X##_f[3], Y##_f[1]); \ + doit(_e_f1, _e_f0, X##_f[2], Y##_f[3]); \ + doit(_f_f1, _f_f0, X##_f[3], Y##_f[2]); \ + __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,6),_FP_FRAC_WORD_8(R,5), \ + _FP_FRAC_WORD_8(R,4), 0,_b_f1,_b_f0, \ + 0,_FP_FRAC_WORD_8(R,5),_FP_FRAC_WORD_8(R,4)); \ + __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,6),_FP_FRAC_WORD_8(R,5), \ + _FP_FRAC_WORD_8(R,4), 0,_c_f1,_c_f0, \ + _FP_FRAC_WORD_8(R,6),_FP_FRAC_WORD_8(R,5), \ + _FP_FRAC_WORD_8(R,4)); \ + __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,6),_FP_FRAC_WORD_8(R,5), \ + _FP_FRAC_WORD_8(R,4), 0,_d_f1,_d_f0, \ + _FP_FRAC_WORD_8(R,6),_FP_FRAC_WORD_8(R,5), \ + _FP_FRAC_WORD_8(R,4)); \ + __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,7),_FP_FRAC_WORD_8(R,6), \ + _FP_FRAC_WORD_8(R,5), 0,_e_f1,_e_f0, \ + 0,_FP_FRAC_WORD_8(R,6),_FP_FRAC_WORD_8(R,5)); \ + __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(R,7),_FP_FRAC_WORD_8(R,6), \ + _FP_FRAC_WORD_8(R,5), 0,_f_f1,_f_f0, \ + _FP_FRAC_WORD_8(R,7),_FP_FRAC_WORD_8(R,6), \ + _FP_FRAC_WORD_8(R,5)); \ + doit(_b_f1, _b_f0, X##_f[3], Y##_f[3]); \ + __FP_FRAC_ADD_2(_FP_FRAC_WORD_8(R,7),_FP_FRAC_WORD_8(R,6), \ + _b_f1,_b_f0, \ + _FP_FRAC_WORD_8(R,7),_FP_FRAC_WORD_8(R,6)); \ + } \ + while (0) + +#define _FP_MUL_MEAT_4_wide(wfracbits, R, X, Y, doit) \ + do \ + { \ + _FP_FRAC_DECL_8(_z); \ + \ + _FP_MUL_MEAT_DW_4_wide(wfracbits, _z, X, Y, doit); \ + \ + /* Normalize since we know where the msb of the multiplicands \ + were (bit B), we know that the msb of the of the product is \ + at either 2B or 2B-1. */ \ + _FP_FRAC_SRS_8(_z, wfracbits-1, 2*wfracbits); \ + __FP_FRAC_SET_4(R, _FP_FRAC_WORD_8(_z,3), _FP_FRAC_WORD_8(_z,2), \ + _FP_FRAC_WORD_8(_z,1), _FP_FRAC_WORD_8(_z,0)); \ + } \ + while (0) + +#define _FP_MUL_MEAT_DW_4_gmp(wfracbits, R, X, Y) \ + do \ + { \ + mpn_mul_n(R##_f, _x_f, _y_f, 4); \ + } \ + while (0) + +#define _FP_MUL_MEAT_4_gmp(wfracbits, R, X, Y) \ + do \ + { \ + _FP_FRAC_DECL_8(_z); \ + \ + _FP_MUL_MEAT_DW_4_gmp(wfracbits, _z, X, Y); \ + \ + /* Normalize since we know where the msb of the multiplicands \ + were (bit B), we know that the msb of the of the product is \ + at either 2B or 2B-1. */ \ + _FP_FRAC_SRS_8(_z, wfracbits-1, 2*wfracbits); \ + __FP_FRAC_SET_4(R, _FP_FRAC_WORD_8(_z,3), _FP_FRAC_WORD_8(_z,2), \ + _FP_FRAC_WORD_8(_z,1), _FP_FRAC_WORD_8(_z,0)); \ + } \ + while (0) /* * Helper utility for _FP_DIV_MEAT_4_udiv: * pppp = m * nnn */ -#define umul_ppppmnnn(p3,p2,p1,p0,m,n2,n1,n0) \ - do { \ - UWtype _t; \ - umul_ppmm(p1,p0,m,n0); \ - umul_ppmm(p2,_t,m,n1); \ - __FP_FRAC_ADDI_2(p2,p1,_t); \ - umul_ppmm(p3,_t,m,n2); \ - __FP_FRAC_ADDI_2(p3,p2,_t); \ - } while (0) +#define umul_ppppmnnn(p3,p2,p1,p0,m,n2,n1,n0) \ + do \ + { \ + UWtype _t; \ + umul_ppmm(p1,p0,m,n0); \ + umul_ppmm(p2,_t,m,n1); \ + __FP_FRAC_ADDI_2(p2,p1,_t); \ + umul_ppmm(p3,_t,m,n2); \ + __FP_FRAC_ADDI_2(p3,p2,_t); \ + } \ + while (0) /* * Division algorithms: */ -#define _FP_DIV_MEAT_4_udiv(fs, R, X, Y) \ - do { \ - int _i; \ - _FP_FRAC_DECL_4(_n); _FP_FRAC_DECL_4(_m); \ - _FP_FRAC_SET_4(_n, _FP_ZEROFRAC_4); \ - if (_FP_FRAC_GE_4(X, Y)) \ - { \ - _n_f[3] = X##_f[0] << (_FP_W_TYPE_SIZE - 1); \ - _FP_FRAC_SRL_4(X, 1); \ - } \ - else \ - R##_e--; \ - \ - /* Normalize, i.e. make the most significant bit of the \ - denominator set. */ \ - _FP_FRAC_SLL_4(Y, _FP_WFRACXBITS_##fs); \ - \ - for (_i = 3; ; _i--) \ - { \ - if (X##_f[3] == Y##_f[3]) \ - { \ - /* This is a special case, not an optimization \ - (X##_f[3]/Y##_f[3] would not fit into UWtype). \ - As X## is guaranteed to be < Y, R##_f[_i] can be either \ - (UWtype)-1 or (UWtype)-2. */ \ - R##_f[_i] = -1; \ - if (!_i) \ - break; \ - __FP_FRAC_SUB_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0], \ - Y##_f[2], Y##_f[1], Y##_f[0], 0, \ - X##_f[2], X##_f[1], X##_f[0], _n_f[_i]); \ - _FP_FRAC_SUB_4(X, Y, X); \ - if (X##_f[3] > Y##_f[3]) \ - { \ - R##_f[_i] = -2; \ - _FP_FRAC_ADD_4(X, Y, X); \ - } \ - } \ - else \ - { \ - udiv_qrnnd(R##_f[_i], X##_f[3], X##_f[3], X##_f[2], Y##_f[3]); \ - umul_ppppmnnn(_m_f[3], _m_f[2], _m_f[1], _m_f[0], \ - R##_f[_i], Y##_f[2], Y##_f[1], Y##_f[0]); \ - X##_f[2] = X##_f[1]; \ - X##_f[1] = X##_f[0]; \ - X##_f[0] = _n_f[_i]; \ - if (_FP_FRAC_GT_4(_m, X)) \ - { \ - R##_f[_i]--; \ - _FP_FRAC_ADD_4(X, Y, X); \ - if (_FP_FRAC_GE_4(X, Y) && _FP_FRAC_GT_4(_m, X)) \ - { \ - R##_f[_i]--; \ - _FP_FRAC_ADD_4(X, Y, X); \ - } \ - } \ - _FP_FRAC_DEC_4(X, _m); \ - if (!_i) \ - { \ - if (!_FP_FRAC_EQ_4(X, _m)) \ - R##_f[0] |= _FP_WORK_STICKY; \ - break; \ - } \ - } \ - } \ - } while (0) +#define _FP_DIV_MEAT_4_udiv(fs, R, X, Y) \ + do \ + { \ + int _i; \ + _FP_FRAC_DECL_4(_n); \ + _FP_FRAC_DECL_4(_m); \ + _FP_FRAC_SET_4(_n, _FP_ZEROFRAC_4); \ + if (_FP_FRAC_GE_4(X, Y)) \ + { \ + _n_f[3] = X##_f[0] << (_FP_W_TYPE_SIZE - 1); \ + _FP_FRAC_SRL_4(X, 1); \ + } \ + else \ + R##_e--; \ + \ + /* Normalize, i.e. make the most significant bit of the \ + denominator set. */ \ + _FP_FRAC_SLL_4(Y, _FP_WFRACXBITS_##fs); \ + \ + for (_i = 3; ; _i--) \ + { \ + if (X##_f[3] == Y##_f[3]) \ + { \ + /* This is a special case, not an optimization \ + (X##_f[3]/Y##_f[3] would not fit into UWtype). \ + As X## is guaranteed to be < Y, R##_f[_i] can be either \ + (UWtype)-1 or (UWtype)-2. */ \ + R##_f[_i] = -1; \ + if (!_i) \ + break; \ + __FP_FRAC_SUB_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0], \ + Y##_f[2], Y##_f[1], Y##_f[0], 0, \ + X##_f[2], X##_f[1], X##_f[0], _n_f[_i]); \ + _FP_FRAC_SUB_4(X, Y, X); \ + if (X##_f[3] > Y##_f[3]) \ + { \ + R##_f[_i] = -2; \ + _FP_FRAC_ADD_4(X, Y, X); \ + } \ + } \ + else \ + { \ + udiv_qrnnd(R##_f[_i], X##_f[3], X##_f[3], X##_f[2], Y##_f[3]); \ + umul_ppppmnnn(_m_f[3], _m_f[2], _m_f[1], _m_f[0], \ + R##_f[_i], Y##_f[2], Y##_f[1], Y##_f[0]); \ + X##_f[2] = X##_f[1]; \ + X##_f[1] = X##_f[0]; \ + X##_f[0] = _n_f[_i]; \ + if (_FP_FRAC_GT_4(_m, X)) \ + { \ + R##_f[_i]--; \ + _FP_FRAC_ADD_4(X, Y, X); \ + if (_FP_FRAC_GE_4(X, Y) && _FP_FRAC_GT_4(_m, X)) \ + { \ + R##_f[_i]--; \ + _FP_FRAC_ADD_4(X, Y, X); \ + } \ + } \ + _FP_FRAC_DEC_4(X, _m); \ + if (!_i) \ + { \ + if (!_FP_FRAC_EQ_4(X, _m)) \ + R##_f[0] |= _FP_WORK_STICKY; \ + break; \ + } \ + } \ + } \ + } \ + while (0) /* @@ -450,83 +481,87 @@ * should be added for those machines where division is fast. */ -#define _FP_SQRT_MEAT_4(R, S, T, X, q) \ - do { \ - while (q) \ - { \ - T##_f[3] = S##_f[3] + q; \ - if (T##_f[3] <= X##_f[3]) \ - { \ - S##_f[3] = T##_f[3] + q; \ - X##_f[3] -= T##_f[3]; \ - R##_f[3] += q; \ - } \ - _FP_FRAC_SLL_4(X, 1); \ - q >>= 1; \ - } \ - q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ - while (q) \ - { \ - T##_f[2] = S##_f[2] + q; \ - T##_f[3] = S##_f[3]; \ - if (T##_f[3] < X##_f[3] || \ - (T##_f[3] == X##_f[3] && T##_f[2] <= X##_f[2])) \ - { \ - S##_f[2] = T##_f[2] + q; \ - S##_f[3] += (T##_f[2] > S##_f[2]); \ - __FP_FRAC_DEC_2(X##_f[3], X##_f[2], \ - T##_f[3], T##_f[2]); \ - R##_f[2] += q; \ - } \ - _FP_FRAC_SLL_4(X, 1); \ - q >>= 1; \ - } \ - q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ - while (q) \ - { \ - T##_f[1] = S##_f[1] + q; \ - T##_f[2] = S##_f[2]; \ - T##_f[3] = S##_f[3]; \ - if (T##_f[3] < X##_f[3] || \ - (T##_f[3] == X##_f[3] && (T##_f[2] < X##_f[2] || \ - (T##_f[2] == X##_f[2] && T##_f[1] <= X##_f[1])))) \ - { \ - S##_f[1] = T##_f[1] + q; \ - S##_f[2] += (T##_f[1] > S##_f[1]); \ - S##_f[3] += (T##_f[2] > S##_f[2]); \ - __FP_FRAC_DEC_3(X##_f[3], X##_f[2], X##_f[1], \ - T##_f[3], T##_f[2], T##_f[1]); \ - R##_f[1] += q; \ - } \ - _FP_FRAC_SLL_4(X, 1); \ - q >>= 1; \ - } \ - q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ - while (q != _FP_WORK_ROUND) \ - { \ - T##_f[0] = S##_f[0] + q; \ - T##_f[1] = S##_f[1]; \ - T##_f[2] = S##_f[2]; \ - T##_f[3] = S##_f[3]; \ - if (_FP_FRAC_GE_4(X,T)) \ - { \ - S##_f[0] = T##_f[0] + q; \ - S##_f[1] += (T##_f[0] > S##_f[0]); \ - S##_f[2] += (T##_f[1] > S##_f[1]); \ - S##_f[3] += (T##_f[2] > S##_f[2]); \ - _FP_FRAC_DEC_4(X, T); \ - R##_f[0] += q; \ - } \ - _FP_FRAC_SLL_4(X, 1); \ - q >>= 1; \ - } \ - if (!_FP_FRAC_ZEROP_4(X)) \ - { \ - if (_FP_FRAC_GT_4(X,S)) \ - R##_f[0] |= _FP_WORK_ROUND; \ - R##_f[0] |= _FP_WORK_STICKY; \ - } \ - } while (0) +#define _FP_SQRT_MEAT_4(R, S, T, X, q) \ + do \ + { \ + while (q) \ + { \ + T##_f[3] = S##_f[3] + q; \ + if (T##_f[3] <= X##_f[3]) \ + { \ + S##_f[3] = T##_f[3] + q; \ + X##_f[3] -= T##_f[3]; \ + R##_f[3] += q; \ + } \ + _FP_FRAC_SLL_4(X, 1); \ + q >>= 1; \ + } \ + q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ + while (q) \ + { \ + T##_f[2] = S##_f[2] + q; \ + T##_f[3] = S##_f[3]; \ + if (T##_f[3] < X##_f[3] \ + || (T##_f[3] == X##_f[3] && T##_f[2] <= X##_f[2])) \ + { \ + S##_f[2] = T##_f[2] + q; \ + S##_f[3] += (T##_f[2] > S##_f[2]); \ + __FP_FRAC_DEC_2(X##_f[3], X##_f[2], \ + T##_f[3], T##_f[2]); \ + R##_f[2] += q; \ + } \ + _FP_FRAC_SLL_4(X, 1); \ + q >>= 1; \ + } \ + q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ + while (q) \ + { \ + T##_f[1] = S##_f[1] + q; \ + T##_f[2] = S##_f[2]; \ + T##_f[3] = S##_f[3]; \ + if (T##_f[3] < X##_f[3] \ + || (T##_f[3] == X##_f[3] \ + && (T##_f[2] < X##_f[2] \ + || (T##_f[2] == X##_f[2] \ + && T##_f[1] <= X##_f[1])))) \ + { \ + S##_f[1] = T##_f[1] + q; \ + S##_f[2] += (T##_f[1] > S##_f[1]); \ + S##_f[3] += (T##_f[2] > S##_f[2]); \ + __FP_FRAC_DEC_3(X##_f[3], X##_f[2], X##_f[1], \ + T##_f[3], T##_f[2], T##_f[1]); \ + R##_f[1] += q; \ + } \ + _FP_FRAC_SLL_4(X, 1); \ + q >>= 1; \ + } \ + q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ + while (q != _FP_WORK_ROUND) \ + { \ + T##_f[0] = S##_f[0] + q; \ + T##_f[1] = S##_f[1]; \ + T##_f[2] = S##_f[2]; \ + T##_f[3] = S##_f[3]; \ + if (_FP_FRAC_GE_4(X,T)) \ + { \ + S##_f[0] = T##_f[0] + q; \ + S##_f[1] += (T##_f[0] > S##_f[0]); \ + S##_f[2] += (T##_f[1] > S##_f[1]); \ + S##_f[3] += (T##_f[2] > S##_f[2]); \ + _FP_FRAC_DEC_4(X, T); \ + R##_f[0] += q; \ + } \ + _FP_FRAC_SLL_4(X, 1); \ + q >>= 1; \ + } \ + if (!_FP_FRAC_ZEROP_4(X)) \ + { \ + if (_FP_FRAC_GT_4(X,S)) \ + R##_f[0] |= _FP_WORK_ROUND; \ + R##_f[0] |= _FP_WORK_STICKY; \ + } \ + } \ + while (0) /* @@ -538,95 +573,111 @@ #ifndef __FP_FRAC_ADD_3 # define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \ - do { \ - _FP_W_TYPE __FP_FRAC_ADD_3_c1, __FP_FRAC_ADD_3_c2; \ - r0 = x0 + y0; \ - __FP_FRAC_ADD_3_c1 = r0 < x0; \ - r1 = x1 + y1; \ - __FP_FRAC_ADD_3_c2 = r1 < x1; \ - r1 += __FP_FRAC_ADD_3_c1; \ - __FP_FRAC_ADD_3_c2 |= r1 < __FP_FRAC_ADD_3_c1; \ - r2 = x2 + y2 + __FP_FRAC_ADD_3_c2; \ - } while (0) + do \ + { \ + _FP_W_TYPE __FP_FRAC_ADD_3_c1, __FP_FRAC_ADD_3_c2; \ + r0 = x0 + y0; \ + __FP_FRAC_ADD_3_c1 = r0 < x0; \ + r1 = x1 + y1; \ + __FP_FRAC_ADD_3_c2 = r1 < x1; \ + r1 += __FP_FRAC_ADD_3_c1; \ + __FP_FRAC_ADD_3_c2 |= r1 < __FP_FRAC_ADD_3_c1; \ + r2 = x2 + y2 + __FP_FRAC_ADD_3_c2; \ + } \ + while (0) #endif #ifndef __FP_FRAC_ADD_4 # define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \ - do { \ - _FP_W_TYPE _c1, _c2, _c3; \ - r0 = x0 + y0; \ - _c1 = r0 < x0; \ - r1 = x1 + y1; \ - _c2 = r1 < x1; \ - r1 += _c1; \ - _c2 |= r1 < _c1; \ - r2 = x2 + y2; \ - _c3 = r2 < x2; \ - r2 += _c2; \ - _c3 |= r2 < _c2; \ - r3 = x3 + y3 + _c3; \ - } while (0) + do \ + { \ + _FP_W_TYPE _c1, _c2, _c3; \ + r0 = x0 + y0; \ + _c1 = r0 < x0; \ + r1 = x1 + y1; \ + _c2 = r1 < x1; \ + r1 += _c1; \ + _c2 |= r1 < _c1; \ + r2 = x2 + y2; \ + _c3 = r2 < x2; \ + r2 += _c2; \ + _c3 |= r2 < _c2; \ + r3 = x3 + y3 + _c3; \ + } \ + while (0) #endif #ifndef __FP_FRAC_SUB_3 -# define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \ - do { \ - _FP_W_TYPE _c1, _c2; \ - r0 = x0 - y0; \ - _c1 = r0 > x0; \ - r1 = x1 - y1; \ - _c2 = r1 > x1; \ - r1 -= _c1; \ - _c2 |= _c1 && (y1 == x1); \ - r2 = x2 - y2 - _c2; \ - } while (0) +# define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \ + do \ + { \ + _FP_W_TYPE _c1, _c2; \ + r0 = x0 - y0; \ + _c1 = r0 > x0; \ + r1 = x1 - y1; \ + _c2 = r1 > x1; \ + r1 -= _c1; \ + _c2 |= _c1 && (y1 == x1); \ + r2 = x2 - y2 - _c2; \ + } \ + while (0) #endif #ifndef __FP_FRAC_SUB_4 # define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \ - do { \ - _FP_W_TYPE _c1, _c2, _c3; \ - r0 = x0 - y0; \ - _c1 = r0 > x0; \ - r1 = x1 - y1; \ - _c2 = r1 > x1; \ - r1 -= _c1; \ - _c2 |= _c1 && (y1 == x1); \ - r2 = x2 - y2; \ - _c3 = r2 > x2; \ - r2 -= _c2; \ - _c3 |= _c2 && (y2 == x2); \ - r3 = x3 - y3 - _c3; \ - } while (0) + do \ + { \ + _FP_W_TYPE _c1, _c2, _c3; \ + r0 = x0 - y0; \ + _c1 = r0 > x0; \ + r1 = x1 - y1; \ + _c2 = r1 > x1; \ + r1 -= _c1; \ + _c2 |= _c1 && (y1 == x1); \ + r2 = x2 - y2; \ + _c3 = r2 > x2; \ + r2 -= _c2; \ + _c3 |= _c2 && (y2 == x2); \ + r3 = x3 - y3 - _c3; \ + } \ + while (0) #endif #ifndef __FP_FRAC_DEC_3 -# define __FP_FRAC_DEC_3(x2,x1,x0,y2,y1,y0) \ - do { \ - UWtype _t0, _t1, _t2; \ - _t0 = x0, _t1 = x1, _t2 = x2; \ - __FP_FRAC_SUB_3 (x2, x1, x0, _t2, _t1, _t0, y2, y1, y0); \ - } while (0) +# define __FP_FRAC_DEC_3(x2,x1,x0,y2,y1,y0) \ + do \ + { \ + UWtype _t0, _t1, _t2; \ + _t0 = x0, _t1 = x1, _t2 = x2; \ + __FP_FRAC_SUB_3 (x2, x1, x0, _t2, _t1, _t0, y2, y1, y0); \ + } \ + while (0) #endif #ifndef __FP_FRAC_DEC_4 # define __FP_FRAC_DEC_4(x3,x2,x1,x0,y3,y2,y1,y0) \ - do { \ - UWtype _t0, _t1, _t2, _t3; \ - _t0 = x0, _t1 = x1, _t2 = x2, _t3 = x3; \ - __FP_FRAC_SUB_4 (x3,x2,x1,x0,_t3,_t2,_t1,_t0, y3,y2,y1,y0); \ - } while (0) + do \ + { \ + UWtype _t0, _t1, _t2, _t3; \ + _t0 = x0, _t1 = x1, _t2 = x2, _t3 = x3; \ + __FP_FRAC_SUB_4 (x3,x2,x1,x0,_t3,_t2,_t1,_t0, y3,y2,y1,y0); \ + } \ + while (0) #endif #ifndef __FP_FRAC_ADDI_4 -# define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i) \ - do { \ - UWtype _t; \ - _t = ((x0 += i) < i); \ - x1 += _t; _t = (x1 < _t); \ - x2 += _t; _t = (x2 < _t); \ - x3 += _t; \ - } while (0) +# define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i) \ + do \ + { \ + UWtype _t; \ + _t = ((x0 += i) < i); \ + x1 += _t; \ + _t = (x1 < _t); \ + x2 += _t; \ + _t = (x2 < _t); \ + x3 += _t; \ + } \ + while (0) #endif /* Convert FP values between word sizes. This appears to be more @@ -639,38 +690,42 @@ #define _FP_FRAC_COPY_1_4(D, S) (D##_f = S##_f[0]) #define _FP_FRAC_COPY_2_4(D, S) \ -do { \ - D##_f0 = S##_f[0]; \ - D##_f1 = S##_f[1]; \ -} while (0) + do \ + { \ + D##_f0 = S##_f[0]; \ + D##_f1 = S##_f[1]; \ + } \ + while (0) /* Assembly/disassembly for converting to/from integral types. * No shifting or overflow handled here. */ /* Put the FP value X into r, which is an integer of size rsize. */ #define _FP_FRAC_ASSEMBLE_4(r, X, rsize) \ - do { \ - if (rsize <= _FP_W_TYPE_SIZE) \ - r = X##_f[0]; \ - else if (rsize <= 2*_FP_W_TYPE_SIZE) \ - { \ - r = X##_f[1]; \ - r <<= _FP_W_TYPE_SIZE; \ - r += X##_f[0]; \ - } \ - else \ + do \ { \ - /* I'm feeling lazy so we deal with int == 3words (implausible)*/ \ - /* and int == 4words as a single case. */ \ - r = X##_f[3]; \ - r <<= _FP_W_TYPE_SIZE; \ - r += X##_f[2]; \ - r <<= _FP_W_TYPE_SIZE; \ - r += X##_f[1]; \ - r <<= _FP_W_TYPE_SIZE; \ - r += X##_f[0]; \ + if (rsize <= _FP_W_TYPE_SIZE) \ + r = X##_f[0]; \ + else if (rsize <= 2*_FP_W_TYPE_SIZE) \ + { \ + r = X##_f[1]; \ + r <<= _FP_W_TYPE_SIZE; \ + r += X##_f[0]; \ + } \ + else \ + { \ + /* I'm feeling lazy so we deal with int == 3words (implausible)*/ \ + /* and int == 4words as a single case. */ \ + r = X##_f[3]; \ + r <<= _FP_W_TYPE_SIZE; \ + r += X##_f[2]; \ + r <<= _FP_W_TYPE_SIZE; \ + r += X##_f[1]; \ + r <<= _FP_W_TYPE_SIZE; \ + r += X##_f[0]; \ + } \ } \ - } while (0) + while (0) /* "No disassemble Number Five!" */ /* move an integer of size rsize into X's fractional part. We rely on @@ -678,24 +733,30 @@ do { \ * having to mask the values we store into it. */ #define _FP_FRAC_DISASSEMBLE_4(X, r, rsize) \ - do { \ - X##_f[0] = r; \ - X##_f[1] = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE); \ - X##_f[2] = (rsize <= 2*_FP_W_TYPE_SIZE ? 0 : r >> 2*_FP_W_TYPE_SIZE); \ - X##_f[3] = (rsize <= 3*_FP_W_TYPE_SIZE ? 0 : r >> 3*_FP_W_TYPE_SIZE); \ - } while (0) + do \ + { \ + X##_f[0] = r; \ + X##_f[1] = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE); \ + X##_f[2] = (rsize <= 2*_FP_W_TYPE_SIZE ? 0 : r >> 2*_FP_W_TYPE_SIZE); \ + X##_f[3] = (rsize <= 3*_FP_W_TYPE_SIZE ? 0 : r >> 3*_FP_W_TYPE_SIZE); \ + } \ + while (0) #define _FP_FRAC_COPY_4_1(D, S) \ -do { \ - D##_f[0] = S##_f; \ - D##_f[1] = D##_f[2] = D##_f[3] = 0; \ -} while (0) + do \ + { \ + D##_f[0] = S##_f; \ + D##_f[1] = D##_f[2] = D##_f[3] = 0; \ + } \ + while (0) #define _FP_FRAC_COPY_4_2(D, S) \ -do { \ - D##_f[0] = S##_f0; \ - D##_f[1] = S##_f1; \ - D##_f[2] = D##_f[3] = 0; \ -} while (0) + do \ + { \ + D##_f[0] = S##_f0; \ + D##_f[1] = S##_f1; \ + D##_f[2] = D##_f[3] = 0; \ + } \ + while (0) #define _FP_FRAC_COPY_4_4(D,S) _FP_FRAC_COPY_4(D,S) diff --git a/soft-fp/op-8.h b/soft-fp/op-8.h index 8890d02..1cfe819 100644 --- a/soft-fp/op-8.h +++ b/soft-fp/op-8.h @@ -36,45 +36,49 @@ #define _FP_FRAC_LOW_8(X) (X##_f[0]) #define _FP_FRAC_WORD_8(X,w) (X##_f[w]) -#define _FP_FRAC_SLL_8(X,N) \ - do { \ - _FP_I_TYPE _up, _down, _skip, _i; \ - _skip = (N) / _FP_W_TYPE_SIZE; \ - _up = (N) % _FP_W_TYPE_SIZE; \ - _down = _FP_W_TYPE_SIZE - _up; \ - if (!_up) \ - for (_i = 7; _i >= _skip; --_i) \ - X##_f[_i] = X##_f[_i-_skip]; \ - else \ - { \ - for (_i = 7; _i > _skip; --_i) \ - X##_f[_i] = X##_f[_i-_skip] << _up \ - | X##_f[_i-_skip-1] >> _down; \ - X##_f[_i--] = X##_f[0] << _up; \ - } \ - for (; _i >= 0; --_i) \ - X##_f[_i] = 0; \ - } while (0) +#define _FP_FRAC_SLL_8(X,N) \ + do \ + { \ + _FP_I_TYPE _up, _down, _skip, _i; \ + _skip = (N) / _FP_W_TYPE_SIZE; \ + _up = (N) % _FP_W_TYPE_SIZE; \ + _down = _FP_W_TYPE_SIZE - _up; \ + if (!_up) \ + for (_i = 7; _i >= _skip; --_i) \ + X##_f[_i] = X##_f[_i-_skip]; \ + else \ + { \ + for (_i = 7; _i > _skip; --_i) \ + X##_f[_i] = (X##_f[_i-_skip] << _up \ + | X##_f[_i-_skip-1] >> _down); \ + X##_f[_i--] = X##_f[0] << _up; \ + } \ + for (; _i >= 0; --_i) \ + X##_f[_i] = 0; \ + } \ + while (0) -#define _FP_FRAC_SRL_8(X,N) \ - do { \ - _FP_I_TYPE _up, _down, _skip, _i; \ - _skip = (N) / _FP_W_TYPE_SIZE; \ - _down = (N) % _FP_W_TYPE_SIZE; \ - _up = _FP_W_TYPE_SIZE - _down; \ - if (!_down) \ - for (_i = 0; _i <= 7-_skip; ++_i) \ - X##_f[_i] = X##_f[_i+_skip]; \ - else \ - { \ - for (_i = 0; _i < 7-_skip; ++_i) \ - X##_f[_i] = X##_f[_i+_skip] >> _down \ - | X##_f[_i+_skip+1] << _up; \ - X##_f[_i++] = X##_f[7] >> _down; \ - } \ - for (; _i < 8; ++_i) \ - X##_f[_i] = 0; \ - } while (0) +#define _FP_FRAC_SRL_8(X,N) \ + do \ + { \ + _FP_I_TYPE _up, _down, _skip, _i; \ + _skip = (N) / _FP_W_TYPE_SIZE; \ + _down = (N) % _FP_W_TYPE_SIZE; \ + _up = _FP_W_TYPE_SIZE - _down; \ + if (!_down) \ + for (_i = 0; _i <= 7-_skip; ++_i) \ + X##_f[_i] = X##_f[_i+_skip]; \ + else \ + { \ + for (_i = 0; _i < 7-_skip; ++_i) \ + X##_f[_i] = (X##_f[_i+_skip] >> _down \ + | X##_f[_i+_skip+1] << _up); \ + X##_f[_i++] = X##_f[7] >> _down; \ + } \ + for (; _i < 8; ++_i) \ + X##_f[_i] = 0; \ + } \ + while (0) /* Right shift with sticky-lsb. @@ -83,27 +87,30 @@ * were one then we always set the LSbit. */ #define _FP_FRAC_SRS_8(X,N,size) \ - do { \ - _FP_I_TYPE _up, _down, _skip, _i; \ - _FP_W_TYPE _s; \ - _skip = (N) / _FP_W_TYPE_SIZE; \ - _down = (N) % _FP_W_TYPE_SIZE; \ - _up = _FP_W_TYPE_SIZE - _down; \ - for (_s = _i = 0; _i < _skip; ++_i) \ - _s |= X##_f[_i]; \ - if (!_down) \ - for (_i = 0; _i <= 7-_skip; ++_i) \ - X##_f[_i] = X##_f[_i+_skip]; \ - else \ - { \ - _s |= X##_f[_i] << _up; \ - for (_i = 0; _i < 7-_skip; ++_i) \ - X##_f[_i] = X##_f[_i+_skip] >> _down \ - | X##_f[_i+_skip+1] << _up; \ - X##_f[_i++] = X##_f[7] >> _down; \ - } \ - for (; _i < 8; ++_i) \ - X##_f[_i] = 0; \ - /* don't fix the LSB until the very end when we're sure f[0] is stable */ \ - X##_f[0] |= (_s != 0); \ - } while (0) + do \ + { \ + _FP_I_TYPE _up, _down, _skip, _i; \ + _FP_W_TYPE _s; \ + _skip = (N) / _FP_W_TYPE_SIZE; \ + _down = (N) % _FP_W_TYPE_SIZE; \ + _up = _FP_W_TYPE_SIZE - _down; \ + for (_s = _i = 0; _i < _skip; ++_i) \ + _s |= X##_f[_i]; \ + if (!_down) \ + for (_i = 0; _i <= 7-_skip; ++_i) \ + X##_f[_i] = X##_f[_i+_skip]; \ + else \ + { \ + _s |= X##_f[_i] << _up; \ + for (_i = 0; _i < 7-_skip; ++_i) \ + X##_f[_i] = (X##_f[_i+_skip] >> _down \ + | X##_f[_i+_skip+1] << _up); \ + X##_f[_i++] = X##_f[7] >> _down; \ + } \ + for (; _i < 8; ++_i) \ + X##_f[_i] = 0; \ + /* don't fix the LSB until the very end when we're sure f[0] is \ + stable */ \ + X##_f[0] |= (_s != 0); \ + } \ + while (0) diff --git a/soft-fp/op-common.h b/soft-fp/op-common.h index d87ffaf..89fec5d 100644 --- a/soft-fp/op-common.h +++ b/soft-fp/op-common.h @@ -50,46 +50,48 @@ * of fp value and normalizing both the exponent and the fraction. */ -#define _FP_UNPACK_CANONICAL(fs, wc, X) \ -do { \ - switch (X##_e) \ - { \ - default: \ - _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs; \ - _FP_FRAC_SLL_##wc(X, _FP_WORKBITS); \ - X##_e -= _FP_EXPBIAS_##fs; \ - X##_c = FP_CLS_NORMAL; \ - break; \ - \ - case 0: \ - if (_FP_FRAC_ZEROP_##wc(X)) \ - X##_c = FP_CLS_ZERO; \ - else \ - { \ - /* a denormalized number */ \ - _FP_I_TYPE _shift; \ - _FP_FRAC_CLZ_##wc(_shift, X); \ - _shift -= _FP_FRACXBITS_##fs; \ - _FP_FRAC_SLL_##wc(X, (_shift+_FP_WORKBITS)); \ - X##_e -= _FP_EXPBIAS_##fs - 1 + _shift; \ - X##_c = FP_CLS_NORMAL; \ - FP_SET_EXCEPTION(FP_EX_DENORM); \ - } \ - break; \ - \ - case _FP_EXPMAX_##fs: \ - if (_FP_FRAC_ZEROP_##wc(X)) \ - X##_c = FP_CLS_INF; \ - else \ - { \ - X##_c = FP_CLS_NAN; \ - /* Check for signaling NaN */ \ - if (_FP_FRAC_SNANP(fs, X)) \ - FP_SET_EXCEPTION(FP_EX_INVALID); \ - } \ - break; \ - } \ -} while (0) +#define _FP_UNPACK_CANONICAL(fs, wc, X) \ + do \ + { \ + switch (X##_e) \ + { \ + default: \ + _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs; \ + _FP_FRAC_SLL_##wc(X, _FP_WORKBITS); \ + X##_e -= _FP_EXPBIAS_##fs; \ + X##_c = FP_CLS_NORMAL; \ + break; \ + \ + case 0: \ + if (_FP_FRAC_ZEROP_##wc(X)) \ + X##_c = FP_CLS_ZERO; \ + else \ + { \ + /* a denormalized number */ \ + _FP_I_TYPE _shift; \ + _FP_FRAC_CLZ_##wc(_shift, X); \ + _shift -= _FP_FRACXBITS_##fs; \ + _FP_FRAC_SLL_##wc(X, (_shift+_FP_WORKBITS)); \ + X##_e -= _FP_EXPBIAS_##fs - 1 + _shift; \ + X##_c = FP_CLS_NORMAL; \ + FP_SET_EXCEPTION(FP_EX_DENORM); \ + } \ + break; \ + \ + case _FP_EXPMAX_##fs: \ + if (_FP_FRAC_ZEROP_##wc(X)) \ + X##_c = FP_CLS_INF; \ + else \ + { \ + X##_c = FP_CLS_NAN; \ + /* Check for signaling NaN */ \ + if (_FP_FRAC_SNANP(fs, X)) \ + FP_SET_EXCEPTION(FP_EX_INVALID); \ + } \ + break; \ + } \ + } \ + while (0) /* Finish unpacking an fp value in semi-raw mode: the mantissa is shifted by _FP_WORKBITS but the implicit MSB is not inserted and @@ -99,76 +101,86 @@ do { \ /* A semi-raw value has overflowed to infinity. Adjust the mantissa and exponent appropriately. */ #define _FP_OVERFLOW_SEMIRAW(fs, wc, X) \ -do { \ - if (FP_ROUNDMODE == FP_RND_NEAREST \ - || (FP_ROUNDMODE == FP_RND_PINF && !X##_s) \ - || (FP_ROUNDMODE == FP_RND_MINF && X##_s)) \ - { \ - X##_e = _FP_EXPMAX_##fs; \ - _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ - } \ - else \ + do \ { \ - X##_e = _FP_EXPMAX_##fs - 1; \ - _FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc); \ + if (FP_ROUNDMODE == FP_RND_NEAREST \ + || (FP_ROUNDMODE == FP_RND_PINF && !X##_s) \ + || (FP_ROUNDMODE == FP_RND_MINF && X##_s)) \ + { \ + X##_e = _FP_EXPMAX_##fs; \ + _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ + } \ + else \ + { \ + X##_e = _FP_EXPMAX_##fs - 1; \ + _FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc); \ + } \ + FP_SET_EXCEPTION(FP_EX_INEXACT); \ + FP_SET_EXCEPTION(FP_EX_OVERFLOW); \ } \ - FP_SET_EXCEPTION(FP_EX_INEXACT); \ - FP_SET_EXCEPTION(FP_EX_OVERFLOW); \ -} while (0) + while (0) /* Check for a semi-raw value being a signaling NaN and raise the invalid exception if so. */ -#define _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X) \ -do { \ - if (X##_e == _FP_EXPMAX_##fs \ - && !_FP_FRAC_ZEROP_##wc(X) \ - && _FP_FRAC_SNANP_SEMIRAW(fs, X)) \ - FP_SET_EXCEPTION(FP_EX_INVALID); \ -} while (0) +#define _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X) \ + do \ + { \ + if (X##_e == _FP_EXPMAX_##fs \ + && !_FP_FRAC_ZEROP_##wc(X) \ + && _FP_FRAC_SNANP_SEMIRAW(fs, X)) \ + FP_SET_EXCEPTION(FP_EX_INVALID); \ + } \ + while (0) /* Choose a NaN result from an operation on two semi-raw NaN values. */ #define _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP) \ -do { \ - /* _FP_CHOOSENAN expects raw values, so shift as required. */ \ - _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ - _FP_FRAC_SRL_##wc(Y, _FP_WORKBITS); \ - _FP_CHOOSENAN(fs, wc, R, X, Y, OP); \ - _FP_FRAC_SLL_##wc(R, _FP_WORKBITS); \ -} while (0) + do \ + { \ + /* _FP_CHOOSENAN expects raw values, so shift as required. */ \ + _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ + _FP_FRAC_SRL_##wc(Y, _FP_WORKBITS); \ + _FP_CHOOSENAN(fs, wc, R, X, Y, OP); \ + _FP_FRAC_SLL_##wc(R, _FP_WORKBITS); \ + } \ + while (0) /* Make the fractional part a quiet NaN, preserving the payload if possible, otherwise make it the canonical quiet NaN and set the sign bit accordingly. */ -#define _FP_SETQNAN(fs, wc, X) \ -do { \ - if (_FP_QNANNEGATEDP) \ - { \ - _FP_FRAC_HIGH_RAW_##fs(X) &= _FP_QNANBIT_##fs - 1; \ - if (_FP_FRAC_ZEROP_##wc(X)) \ - { \ - X##_s = _FP_NANSIGN_##fs; \ - _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \ - } \ - } \ - else \ - _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs; \ -} while (0) -#define _FP_SETQNAN_SEMIRAW(fs, wc, X) \ -do { \ - if (_FP_QNANNEGATEDP) \ - { \ - _FP_FRAC_HIGH_##fs(X) &= _FP_QNANBIT_SH_##fs - 1; \ - if (_FP_FRAC_ZEROP_##wc(X)) \ - { \ - X##_s = _FP_NANSIGN_##fs; \ - _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \ - _FP_FRAC_SLL_##wc(X, _FP_WORKBITS); \ - } \ - } \ - else \ - _FP_FRAC_HIGH_##fs(X) |= _FP_QNANBIT_SH_##fs; \ -} while (0) +#define _FP_SETQNAN(fs, wc, X) \ + do \ + { \ + if (_FP_QNANNEGATEDP) \ + { \ + _FP_FRAC_HIGH_RAW_##fs(X) &= _FP_QNANBIT_##fs - 1; \ + if (_FP_FRAC_ZEROP_##wc(X)) \ + { \ + X##_s = _FP_NANSIGN_##fs; \ + _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \ + } \ + } \ + else \ + _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs; \ + } \ + while (0) +#define _FP_SETQNAN_SEMIRAW(fs, wc, X) \ + do \ + { \ + if (_FP_QNANNEGATEDP) \ + { \ + _FP_FRAC_HIGH_##fs(X) &= _FP_QNANBIT_SH_##fs - 1; \ + if (_FP_FRAC_ZEROP_##wc(X)) \ + { \ + X##_s = _FP_NANSIGN_##fs; \ + _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \ + _FP_FRAC_SLL_##wc(X, _FP_WORKBITS); \ + } \ + } \ + else \ + _FP_FRAC_HIGH_##fs(X) |= _FP_QNANBIT_SH_##fs; \ + } \ + while (0) /* Test whether a biased exponent is normal (not zero or maximum). */ #define _FP_EXP_NORMAL(fs, wc, X) (((X##_e + 1) & _FP_EXPMAX_##fs) > 1) @@ -177,34 +189,36 @@ do { \ rounded and shifted right, with the rounding possibly increasing the exponent (including changing a finite value to infinity). */ #define _FP_PACK_SEMIRAW(fs, wc, X) \ -do { \ - _FP_ROUND(wc, X); \ - if (X##_e == 0 && !_FP_FRAC_ZEROP_##wc(X)) \ - { \ + do \ + { \ + _FP_ROUND(wc, X); \ + if (X##_e == 0 && !_FP_FRAC_ZEROP_##wc(X)) \ + { \ if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) \ || (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW)) \ FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \ - } \ - if (_FP_FRAC_HIGH_##fs(X) \ - & (_FP_OVERFLOW_##fs >> 1)) \ - { \ - _FP_FRAC_HIGH_##fs(X) &= ~(_FP_OVERFLOW_##fs >> 1); \ - X##_e++; \ - if (X##_e == _FP_EXPMAX_##fs) \ - _FP_OVERFLOW_SEMIRAW(fs, wc, X); \ - } \ - _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ - if (X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \ - { \ - if (!_FP_KEEPNANFRACP) \ + } \ + if (_FP_FRAC_HIGH_##fs(X) \ + & (_FP_OVERFLOW_##fs >> 1)) \ { \ - _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \ - X##_s = _FP_NANSIGN_##fs; \ + _FP_FRAC_HIGH_##fs(X) &= ~(_FP_OVERFLOW_##fs >> 1); \ + X##_e++; \ + if (X##_e == _FP_EXPMAX_##fs) \ + _FP_OVERFLOW_SEMIRAW(fs, wc, X); \ + } \ + _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ + if (X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \ + { \ + if (!_FP_KEEPNANFRACP) \ + { \ + _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \ + X##_s = _FP_NANSIGN_##fs; \ + } \ + else \ + _FP_SETQNAN(fs, wc, X); \ } \ - else \ - _FP_SETQNAN(fs, wc, X); \ } \ -} while (0) + while (0) /* * Before packing the bits back into the native fp result, take care @@ -213,910 +227,927 @@ do { \ * extracted -- but that is ok, we can regenerate them now. */ -#define _FP_PACK_CANONICAL(fs, wc, X) \ -do { \ - switch (X##_c) \ - { \ - case FP_CLS_NORMAL: \ - X##_e += _FP_EXPBIAS_##fs; \ - if (X##_e > 0) \ - { \ - _FP_ROUND(wc, X); \ - if (_FP_FRAC_OVERP_##wc(fs, X)) \ - { \ - _FP_FRAC_CLEAR_OVERP_##wc(fs, X); \ - X##_e++; \ - } \ - _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ - if (X##_e >= _FP_EXPMAX_##fs) \ - { \ - /* overflow */ \ - switch (FP_ROUNDMODE) \ - { \ - case FP_RND_NEAREST: \ - X##_c = FP_CLS_INF; \ - break; \ - case FP_RND_PINF: \ - if (!X##_s) X##_c = FP_CLS_INF; \ - break; \ - case FP_RND_MINF: \ - if (X##_s) X##_c = FP_CLS_INF; \ - break; \ - } \ - if (X##_c == FP_CLS_INF) \ - { \ - /* Overflow to infinity */ \ - X##_e = _FP_EXPMAX_##fs; \ - _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ - } \ - else \ - { \ - /* Overflow to maximum normal */ \ - X##_e = _FP_EXPMAX_##fs - 1; \ - _FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc); \ - } \ - FP_SET_EXCEPTION(FP_EX_OVERFLOW); \ - FP_SET_EXCEPTION(FP_EX_INEXACT); \ - } \ - } \ - else \ - { \ - /* we've got a denormalized number */ \ - X##_e = -X##_e + 1; \ - if (X##_e <= _FP_WFRACBITS_##fs) \ - { \ - _FP_FRAC_SRS_##wc(X, X##_e, _FP_WFRACBITS_##fs); \ - _FP_ROUND(wc, X); \ - if (_FP_FRAC_HIGH_##fs(X) \ - & (_FP_OVERFLOW_##fs >> 1)) \ - { \ - X##_e = 1; \ - _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ - FP_SET_EXCEPTION(FP_EX_INEXACT); \ - } \ - else \ - { \ - X##_e = 0; \ - _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ - } \ - if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) \ - || (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW)) \ - FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \ - } \ - else \ - { \ - /* underflow to zero */ \ - X##_e = 0; \ - if (!_FP_FRAC_ZEROP_##wc(X)) \ - { \ - _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \ - _FP_ROUND(wc, X); \ - _FP_FRAC_LOW_##wc(X) >>= (_FP_WORKBITS); \ - } \ - FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \ - } \ - } \ - break; \ - \ - case FP_CLS_ZERO: \ - X##_e = 0; \ - _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ - break; \ - \ - case FP_CLS_INF: \ - X##_e = _FP_EXPMAX_##fs; \ - _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ - break; \ - \ - case FP_CLS_NAN: \ - X##_e = _FP_EXPMAX_##fs; \ - if (!_FP_KEEPNANFRACP) \ - { \ - _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \ - X##_s = _FP_NANSIGN_##fs; \ - } \ - else \ - _FP_SETQNAN(fs, wc, X); \ - break; \ - } \ -} while (0) +#define _FP_PACK_CANONICAL(fs, wc, X) \ + do \ + { \ + switch (X##_c) \ + { \ + case FP_CLS_NORMAL: \ + X##_e += _FP_EXPBIAS_##fs; \ + if (X##_e > 0) \ + { \ + _FP_ROUND(wc, X); \ + if (_FP_FRAC_OVERP_##wc(fs, X)) \ + { \ + _FP_FRAC_CLEAR_OVERP_##wc(fs, X); \ + X##_e++; \ + } \ + _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ + if (X##_e >= _FP_EXPMAX_##fs) \ + { \ + /* overflow */ \ + switch (FP_ROUNDMODE) \ + { \ + case FP_RND_NEAREST: \ + X##_c = FP_CLS_INF; \ + break; \ + case FP_RND_PINF: \ + if (!X##_s) \ + X##_c = FP_CLS_INF; \ + break; \ + case FP_RND_MINF: \ + if (X##_s) \ + X##_c = FP_CLS_INF; \ + break; \ + } \ + if (X##_c == FP_CLS_INF) \ + { \ + /* Overflow to infinity */ \ + X##_e = _FP_EXPMAX_##fs; \ + _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ + } \ + else \ + { \ + /* Overflow to maximum normal */ \ + X##_e = _FP_EXPMAX_##fs - 1; \ + _FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc); \ + } \ + FP_SET_EXCEPTION(FP_EX_OVERFLOW); \ + FP_SET_EXCEPTION(FP_EX_INEXACT); \ + } \ + } \ + else \ + { \ + /* we've got a denormalized number */ \ + X##_e = -X##_e + 1; \ + if (X##_e <= _FP_WFRACBITS_##fs) \ + { \ + _FP_FRAC_SRS_##wc(X, X##_e, _FP_WFRACBITS_##fs); \ + _FP_ROUND(wc, X); \ + if (_FP_FRAC_HIGH_##fs(X) \ + & (_FP_OVERFLOW_##fs >> 1)) \ + { \ + X##_e = 1; \ + _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ + FP_SET_EXCEPTION(FP_EX_INEXACT); \ + } \ + else \ + { \ + X##_e = 0; \ + _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ + } \ + if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) \ + || (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW)) \ + FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \ + } \ + else \ + { \ + /* underflow to zero */ \ + X##_e = 0; \ + if (!_FP_FRAC_ZEROP_##wc(X)) \ + { \ + _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \ + _FP_ROUND(wc, X); \ + _FP_FRAC_LOW_##wc(X) >>= (_FP_WORKBITS); \ + } \ + FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \ + } \ + } \ + break; \ + \ + case FP_CLS_ZERO: \ + X##_e = 0; \ + _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ + break; \ + \ + case FP_CLS_INF: \ + X##_e = _FP_EXPMAX_##fs; \ + _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ + break; \ + \ + case FP_CLS_NAN: \ + X##_e = _FP_EXPMAX_##fs; \ + if (!_FP_KEEPNANFRACP) \ + { \ + _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \ + X##_s = _FP_NANSIGN_##fs; \ + } \ + else \ + _FP_SETQNAN(fs, wc, X); \ + break; \ + } \ + } \ + while (0) /* This one accepts raw argument and not cooked, returns * 1 if X is a signaling NaN. */ -#define _FP_ISSIGNAN(fs, wc, X) \ -({ \ - int __ret = 0; \ - if (X##_e == _FP_EXPMAX_##fs) \ - { \ - if (!_FP_FRAC_ZEROP_##wc(X) \ - && _FP_FRAC_SNANP(fs, X)) \ - __ret = 1; \ - } \ - __ret; \ -}) +#define _FP_ISSIGNAN(fs, wc, X) \ + ({ \ + int __ret = 0; \ + if (X##_e == _FP_EXPMAX_##fs) \ + { \ + if (!_FP_FRAC_ZEROP_##wc(X) \ + && _FP_FRAC_SNANP(fs, X)) \ + __ret = 1; \ + } \ + __ret; \ + }) /* Addition on semi-raw values. */ -#define _FP_ADD_INTERNAL(fs, wc, R, X, Y, OP) \ -do { \ - if (X##_s == Y##_s) \ - { \ - /* Addition. */ \ - R##_s = X##_s; \ - int ediff = X##_e - Y##_e; \ - if (ediff > 0) \ - { \ - R##_e = X##_e; \ - if (Y##_e == 0) \ - { \ - /* Y is zero or denormalized. */ \ - if (_FP_FRAC_ZEROP_##wc(Y)) \ - { \ - _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ - _FP_FRAC_COPY_##wc(R, X); \ - goto add_done; \ - } \ - else \ - { \ - FP_SET_EXCEPTION(FP_EX_DENORM); \ - ediff--; \ - if (ediff == 0) \ - { \ - _FP_FRAC_ADD_##wc(R, X, Y); \ - goto add3; \ - } \ - if (X##_e == _FP_EXPMAX_##fs) \ - { \ - _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ - _FP_FRAC_COPY_##wc(R, X); \ - goto add_done; \ - } \ - goto add1; \ - } \ - } \ - else if (X##_e == _FP_EXPMAX_##fs) \ - { \ - /* X is NaN or Inf, Y is normal. */ \ - _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ - _FP_FRAC_COPY_##wc(R, X); \ - goto add_done; \ - } \ - \ - /* Insert implicit MSB of Y. */ \ - _FP_FRAC_HIGH_##fs(Y) |= _FP_IMPLBIT_SH_##fs; \ - \ - add1: \ - /* Shift the mantissa of Y to the right EDIFF steps; \ - remember to account later for the implicit MSB of X. */ \ - if (ediff <= _FP_WFRACBITS_##fs) \ - _FP_FRAC_SRS_##wc(Y, ediff, _FP_WFRACBITS_##fs); \ - else if (!_FP_FRAC_ZEROP_##wc(Y)) \ - _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \ - _FP_FRAC_ADD_##wc(R, X, Y); \ - } \ - else if (ediff < 0) \ - { \ - ediff = -ediff; \ - R##_e = Y##_e; \ - if (X##_e == 0) \ - { \ - /* X is zero or denormalized. */ \ - if (_FP_FRAC_ZEROP_##wc(X)) \ - { \ - _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ - _FP_FRAC_COPY_##wc(R, Y); \ - goto add_done; \ - } \ - else \ - { \ - FP_SET_EXCEPTION(FP_EX_DENORM); \ - ediff--; \ - if (ediff == 0) \ - { \ - _FP_FRAC_ADD_##wc(R, Y, X); \ - goto add3; \ - } \ - if (Y##_e == _FP_EXPMAX_##fs) \ - { \ - _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ - _FP_FRAC_COPY_##wc(R, Y); \ - goto add_done; \ - } \ - goto add2; \ - } \ - } \ - else if (Y##_e == _FP_EXPMAX_##fs) \ - { \ - /* Y is NaN or Inf, X is normal. */ \ - _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ - _FP_FRAC_COPY_##wc(R, Y); \ - goto add_done; \ - } \ - \ - /* Insert implicit MSB of X. */ \ - _FP_FRAC_HIGH_##fs(X) |= _FP_IMPLBIT_SH_##fs; \ - \ - add2: \ - /* Shift the mantissa of X to the right EDIFF steps; \ - remember to account later for the implicit MSB of Y. */ \ - if (ediff <= _FP_WFRACBITS_##fs) \ - _FP_FRAC_SRS_##wc(X, ediff, _FP_WFRACBITS_##fs); \ - else if (!_FP_FRAC_ZEROP_##wc(X)) \ - _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \ - _FP_FRAC_ADD_##wc(R, Y, X); \ - } \ - else \ - { \ - /* ediff == 0. */ \ - if (!_FP_EXP_NORMAL(fs, wc, X)) \ - { \ - if (X##_e == 0) \ - { \ - /* X and Y are zero or denormalized. */ \ - R##_e = 0; \ - if (_FP_FRAC_ZEROP_##wc(X)) \ - { \ - if (!_FP_FRAC_ZEROP_##wc(Y)) \ - FP_SET_EXCEPTION(FP_EX_DENORM); \ - _FP_FRAC_COPY_##wc(R, Y); \ - goto add_done; \ - } \ - else if (_FP_FRAC_ZEROP_##wc(Y)) \ - { \ - FP_SET_EXCEPTION(FP_EX_DENORM); \ - _FP_FRAC_COPY_##wc(R, X); \ - goto add_done; \ - } \ - else \ - { \ - FP_SET_EXCEPTION(FP_EX_DENORM); \ - _FP_FRAC_ADD_##wc(R, X, Y); \ - if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ - { \ - /* Normalized result. */ \ - _FP_FRAC_HIGH_##fs(R) \ - &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \ - R##_e = 1; \ - } \ - goto add_done; \ - } \ - } \ - else \ - { \ - /* X and Y are NaN or Inf. */ \ - _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ - _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ - R##_e = _FP_EXPMAX_##fs; \ - if (_FP_FRAC_ZEROP_##wc(X)) \ - _FP_FRAC_COPY_##wc(R, Y); \ - else if (_FP_FRAC_ZEROP_##wc(Y)) \ - _FP_FRAC_COPY_##wc(R, X); \ - else \ - _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP); \ - goto add_done; \ - } \ - } \ - /* The exponents of X and Y, both normal, are equal. The \ - implicit MSBs will always add to increase the \ - exponent. */ \ - _FP_FRAC_ADD_##wc(R, X, Y); \ - R##_e = X##_e + 1; \ - _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \ - if (R##_e == _FP_EXPMAX_##fs) \ - /* Overflow to infinity (depending on rounding mode). */ \ - _FP_OVERFLOW_SEMIRAW(fs, wc, R); \ - goto add_done; \ - } \ - add3: \ - if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ - { \ - /* Overflow. */ \ - _FP_FRAC_HIGH_##fs(R) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \ - R##_e++; \ - _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \ - if (R##_e == _FP_EXPMAX_##fs) \ - /* Overflow to infinity (depending on rounding mode). */ \ - _FP_OVERFLOW_SEMIRAW(fs, wc, R); \ - } \ - add_done: ; \ - } \ - else \ - { \ - /* Subtraction. */ \ - int ediff = X##_e - Y##_e; \ - if (ediff > 0) \ - { \ - R##_e = X##_e; \ - R##_s = X##_s; \ - if (Y##_e == 0) \ - { \ - /* Y is zero or denormalized. */ \ - if (_FP_FRAC_ZEROP_##wc(Y)) \ - { \ - _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ - _FP_FRAC_COPY_##wc(R, X); \ - goto sub_done; \ - } \ - else \ - { \ - FP_SET_EXCEPTION(FP_EX_DENORM); \ - ediff--; \ - if (ediff == 0) \ - { \ - _FP_FRAC_SUB_##wc(R, X, Y); \ - goto sub3; \ - } \ - if (X##_e == _FP_EXPMAX_##fs) \ - { \ - _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ - _FP_FRAC_COPY_##wc(R, X); \ - goto sub_done; \ - } \ - goto sub1; \ - } \ - } \ - else if (X##_e == _FP_EXPMAX_##fs) \ - { \ - /* X is NaN or Inf, Y is normal. */ \ - _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ - _FP_FRAC_COPY_##wc(R, X); \ - goto sub_done; \ - } \ - \ - /* Insert implicit MSB of Y. */ \ - _FP_FRAC_HIGH_##fs(Y) |= _FP_IMPLBIT_SH_##fs; \ - \ - sub1: \ - /* Shift the mantissa of Y to the right EDIFF steps; \ - remember to account later for the implicit MSB of X. */ \ - if (ediff <= _FP_WFRACBITS_##fs) \ - _FP_FRAC_SRS_##wc(Y, ediff, _FP_WFRACBITS_##fs); \ - else if (!_FP_FRAC_ZEROP_##wc(Y)) \ - _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \ - _FP_FRAC_SUB_##wc(R, X, Y); \ - } \ - else if (ediff < 0) \ - { \ - ediff = -ediff; \ - R##_e = Y##_e; \ - R##_s = Y##_s; \ - if (X##_e == 0) \ - { \ - /* X is zero or denormalized. */ \ - if (_FP_FRAC_ZEROP_##wc(X)) \ - { \ - _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ - _FP_FRAC_COPY_##wc(R, Y); \ - goto sub_done; \ - } \ - else \ - { \ - FP_SET_EXCEPTION(FP_EX_DENORM); \ - ediff--; \ - if (ediff == 0) \ - { \ - _FP_FRAC_SUB_##wc(R, Y, X); \ - goto sub3; \ - } \ - if (Y##_e == _FP_EXPMAX_##fs) \ - { \ - _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ - _FP_FRAC_COPY_##wc(R, Y); \ - goto sub_done; \ - } \ - goto sub2; \ - } \ - } \ - else if (Y##_e == _FP_EXPMAX_##fs) \ - { \ - /* Y is NaN or Inf, X is normal. */ \ - _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ - _FP_FRAC_COPY_##wc(R, Y); \ - goto sub_done; \ - } \ - \ - /* Insert implicit MSB of X. */ \ - _FP_FRAC_HIGH_##fs(X) |= _FP_IMPLBIT_SH_##fs; \ - \ - sub2: \ - /* Shift the mantissa of X to the right EDIFF steps; \ - remember to account later for the implicit MSB of Y. */ \ - if (ediff <= _FP_WFRACBITS_##fs) \ - _FP_FRAC_SRS_##wc(X, ediff, _FP_WFRACBITS_##fs); \ - else if (!_FP_FRAC_ZEROP_##wc(X)) \ - _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \ - _FP_FRAC_SUB_##wc(R, Y, X); \ - } \ - else \ - { \ - /* ediff == 0. */ \ - if (!_FP_EXP_NORMAL(fs, wc, X)) \ - { \ - if (X##_e == 0) \ - { \ - /* X and Y are zero or denormalized. */ \ - R##_e = 0; \ - if (_FP_FRAC_ZEROP_##wc(X)) \ - { \ - _FP_FRAC_COPY_##wc(R, Y); \ - if (_FP_FRAC_ZEROP_##wc(Y)) \ - R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ - else \ - { \ - FP_SET_EXCEPTION(FP_EX_DENORM); \ - R##_s = Y##_s; \ - } \ - goto sub_done; \ - } \ - else if (_FP_FRAC_ZEROP_##wc(Y)) \ - { \ - FP_SET_EXCEPTION(FP_EX_DENORM); \ - _FP_FRAC_COPY_##wc(R, X); \ - R##_s = X##_s; \ - goto sub_done; \ - } \ - else \ - { \ - FP_SET_EXCEPTION(FP_EX_DENORM); \ - _FP_FRAC_SUB_##wc(R, X, Y); \ - R##_s = X##_s; \ - if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ - { \ - /* |X| < |Y|, negate result. */ \ - _FP_FRAC_SUB_##wc(R, Y, X); \ - R##_s = Y##_s; \ - } \ - else if (_FP_FRAC_ZEROP_##wc(R)) \ - R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ - goto sub_done; \ - } \ - } \ - else \ - { \ - /* X and Y are NaN or Inf, of opposite signs. */ \ - _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ - _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ - R##_e = _FP_EXPMAX_##fs; \ - if (_FP_FRAC_ZEROP_##wc(X)) \ - { \ - if (_FP_FRAC_ZEROP_##wc(Y)) \ - { \ - /* Inf - Inf. */ \ - R##_s = _FP_NANSIGN_##fs; \ - _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ - _FP_FRAC_SLL_##wc(R, _FP_WORKBITS); \ - FP_SET_EXCEPTION(FP_EX_INVALID); \ - } \ - else \ - { \ - /* Inf - NaN. */ \ - R##_s = Y##_s; \ - _FP_FRAC_COPY_##wc(R, Y); \ - } \ - } \ - else \ - { \ - if (_FP_FRAC_ZEROP_##wc(Y)) \ - { \ - /* NaN - Inf. */ \ - R##_s = X##_s; \ - _FP_FRAC_COPY_##wc(R, X); \ - } \ - else \ - { \ - /* NaN - NaN. */ \ - _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP); \ - } \ - } \ - goto sub_done; \ - } \ - } \ - /* The exponents of X and Y, both normal, are equal. The \ - implicit MSBs cancel. */ \ - R##_e = X##_e; \ - _FP_FRAC_SUB_##wc(R, X, Y); \ - R##_s = X##_s; \ - if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ - { \ - /* |X| < |Y|, negate result. */ \ - _FP_FRAC_SUB_##wc(R, Y, X); \ - R##_s = Y##_s; \ - } \ - else if (_FP_FRAC_ZEROP_##wc(R)) \ - { \ - R##_e = 0; \ - R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ - goto sub_done; \ - } \ - goto norm; \ - } \ - sub3: \ - if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ - { \ - int diff; \ - /* Carry into most significant bit of larger one of X and Y, \ - canceling it; renormalize. */ \ - _FP_FRAC_HIGH_##fs(R) &= _FP_IMPLBIT_SH_##fs - 1; \ - norm: \ - _FP_FRAC_CLZ_##wc(diff, R); \ - diff -= _FP_WFRACXBITS_##fs; \ - _FP_FRAC_SLL_##wc(R, diff); \ - if (R##_e <= diff) \ - { \ - /* R is denormalized. */ \ - diff = diff - R##_e + 1; \ - _FP_FRAC_SRS_##wc(R, diff, _FP_WFRACBITS_##fs); \ - R##_e = 0; \ - } \ - else \ - { \ - R##_e -= diff; \ +#define _FP_ADD_INTERNAL(fs, wc, R, X, Y, OP) \ + do \ + { \ + if (X##_s == Y##_s) \ + { \ + /* Addition. */ \ + R##_s = X##_s; \ + int ediff = X##_e - Y##_e; \ + if (ediff > 0) \ + { \ + R##_e = X##_e; \ + if (Y##_e == 0) \ + { \ + /* Y is zero or denormalized. */ \ + if (_FP_FRAC_ZEROP_##wc(Y)) \ + { \ + _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ + _FP_FRAC_COPY_##wc(R, X); \ + goto add_done; \ + } \ + else \ + { \ + FP_SET_EXCEPTION(FP_EX_DENORM); \ + ediff--; \ + if (ediff == 0) \ + { \ + _FP_FRAC_ADD_##wc(R, X, Y); \ + goto add3; \ + } \ + if (X##_e == _FP_EXPMAX_##fs) \ + { \ + _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ + _FP_FRAC_COPY_##wc(R, X); \ + goto add_done; \ + } \ + goto add1; \ + } \ + } \ + else if (X##_e == _FP_EXPMAX_##fs) \ + { \ + /* X is NaN or Inf, Y is normal. */ \ + _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ + _FP_FRAC_COPY_##wc(R, X); \ + goto add_done; \ + } \ + \ + /* Insert implicit MSB of Y. */ \ + _FP_FRAC_HIGH_##fs(Y) |= _FP_IMPLBIT_SH_##fs; \ + \ + add1: \ + /* Shift the mantissa of Y to the right EDIFF steps; \ + remember to account later for the implicit MSB of X. */ \ + if (ediff <= _FP_WFRACBITS_##fs) \ + _FP_FRAC_SRS_##wc(Y, ediff, _FP_WFRACBITS_##fs); \ + else if (!_FP_FRAC_ZEROP_##wc(Y)) \ + _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \ + _FP_FRAC_ADD_##wc(R, X, Y); \ + } \ + else if (ediff < 0) \ + { \ + ediff = -ediff; \ + R##_e = Y##_e; \ + if (X##_e == 0) \ + { \ + /* X is zero or denormalized. */ \ + if (_FP_FRAC_ZEROP_##wc(X)) \ + { \ + _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ + _FP_FRAC_COPY_##wc(R, Y); \ + goto add_done; \ + } \ + else \ + { \ + FP_SET_EXCEPTION(FP_EX_DENORM); \ + ediff--; \ + if (ediff == 0) \ + { \ + _FP_FRAC_ADD_##wc(R, Y, X); \ + goto add3; \ + } \ + if (Y##_e == _FP_EXPMAX_##fs) \ + { \ + _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ + _FP_FRAC_COPY_##wc(R, Y); \ + goto add_done; \ + } \ + goto add2; \ + } \ + } \ + else if (Y##_e == _FP_EXPMAX_##fs) \ + { \ + /* Y is NaN or Inf, X is normal. */ \ + _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ + _FP_FRAC_COPY_##wc(R, Y); \ + goto add_done; \ + } \ + \ + /* Insert implicit MSB of X. */ \ + _FP_FRAC_HIGH_##fs(X) |= _FP_IMPLBIT_SH_##fs; \ + \ + add2: \ + /* Shift the mantissa of X to the right EDIFF steps; \ + remember to account later for the implicit MSB of Y. */ \ + if (ediff <= _FP_WFRACBITS_##fs) \ + _FP_FRAC_SRS_##wc(X, ediff, _FP_WFRACBITS_##fs); \ + else if (!_FP_FRAC_ZEROP_##wc(X)) \ + _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \ + _FP_FRAC_ADD_##wc(R, Y, X); \ + } \ + else \ + { \ + /* ediff == 0. */ \ + if (!_FP_EXP_NORMAL(fs, wc, X)) \ + { \ + if (X##_e == 0) \ + { \ + /* X and Y are zero or denormalized. */ \ + R##_e = 0; \ + if (_FP_FRAC_ZEROP_##wc(X)) \ + { \ + if (!_FP_FRAC_ZEROP_##wc(Y)) \ + FP_SET_EXCEPTION(FP_EX_DENORM); \ + _FP_FRAC_COPY_##wc(R, Y); \ + goto add_done; \ + } \ + else if (_FP_FRAC_ZEROP_##wc(Y)) \ + { \ + FP_SET_EXCEPTION(FP_EX_DENORM); \ + _FP_FRAC_COPY_##wc(R, X); \ + goto add_done; \ + } \ + else \ + { \ + FP_SET_EXCEPTION(FP_EX_DENORM); \ + _FP_FRAC_ADD_##wc(R, X, Y); \ + if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ + { \ + /* Normalized result. */ \ + _FP_FRAC_HIGH_##fs(R) \ + &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \ + R##_e = 1; \ + } \ + goto add_done; \ + } \ + } \ + else \ + { \ + /* X and Y are NaN or Inf. */ \ + _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ + _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ + R##_e = _FP_EXPMAX_##fs; \ + if (_FP_FRAC_ZEROP_##wc(X)) \ + _FP_FRAC_COPY_##wc(R, Y); \ + else if (_FP_FRAC_ZEROP_##wc(Y)) \ + _FP_FRAC_COPY_##wc(R, X); \ + else \ + _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP); \ + goto add_done; \ + } \ + } \ + /* The exponents of X and Y, both normal, are equal. The \ + implicit MSBs will always add to increase the \ + exponent. */ \ + _FP_FRAC_ADD_##wc(R, X, Y); \ + R##_e = X##_e + 1; \ + _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \ + if (R##_e == _FP_EXPMAX_##fs) \ + /* Overflow to infinity (depending on rounding mode). */ \ + _FP_OVERFLOW_SEMIRAW(fs, wc, R); \ + goto add_done; \ + } \ + add3: \ + if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ + { \ + /* Overflow. */ \ _FP_FRAC_HIGH_##fs(R) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \ - } \ - } \ - sub_done: ; \ - } \ -} while (0) + R##_e++; \ + _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \ + if (R##_e == _FP_EXPMAX_##fs) \ + /* Overflow to infinity (depending on rounding mode). */ \ + _FP_OVERFLOW_SEMIRAW(fs, wc, R); \ + } \ + add_done: ; \ + } \ + else \ + { \ + /* Subtraction. */ \ + int ediff = X##_e - Y##_e; \ + if (ediff > 0) \ + { \ + R##_e = X##_e; \ + R##_s = X##_s; \ + if (Y##_e == 0) \ + { \ + /* Y is zero or denormalized. */ \ + if (_FP_FRAC_ZEROP_##wc(Y)) \ + { \ + _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ + _FP_FRAC_COPY_##wc(R, X); \ + goto sub_done; \ + } \ + else \ + { \ + FP_SET_EXCEPTION(FP_EX_DENORM); \ + ediff--; \ + if (ediff == 0) \ + { \ + _FP_FRAC_SUB_##wc(R, X, Y); \ + goto sub3; \ + } \ + if (X##_e == _FP_EXPMAX_##fs) \ + { \ + _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ + _FP_FRAC_COPY_##wc(R, X); \ + goto sub_done; \ + } \ + goto sub1; \ + } \ + } \ + else if (X##_e == _FP_EXPMAX_##fs) \ + { \ + /* X is NaN or Inf, Y is normal. */ \ + _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ + _FP_FRAC_COPY_##wc(R, X); \ + goto sub_done; \ + } \ + \ + /* Insert implicit MSB of Y. */ \ + _FP_FRAC_HIGH_##fs(Y) |= _FP_IMPLBIT_SH_##fs; \ + \ + sub1: \ + /* Shift the mantissa of Y to the right EDIFF steps; \ + remember to account later for the implicit MSB of X. */ \ + if (ediff <= _FP_WFRACBITS_##fs) \ + _FP_FRAC_SRS_##wc(Y, ediff, _FP_WFRACBITS_##fs); \ + else if (!_FP_FRAC_ZEROP_##wc(Y)) \ + _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \ + _FP_FRAC_SUB_##wc(R, X, Y); \ + } \ + else if (ediff < 0) \ + { \ + ediff = -ediff; \ + R##_e = Y##_e; \ + R##_s = Y##_s; \ + if (X##_e == 0) \ + { \ + /* X is zero or denormalized. */ \ + if (_FP_FRAC_ZEROP_##wc(X)) \ + { \ + _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ + _FP_FRAC_COPY_##wc(R, Y); \ + goto sub_done; \ + } \ + else \ + { \ + FP_SET_EXCEPTION(FP_EX_DENORM); \ + ediff--; \ + if (ediff == 0) \ + { \ + _FP_FRAC_SUB_##wc(R, Y, X); \ + goto sub3; \ + } \ + if (Y##_e == _FP_EXPMAX_##fs) \ + { \ + _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ + _FP_FRAC_COPY_##wc(R, Y); \ + goto sub_done; \ + } \ + goto sub2; \ + } \ + } \ + else if (Y##_e == _FP_EXPMAX_##fs) \ + { \ + /* Y is NaN or Inf, X is normal. */ \ + _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ + _FP_FRAC_COPY_##wc(R, Y); \ + goto sub_done; \ + } \ + \ + /* Insert implicit MSB of X. */ \ + _FP_FRAC_HIGH_##fs(X) |= _FP_IMPLBIT_SH_##fs; \ + \ + sub2: \ + /* Shift the mantissa of X to the right EDIFF steps; \ + remember to account later for the implicit MSB of Y. */ \ + if (ediff <= _FP_WFRACBITS_##fs) \ + _FP_FRAC_SRS_##wc(X, ediff, _FP_WFRACBITS_##fs); \ + else if (!_FP_FRAC_ZEROP_##wc(X)) \ + _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \ + _FP_FRAC_SUB_##wc(R, Y, X); \ + } \ + else \ + { \ + /* ediff == 0. */ \ + if (!_FP_EXP_NORMAL(fs, wc, X)) \ + { \ + if (X##_e == 0) \ + { \ + /* X and Y are zero or denormalized. */ \ + R##_e = 0; \ + if (_FP_FRAC_ZEROP_##wc(X)) \ + { \ + _FP_FRAC_COPY_##wc(R, Y); \ + if (_FP_FRAC_ZEROP_##wc(Y)) \ + R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ + else \ + { \ + FP_SET_EXCEPTION(FP_EX_DENORM); \ + R##_s = Y##_s; \ + } \ + goto sub_done; \ + } \ + else if (_FP_FRAC_ZEROP_##wc(Y)) \ + { \ + FP_SET_EXCEPTION(FP_EX_DENORM); \ + _FP_FRAC_COPY_##wc(R, X); \ + R##_s = X##_s; \ + goto sub_done; \ + } \ + else \ + { \ + FP_SET_EXCEPTION(FP_EX_DENORM); \ + _FP_FRAC_SUB_##wc(R, X, Y); \ + R##_s = X##_s; \ + if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ + { \ + /* |X| < |Y|, negate result. */ \ + _FP_FRAC_SUB_##wc(R, Y, X); \ + R##_s = Y##_s; \ + } \ + else if (_FP_FRAC_ZEROP_##wc(R)) \ + R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ + goto sub_done; \ + } \ + } \ + else \ + { \ + /* X and Y are NaN or Inf, of opposite signs. */ \ + _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ + _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ + R##_e = _FP_EXPMAX_##fs; \ + if (_FP_FRAC_ZEROP_##wc(X)) \ + { \ + if (_FP_FRAC_ZEROP_##wc(Y)) \ + { \ + /* Inf - Inf. */ \ + R##_s = _FP_NANSIGN_##fs; \ + _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ + _FP_FRAC_SLL_##wc(R, _FP_WORKBITS); \ + FP_SET_EXCEPTION(FP_EX_INVALID); \ + } \ + else \ + { \ + /* Inf - NaN. */ \ + R##_s = Y##_s; \ + _FP_FRAC_COPY_##wc(R, Y); \ + } \ + } \ + else \ + { \ + if (_FP_FRAC_ZEROP_##wc(Y)) \ + { \ + /* NaN - Inf. */ \ + R##_s = X##_s; \ + _FP_FRAC_COPY_##wc(R, X); \ + } \ + else \ + { \ + /* NaN - NaN. */ \ + _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP); \ + } \ + } \ + goto sub_done; \ + } \ + } \ + /* The exponents of X and Y, both normal, are equal. The \ + implicit MSBs cancel. */ \ + R##_e = X##_e; \ + _FP_FRAC_SUB_##wc(R, X, Y); \ + R##_s = X##_s; \ + if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ + { \ + /* |X| < |Y|, negate result. */ \ + _FP_FRAC_SUB_##wc(R, Y, X); \ + R##_s = Y##_s; \ + } \ + else if (_FP_FRAC_ZEROP_##wc(R)) \ + { \ + R##_e = 0; \ + R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ + goto sub_done; \ + } \ + goto norm; \ + } \ + sub3: \ + if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ + { \ + int diff; \ + /* Carry into most significant bit of larger one of X and Y, \ + canceling it; renormalize. */ \ + _FP_FRAC_HIGH_##fs(R) &= _FP_IMPLBIT_SH_##fs - 1; \ + norm: \ + _FP_FRAC_CLZ_##wc(diff, R); \ + diff -= _FP_WFRACXBITS_##fs; \ + _FP_FRAC_SLL_##wc(R, diff); \ + if (R##_e <= diff) \ + { \ + /* R is denormalized. */ \ + diff = diff - R##_e + 1; \ + _FP_FRAC_SRS_##wc(R, diff, _FP_WFRACBITS_##fs); \ + R##_e = 0; \ + } \ + else \ + { \ + R##_e -= diff; \ + _FP_FRAC_HIGH_##fs(R) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \ + } \ + } \ + sub_done: ; \ + } \ + } \ + while (0) #define _FP_ADD(fs, wc, R, X, Y) _FP_ADD_INTERNAL(fs, wc, R, X, Y, '+') -#define _FP_SUB(fs, wc, R, X, Y) \ - do { \ - if (!(Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) Y##_s ^= 1; \ - _FP_ADD_INTERNAL(fs, wc, R, X, Y, '-'); \ - } while (0) +#define _FP_SUB(fs, wc, R, X, Y) \ + do \ + { \ + if (!(Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \ + Y##_s ^= 1; \ + _FP_ADD_INTERNAL(fs, wc, R, X, Y, '-'); \ + } \ + while (0) /* * Main negation routine. The input value is raw. */ -#define _FP_NEG(fs, wc, R, X) \ - do { \ - _FP_FRAC_COPY_##wc(R, X); \ - R##_e = X##_e; \ - R##_s = 1 ^ X##_s; \ - } while (0) +#define _FP_NEG(fs, wc, R, X) \ + do \ + { \ + _FP_FRAC_COPY_##wc(R, X); \ + R##_e = X##_e; \ + R##_s = 1 ^ X##_s; \ + } \ + while (0) /* * Main multiplication routine. The input values should be cooked. */ -#define _FP_MUL(fs, wc, R, X, Y) \ -do { \ - R##_s = X##_s ^ Y##_s; \ - R##_e = X##_e + Y##_e + 1; \ - switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \ - { \ - case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \ - R##_c = FP_CLS_NORMAL; \ - \ - _FP_MUL_MEAT_##fs(R,X,Y); \ - \ - if (_FP_FRAC_OVERP_##wc(fs, R)) \ - _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \ - else \ - R##_e--; \ - break; \ - \ - case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \ - _FP_CHOOSENAN(fs, wc, R, X, Y, '*'); \ - break; \ - \ - case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \ - case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \ - case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \ - R##_s = X##_s; \ - \ - case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \ - case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \ - case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \ - case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \ - _FP_FRAC_COPY_##wc(R, X); \ - R##_c = X##_c; \ - break; \ - \ - case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \ - case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \ - case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \ - R##_s = Y##_s; \ - \ - case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \ - case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \ - _FP_FRAC_COPY_##wc(R, Y); \ - R##_c = Y##_c; \ - break; \ - \ - case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \ - case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \ - R##_s = _FP_NANSIGN_##fs; \ - R##_c = FP_CLS_NAN; \ - _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ - FP_SET_EXCEPTION(FP_EX_INVALID); \ - break; \ - \ - default: \ - abort(); \ - } \ -} while (0) - - -/* Fused multiply-add. The input values should be cooked. */ - -#define _FP_FMA(fs, wc, dwc, R, X, Y, Z) \ -do { \ - FP_DECL_##fs(T); \ - T##_s = X##_s ^ Y##_s; \ - T##_e = X##_e + Y##_e + 1; \ - switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \ - { \ - case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \ - switch (Z##_c) \ - { \ - case FP_CLS_INF: \ - case FP_CLS_NAN: \ - R##_s = Z##_s; \ - _FP_FRAC_COPY_##wc(R, Z); \ - R##_c = Z##_c; \ - break; \ +#define _FP_MUL(fs, wc, R, X, Y) \ + do \ + { \ + R##_s = X##_s ^ Y##_s; \ + R##_e = X##_e + Y##_e + 1; \ + switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \ + { \ + case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \ + R##_c = FP_CLS_NORMAL; \ \ - case FP_CLS_ZERO: \ - R##_c = FP_CLS_NORMAL; \ - R##_s = T##_s; \ - R##_e = T##_e; \ + _FP_MUL_MEAT_##fs(R,X,Y); \ \ - _FP_MUL_MEAT_##fs(R, X, Y); \ + if (_FP_FRAC_OVERP_##wc(fs, R)) \ + _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \ + else \ + R##_e--; \ + break; \ \ - if (_FP_FRAC_OVERP_##wc(fs, R)) \ - _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \ - else \ - R##_e--; \ - break; \ + case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \ + _FP_CHOOSENAN(fs, wc, R, X, Y, '*'); \ + break; \ \ - case FP_CLS_NORMAL:; \ - _FP_FRAC_DECL_##dwc(TD); \ - _FP_FRAC_DECL_##dwc(ZD); \ - _FP_FRAC_DECL_##dwc(RD); \ - _FP_MUL_MEAT_DW_##fs(TD, X, Y); \ - R##_e = T##_e; \ - int tsh = _FP_FRAC_HIGHBIT_DW_##dwc(fs, TD) == 0; \ - T##_e -= tsh; \ - int ediff = T##_e - Z##_e; \ - if (ediff >= 0) \ - { \ - int shift = _FP_WFRACBITS_##fs - tsh - ediff; \ - if (shift <= -_FP_WFRACBITS_##fs) \ - _FP_FRAC_SET_##dwc(ZD, _FP_MINFRAC_##dwc); \ - else \ - { \ - _FP_FRAC_COPY_##dwc##_##wc(ZD, Z); \ - if (shift < 0) \ - _FP_FRAC_SRS_##dwc(ZD, -shift, \ - _FP_WFRACBITS_DW_##fs); \ - else if (shift > 0) \ - _FP_FRAC_SLL_##dwc(ZD, shift); \ - } \ - R##_s = T##_s; \ - if (T##_s == Z##_s) \ - _FP_FRAC_ADD_##dwc(RD, TD, ZD); \ - else \ - { \ - _FP_FRAC_SUB_##dwc(RD, TD, ZD); \ - if (_FP_FRAC_NEGP_##dwc(RD)) \ - { \ - R##_s = Z##_s; \ - _FP_FRAC_SUB_##dwc(RD, ZD, TD); \ - } \ - } \ - } \ - else \ - { \ - R##_e = Z##_e; \ - R##_s = Z##_s; \ - _FP_FRAC_COPY_##dwc##_##wc(ZD, Z); \ - _FP_FRAC_SLL_##dwc(ZD, _FP_WFRACBITS_##fs); \ - int shift = -ediff - tsh; \ - if (shift >= _FP_WFRACBITS_DW_##fs) \ - _FP_FRAC_SET_##dwc(TD, _FP_MINFRAC_##dwc); \ - else if (shift > 0) \ - _FP_FRAC_SRS_##dwc(TD, shift, \ - _FP_WFRACBITS_DW_##fs); \ - if (Z##_s == T##_s) \ - _FP_FRAC_ADD_##dwc(RD, ZD, TD); \ - else \ - _FP_FRAC_SUB_##dwc(RD, ZD, TD); \ - } \ - if (_FP_FRAC_ZEROP_##dwc(RD)) \ - { \ - if (T##_s == Z##_s) \ - R##_s = Z##_s; \ - else \ - R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ - _FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc); \ - R##_c = FP_CLS_ZERO; \ - } \ - else \ - { \ - int rlz; \ - _FP_FRAC_CLZ_##dwc(rlz, RD); \ - rlz -= _FP_WFRACXBITS_DW_##fs; \ - R##_e -= rlz; \ - int shift = _FP_WFRACBITS_##fs - rlz; \ - if (shift > 0) \ - _FP_FRAC_SRS_##dwc(RD, shift, \ - _FP_WFRACBITS_DW_##fs); \ - else if (shift < 0) \ - _FP_FRAC_SLL_##dwc(RD, -shift); \ - _FP_FRAC_COPY_##wc##_##dwc(R, RD); \ - R##_c = FP_CLS_NORMAL; \ - } \ - break; \ - } \ - goto done_fma; \ + case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \ + case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \ + case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \ + R##_s = X##_s; \ \ - case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \ - _FP_CHOOSENAN(fs, wc, T, X, Y, '*'); \ - break; \ + case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \ + case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \ + case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \ + case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \ + _FP_FRAC_COPY_##wc(R, X); \ + R##_c = X##_c; \ + break; \ \ - case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \ - case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \ - case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \ - T##_s = X##_s; \ + case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \ + case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \ + case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \ + R##_s = Y##_s; \ \ - case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \ - case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \ - case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \ - case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \ - _FP_FRAC_COPY_##wc(T, X); \ - T##_c = X##_c; \ - break; \ + case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \ + case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \ + _FP_FRAC_COPY_##wc(R, Y); \ + R##_c = Y##_c; \ + break; \ \ - case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \ - case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \ - case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \ - T##_s = Y##_s; \ + case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \ + case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \ + R##_s = _FP_NANSIGN_##fs; \ + R##_c = FP_CLS_NAN; \ + _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ + FP_SET_EXCEPTION(FP_EX_INVALID); \ + break; \ \ - case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \ - case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \ - _FP_FRAC_COPY_##wc(T, Y); \ - T##_c = Y##_c; \ - break; \ + default: \ + abort(); \ + } \ + } \ + while (0) + + +/* Fused multiply-add. The input values should be cooked. */ + +#define _FP_FMA(fs, wc, dwc, R, X, Y, Z) \ + do \ + { \ + FP_DECL_##fs(T); \ + T##_s = X##_s ^ Y##_s; \ + T##_e = X##_e + Y##_e + 1; \ + switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \ + { \ + case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \ + switch (Z##_c) \ + { \ + case FP_CLS_INF: \ + case FP_CLS_NAN: \ + R##_s = Z##_s; \ + _FP_FRAC_COPY_##wc(R, Z); \ + R##_c = Z##_c; \ + break; \ + \ + case FP_CLS_ZERO: \ + R##_c = FP_CLS_NORMAL; \ + R##_s = T##_s; \ + R##_e = T##_e; \ + \ + _FP_MUL_MEAT_##fs(R, X, Y); \ + \ + if (_FP_FRAC_OVERP_##wc(fs, R)) \ + _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \ + else \ + R##_e--; \ + break; \ + \ + case FP_CLS_NORMAL:; \ + _FP_FRAC_DECL_##dwc(TD); \ + _FP_FRAC_DECL_##dwc(ZD); \ + _FP_FRAC_DECL_##dwc(RD); \ + _FP_MUL_MEAT_DW_##fs(TD, X, Y); \ + R##_e = T##_e; \ + int tsh = _FP_FRAC_HIGHBIT_DW_##dwc(fs, TD) == 0; \ + T##_e -= tsh; \ + int ediff = T##_e - Z##_e; \ + if (ediff >= 0) \ + { \ + int shift = _FP_WFRACBITS_##fs - tsh - ediff; \ + if (shift <= -_FP_WFRACBITS_##fs) \ + _FP_FRAC_SET_##dwc(ZD, _FP_MINFRAC_##dwc); \ + else \ + { \ + _FP_FRAC_COPY_##dwc##_##wc(ZD, Z); \ + if (shift < 0) \ + _FP_FRAC_SRS_##dwc(ZD, -shift, \ + _FP_WFRACBITS_DW_##fs); \ + else if (shift > 0) \ + _FP_FRAC_SLL_##dwc(ZD, shift); \ + } \ + R##_s = T##_s; \ + if (T##_s == Z##_s) \ + _FP_FRAC_ADD_##dwc(RD, TD, ZD); \ + else \ + { \ + _FP_FRAC_SUB_##dwc(RD, TD, ZD); \ + if (_FP_FRAC_NEGP_##dwc(RD)) \ + { \ + R##_s = Z##_s; \ + _FP_FRAC_SUB_##dwc(RD, ZD, TD); \ + } \ + } \ + } \ + else \ + { \ + R##_e = Z##_e; \ + R##_s = Z##_s; \ + _FP_FRAC_COPY_##dwc##_##wc(ZD, Z); \ + _FP_FRAC_SLL_##dwc(ZD, _FP_WFRACBITS_##fs); \ + int shift = -ediff - tsh; \ + if (shift >= _FP_WFRACBITS_DW_##fs) \ + _FP_FRAC_SET_##dwc(TD, _FP_MINFRAC_##dwc); \ + else if (shift > 0) \ + _FP_FRAC_SRS_##dwc(TD, shift, \ + _FP_WFRACBITS_DW_##fs); \ + if (Z##_s == T##_s) \ + _FP_FRAC_ADD_##dwc(RD, ZD, TD); \ + else \ + _FP_FRAC_SUB_##dwc(RD, ZD, TD); \ + } \ + if (_FP_FRAC_ZEROP_##dwc(RD)) \ + { \ + if (T##_s == Z##_s) \ + R##_s = Z##_s; \ + else \ + R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ + _FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc); \ + R##_c = FP_CLS_ZERO; \ + } \ + else \ + { \ + int rlz; \ + _FP_FRAC_CLZ_##dwc(rlz, RD); \ + rlz -= _FP_WFRACXBITS_DW_##fs; \ + R##_e -= rlz; \ + int shift = _FP_WFRACBITS_##fs - rlz; \ + if (shift > 0) \ + _FP_FRAC_SRS_##dwc(RD, shift, \ + _FP_WFRACBITS_DW_##fs); \ + else if (shift < 0) \ + _FP_FRAC_SLL_##dwc(RD, -shift); \ + _FP_FRAC_COPY_##wc##_##dwc(R, RD); \ + R##_c = FP_CLS_NORMAL; \ + } \ + break; \ + } \ + goto done_fma; \ + \ + case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \ + _FP_CHOOSENAN(fs, wc, T, X, Y, '*'); \ + break; \ + \ + case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \ + case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \ + case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \ + T##_s = X##_s; \ + \ + case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \ + case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \ + case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \ + case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \ + _FP_FRAC_COPY_##wc(T, X); \ + T##_c = X##_c; \ + break; \ + \ + case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \ + case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \ + case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \ + T##_s = Y##_s; \ + \ + case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \ + case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \ + _FP_FRAC_COPY_##wc(T, Y); \ + T##_c = Y##_c; \ + break; \ + \ + case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \ + case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \ + T##_s = _FP_NANSIGN_##fs; \ + T##_c = FP_CLS_NAN; \ + _FP_FRAC_SET_##wc(T, _FP_NANFRAC_##fs); \ + FP_SET_EXCEPTION(FP_EX_INVALID); \ + break; \ + \ + default: \ + abort(); \ + } \ + \ + /* T = X * Y is zero, infinity or NaN. */ \ + switch (_FP_CLS_COMBINE(T##_c, Z##_c)) \ + { \ + case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \ + _FP_CHOOSENAN(fs, wc, R, T, Z, '+'); \ + break; \ + \ + case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \ + case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \ + case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \ + case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \ + case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \ + R##_s = T##_s; \ + _FP_FRAC_COPY_##wc(R, T); \ + R##_c = T##_c; \ + break; \ + \ + case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \ + case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \ + case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \ + case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \ + R##_s = Z##_s; \ + _FP_FRAC_COPY_##wc(R, Z); \ + R##_c = Z##_c; \ + break; \ + \ + case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \ + if (T##_s == Z##_s) \ + { \ + R##_s = Z##_s; \ + _FP_FRAC_COPY_##wc(R, Z); \ + R##_c = Z##_c; \ + } \ + else \ + { \ + R##_s = _FP_NANSIGN_##fs; \ + R##_c = FP_CLS_NAN; \ + _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ + FP_SET_EXCEPTION(FP_EX_INVALID); \ + } \ + break; \ + \ + case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \ + if (T##_s == Z##_s) \ + R##_s = Z##_s; \ + else \ + R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ + _FP_FRAC_COPY_##wc(R, Z); \ + R##_c = Z##_c; \ + break; \ + \ + default: \ + abort(); \ + } \ + done_fma: ; \ + } \ + while (0) + + +/* + * Main division routine. The input values should be cooked. + */ + +#define _FP_DIV(fs, wc, R, X, Y) \ + do \ + { \ + R##_s = X##_s ^ Y##_s; \ + R##_e = X##_e - Y##_e; \ + switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \ + { \ + case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \ + R##_c = FP_CLS_NORMAL; \ \ - case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \ - case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \ - T##_s = _FP_NANSIGN_##fs; \ - T##_c = FP_CLS_NAN; \ - _FP_FRAC_SET_##wc(T, _FP_NANFRAC_##fs); \ - FP_SET_EXCEPTION(FP_EX_INVALID); \ - break; \ + _FP_DIV_MEAT_##fs(R,X,Y); \ + break; \ \ - default: \ - abort(); \ - } \ + case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \ + _FP_CHOOSENAN(fs, wc, R, X, Y, '/'); \ + break; \ \ - /* T = X * Y is zero, infinity or NaN. */ \ - switch (_FP_CLS_COMBINE(T##_c, Z##_c)) \ - { \ - case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \ - _FP_CHOOSENAN(fs, wc, R, T, Z, '+'); \ - break; \ + case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \ + case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \ + case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \ + R##_s = X##_s; \ + _FP_FRAC_COPY_##wc(R, X); \ + R##_c = X##_c; \ + break; \ \ - case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \ - case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \ - case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \ - case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \ - case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \ - R##_s = T##_s; \ - _FP_FRAC_COPY_##wc(R, T); \ - R##_c = T##_c; \ - break; \ + case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \ + case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \ + case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \ + R##_s = Y##_s; \ + _FP_FRAC_COPY_##wc(R, Y); \ + R##_c = Y##_c; \ + break; \ \ - case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \ - case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \ - case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \ - case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \ - R##_s = Z##_s; \ - _FP_FRAC_COPY_##wc(R, Z); \ - R##_c = Z##_c; \ - break; \ + case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \ + case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \ + case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \ + R##_c = FP_CLS_ZERO; \ + break; \ \ - case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \ - if (T##_s == Z##_s) \ - { \ - R##_s = Z##_s; \ - _FP_FRAC_COPY_##wc(R, Z); \ - R##_c = Z##_c; \ - } \ - else \ - { \ - R##_s = _FP_NANSIGN_##fs; \ - R##_c = FP_CLS_NAN; \ - _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ - FP_SET_EXCEPTION(FP_EX_INVALID); \ - } \ - break; \ + case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \ + FP_SET_EXCEPTION(FP_EX_DIVZERO); \ + case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \ + case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \ + R##_c = FP_CLS_INF; \ + break; \ \ - case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \ - if (T##_s == Z##_s) \ - R##_s = Z##_s; \ - else \ - R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ - _FP_FRAC_COPY_##wc(R, Z); \ - R##_c = Z##_c; \ - break; \ + case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \ + case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \ + R##_s = _FP_NANSIGN_##fs; \ + R##_c = FP_CLS_NAN; \ + _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ + FP_SET_EXCEPTION(FP_EX_INVALID); \ + break; \ \ - default: \ - abort(); \ - } \ - done_fma: ; \ -} while (0) - - -/* - * Main division routine. The input values should be cooked. - */ - -#define _FP_DIV(fs, wc, R, X, Y) \ -do { \ - R##_s = X##_s ^ Y##_s; \ - R##_e = X##_e - Y##_e; \ - switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \ - { \ - case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \ - R##_c = FP_CLS_NORMAL; \ - \ - _FP_DIV_MEAT_##fs(R,X,Y); \ - break; \ - \ - case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \ - _FP_CHOOSENAN(fs, wc, R, X, Y, '/'); \ - break; \ - \ - case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \ - case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \ - case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \ - R##_s = X##_s; \ - _FP_FRAC_COPY_##wc(R, X); \ - R##_c = X##_c; \ - break; \ - \ - case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \ - case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \ - case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \ - R##_s = Y##_s; \ - _FP_FRAC_COPY_##wc(R, Y); \ - R##_c = Y##_c; \ - break; \ - \ - case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \ - case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \ - case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \ - R##_c = FP_CLS_ZERO; \ - break; \ - \ - case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \ - FP_SET_EXCEPTION(FP_EX_DIVZERO); \ - case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \ - case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \ - R##_c = FP_CLS_INF; \ - break; \ - \ - case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \ - case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \ - R##_s = _FP_NANSIGN_##fs; \ - R##_c = FP_CLS_NAN; \ - _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ - FP_SET_EXCEPTION(FP_EX_INVALID); \ - break; \ - \ - default: \ - abort(); \ - } \ -} while (0) + default: \ + abort(); \ + } \ + } \ + while (0) /* @@ -1125,122 +1156,131 @@ do { \ */ #define _FP_CMP(fs, wc, ret, X, Y, un) \ - do { \ - /* NANs are unordered */ \ - if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \ - || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \ - { \ - ret = un; \ - } \ - else \ - { \ - int __is_zero_x; \ - int __is_zero_y; \ + do \ + { \ + /* NANs are unordered */ \ + if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \ + || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \ + { \ + ret = un; \ + } \ + else \ + { \ + int __is_zero_x; \ + int __is_zero_y; \ \ - __is_zero_x = (!X##_e && _FP_FRAC_ZEROP_##wc(X)) ? 1 : 0; \ - __is_zero_y = (!Y##_e && _FP_FRAC_ZEROP_##wc(Y)) ? 1 : 0; \ + __is_zero_x = (!X##_e && _FP_FRAC_ZEROP_##wc(X)) ? 1 : 0; \ + __is_zero_y = (!Y##_e && _FP_FRAC_ZEROP_##wc(Y)) ? 1 : 0; \ \ - if (__is_zero_x && __is_zero_y) \ - ret = 0; \ - else if (__is_zero_x) \ - ret = Y##_s ? 1 : -1; \ - else if (__is_zero_y) \ - ret = X##_s ? -1 : 1; \ - else if (X##_s != Y##_s) \ - ret = X##_s ? -1 : 1; \ - else if (X##_e > Y##_e) \ - ret = X##_s ? -1 : 1; \ - else if (X##_e < Y##_e) \ - ret = X##_s ? 1 : -1; \ - else if (_FP_FRAC_GT_##wc(X, Y)) \ - ret = X##_s ? -1 : 1; \ - else if (_FP_FRAC_GT_##wc(Y, X)) \ - ret = X##_s ? 1 : -1; \ - else \ - ret = 0; \ - } \ - } while (0) + if (__is_zero_x && __is_zero_y) \ + ret = 0; \ + else if (__is_zero_x) \ + ret = Y##_s ? 1 : -1; \ + else if (__is_zero_y) \ + ret = X##_s ? -1 : 1; \ + else if (X##_s != Y##_s) \ + ret = X##_s ? -1 : 1; \ + else if (X##_e > Y##_e) \ + ret = X##_s ? -1 : 1; \ + else if (X##_e < Y##_e) \ + ret = X##_s ? 1 : -1; \ + else if (_FP_FRAC_GT_##wc(X, Y)) \ + ret = X##_s ? -1 : 1; \ + else if (_FP_FRAC_GT_##wc(Y, X)) \ + ret = X##_s ? 1 : -1; \ + else \ + ret = 0; \ + } \ + } \ + while (0) /* Simplification for strict equality. */ -#define _FP_CMP_EQ(fs, wc, ret, X, Y) \ - do { \ - /* NANs are unordered */ \ - if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \ - || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \ - { \ - ret = 1; \ - } \ - else \ - { \ - ret = !(X##_e == Y##_e \ - && _FP_FRAC_EQ_##wc(X, Y) \ - && (X##_s == Y##_s || (!X##_e && _FP_FRAC_ZEROP_##wc(X)))); \ - } \ - } while (0) +#define _FP_CMP_EQ(fs, wc, ret, X, Y) \ + do \ + { \ + /* NANs are unordered */ \ + if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \ + || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \ + { \ + ret = 1; \ + } \ + else \ + { \ + ret = !(X##_e == Y##_e \ + && _FP_FRAC_EQ_##wc(X, Y) \ + && (X##_s == Y##_s || (!X##_e && _FP_FRAC_ZEROP_##wc(X)))); \ + } \ + } \ + while (0) /* Version to test unordered. */ #define _FP_CMP_UNORD(fs, wc, ret, X, Y) \ - do { \ - ret = ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \ - || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))); \ - } while (0) + do \ + { \ + ret = ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \ + || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))); \ + } \ + while (0) /* * Main square root routine. The input value should be cooked. */ -#define _FP_SQRT(fs, wc, R, X) \ -do { \ - _FP_FRAC_DECL_##wc(T); _FP_FRAC_DECL_##wc(S); \ - _FP_W_TYPE q; \ - switch (X##_c) \ - { \ - case FP_CLS_NAN: \ - _FP_FRAC_COPY_##wc(R, X); \ - R##_s = X##_s; \ - R##_c = FP_CLS_NAN; \ - break; \ - case FP_CLS_INF: \ - if (X##_s) \ - { \ - R##_s = _FP_NANSIGN_##fs; \ - R##_c = FP_CLS_NAN; /* NAN */ \ - _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ - FP_SET_EXCEPTION(FP_EX_INVALID); \ - } \ - else \ - { \ - R##_s = 0; \ - R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */ \ - } \ - break; \ - case FP_CLS_ZERO: \ - R##_s = X##_s; \ - R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */ \ - break; \ - case FP_CLS_NORMAL: \ - R##_s = 0; \ - if (X##_s) \ - { \ - R##_c = FP_CLS_NAN; /* NAN */ \ - R##_s = _FP_NANSIGN_##fs; \ - _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ - FP_SET_EXCEPTION(FP_EX_INVALID); \ - break; \ - } \ - R##_c = FP_CLS_NORMAL; \ - if (X##_e & 1) \ - _FP_FRAC_SLL_##wc(X, 1); \ - R##_e = X##_e >> 1; \ - _FP_FRAC_SET_##wc(S, _FP_ZEROFRAC_##wc); \ - _FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc); \ - q = _FP_OVERFLOW_##fs >> 1; \ - _FP_SQRT_MEAT_##wc(R, S, T, X, q); \ - } \ - } while (0) +#define _FP_SQRT(fs, wc, R, X) \ + do \ + { \ + _FP_FRAC_DECL_##wc(T); \ + _FP_FRAC_DECL_##wc(S); \ + _FP_W_TYPE q; \ + switch (X##_c) \ + { \ + case FP_CLS_NAN: \ + _FP_FRAC_COPY_##wc(R, X); \ + R##_s = X##_s; \ + R##_c = FP_CLS_NAN; \ + break; \ + case FP_CLS_INF: \ + if (X##_s) \ + { \ + R##_s = _FP_NANSIGN_##fs; \ + R##_c = FP_CLS_NAN; /* NAN */ \ + _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ + FP_SET_EXCEPTION(FP_EX_INVALID); \ + } \ + else \ + { \ + R##_s = 0; \ + R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */ \ + } \ + break; \ + case FP_CLS_ZERO: \ + R##_s = X##_s; \ + R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */ \ + break; \ + case FP_CLS_NORMAL: \ + R##_s = 0; \ + if (X##_s) \ + { \ + R##_c = FP_CLS_NAN; /* NAN */ \ + R##_s = _FP_NANSIGN_##fs; \ + _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ + FP_SET_EXCEPTION(FP_EX_INVALID); \ + break; \ + } \ + R##_c = FP_CLS_NORMAL; \ + if (X##_e & 1) \ + _FP_FRAC_SLL_##wc(X, 1); \ + R##_e = X##_e >> 1; \ + _FP_FRAC_SET_##wc(S, _FP_ZEROFRAC_##wc); \ + _FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc); \ + q = _FP_OVERFLOW_##fs >> 1; \ + _FP_SQRT_MEAT_##wc(R, S, T, X, q); \ + } \ + } \ + while (0) /* * Convert from FP to integer. Input is raw. @@ -1258,292 +1298,303 @@ do { \ * depending on the sign in such case. */ #define _FP_TO_INT(fs, wc, r, X, rsize, rsigned) \ -do { \ - if (X##_e < _FP_EXPBIAS_##fs) \ + do \ { \ - r = 0; \ - if (X##_e == 0) \ + if (X##_e < _FP_EXPBIAS_##fs) \ { \ - if (!_FP_FRAC_ZEROP_##wc(X)) \ + r = 0; \ + if (X##_e == 0) \ { \ - FP_SET_EXCEPTION(FP_EX_INEXACT); \ - FP_SET_EXCEPTION(FP_EX_DENORM); \ + if (!_FP_FRAC_ZEROP_##wc(X)) \ + { \ + FP_SET_EXCEPTION(FP_EX_INEXACT); \ + FP_SET_EXCEPTION(FP_EX_DENORM); \ + } \ } \ + else \ + FP_SET_EXCEPTION(FP_EX_INEXACT); \ } \ - else \ - FP_SET_EXCEPTION(FP_EX_INEXACT); \ - } \ - else if (X##_e >= _FP_EXPBIAS_##fs + rsize - (rsigned > 0 || X##_s) \ - || (!rsigned && X##_s)) \ - { \ - /* Overflow or converting to the most negative integer. */ \ - if (rsigned) \ + else if (X##_e >= _FP_EXPBIAS_##fs + rsize - (rsigned > 0 || X##_s) \ + || (!rsigned && X##_s)) \ { \ - r = 1; \ - r <<= rsize - 1; \ - r -= 1 - X##_s; \ - } else { \ - r = 0; \ - if (!X##_s) \ - r = ~r; \ - } \ + /* Overflow or converting to the most negative integer. */ \ + if (rsigned) \ + { \ + r = 1; \ + r <<= rsize - 1; \ + r -= 1 - X##_s; \ + } else { \ + r = 0; \ + if (!X##_s) \ + r = ~r; \ + } \ \ - if (rsigned && X##_s && X##_e == _FP_EXPBIAS_##fs + rsize - 1) \ - { \ - /* Possibly converting to most negative integer; check the \ - mantissa. */ \ - int inexact = 0; \ - (void)((_FP_FRACBITS_##fs > rsize) \ - ? ({ _FP_FRAC_SRST_##wc(X, inexact, \ - _FP_FRACBITS_##fs - rsize, \ - _FP_FRACBITS_##fs); 0; }) \ - : 0); \ - if (!_FP_FRAC_ZEROP_##wc(X)) \ + if (rsigned && X##_s && X##_e == _FP_EXPBIAS_##fs + rsize - 1) \ + { \ + /* Possibly converting to most negative integer; check the \ + mantissa. */ \ + int inexact = 0; \ + (void)((_FP_FRACBITS_##fs > rsize) \ + ? ({ \ + _FP_FRAC_SRST_##wc(X, inexact, \ + _FP_FRACBITS_##fs - rsize, \ + _FP_FRACBITS_##fs); \ + 0; \ + }) \ + : 0); \ + if (!_FP_FRAC_ZEROP_##wc(X)) \ + FP_SET_EXCEPTION(FP_EX_INVALID); \ + else if (inexact) \ + FP_SET_EXCEPTION(FP_EX_INEXACT); \ + } \ + else \ FP_SET_EXCEPTION(FP_EX_INVALID); \ - else if (inexact) \ - FP_SET_EXCEPTION(FP_EX_INEXACT); \ } \ else \ - FP_SET_EXCEPTION(FP_EX_INVALID); \ + { \ + _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs; \ + if (X##_e >= _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1) \ + { \ + _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \ + r <<= X##_e - _FP_EXPBIAS_##fs - _FP_FRACBITS_##fs + 1; \ + } \ + else \ + { \ + int inexact; \ + _FP_FRAC_SRST_##wc(X, inexact, \ + (_FP_FRACBITS_##fs + _FP_EXPBIAS_##fs - 1 \ + - X##_e), \ + _FP_FRACBITS_##fs); \ + if (inexact) \ + FP_SET_EXCEPTION(FP_EX_INEXACT); \ + _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \ + } \ + if (rsigned && X##_s) \ + r = -r; \ + } \ } \ - else \ + while (0) + +/* Convert integer to fp. Output is raw. RTYPE is unsigned even if + input is signed. */ +#define _FP_FROM_INT(fs, wc, X, r, rsize, rtype) \ + do \ { \ - _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs; \ - if (X##_e >= _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1) \ + if (r) \ { \ - _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \ - r <<= X##_e - _FP_EXPBIAS_##fs - _FP_FRACBITS_##fs + 1; \ + rtype ur_; \ + \ + if ((X##_s = (r < 0))) \ + r = -(rtype)r; \ + \ + ur_ = (rtype) r; \ + (void)((rsize <= _FP_W_TYPE_SIZE) \ + ? ({ \ + int lz_; \ + __FP_CLZ(lz_, (_FP_W_TYPE)ur_); \ + X##_e = _FP_EXPBIAS_##fs + _FP_W_TYPE_SIZE - 1 - lz_; \ + }) \ + : ((rsize <= 2 * _FP_W_TYPE_SIZE) \ + ? ({ \ + int lz_; \ + __FP_CLZ_2(lz_, (_FP_W_TYPE)(ur_ >> _FP_W_TYPE_SIZE), \ + (_FP_W_TYPE)ur_); \ + X##_e = (_FP_EXPBIAS_##fs + 2 * _FP_W_TYPE_SIZE - 1 \ + - lz_); \ + }) \ + : (abort(), 0))); \ + \ + if (rsize - 1 + _FP_EXPBIAS_##fs >= _FP_EXPMAX_##fs \ + && X##_e >= _FP_EXPMAX_##fs) \ + { \ + /* Exponent too big; overflow to infinity. (May also \ + happen after rounding below.) */ \ + _FP_OVERFLOW_SEMIRAW(fs, wc, X); \ + goto pack_semiraw; \ + } \ + \ + if (rsize <= _FP_FRACBITS_##fs \ + || X##_e < _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs) \ + { \ + /* Exactly representable; shift left. */ \ + _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize); \ + if (_FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1 - X##_e > 0) \ + _FP_FRAC_SLL_##wc(X, (_FP_EXPBIAS_##fs \ + + _FP_FRACBITS_##fs - 1 - X##_e)); \ + } \ + else \ + { \ + /* More bits in integer than in floating type; need to \ + round. */ \ + if (_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 < X##_e) \ + ur_ = ((ur_ >> (X##_e - _FP_EXPBIAS_##fs \ + - _FP_WFRACBITS_##fs + 1)) \ + | ((ur_ << (rsize - (X##_e - _FP_EXPBIAS_##fs \ + - _FP_WFRACBITS_##fs + 1))) \ + != 0)); \ + _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize); \ + if ((_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 - X##_e) > 0) \ + _FP_FRAC_SLL_##wc(X, (_FP_EXPBIAS_##fs \ + + _FP_WFRACBITS_##fs - 1 - X##_e)); \ + _FP_FRAC_HIGH_##fs(X) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \ + pack_semiraw: \ + _FP_PACK_SEMIRAW(fs, wc, X); \ + } \ } \ else \ { \ - int inexact; \ - _FP_FRAC_SRST_##wc(X, inexact, \ - (_FP_FRACBITS_##fs + _FP_EXPBIAS_##fs - 1 \ - - X##_e), \ - _FP_FRACBITS_##fs); \ - if (inexact) \ - FP_SET_EXCEPTION(FP_EX_INEXACT); \ - _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \ + X##_s = 0; \ + X##_e = 0; \ + _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ } \ - if (rsigned && X##_s) \ - r = -r; \ } \ -} while (0) - -/* Convert integer to fp. Output is raw. RTYPE is unsigned even if - input is signed. */ -#define _FP_FROM_INT(fs, wc, X, r, rsize, rtype) \ - do { \ - if (r) \ - { \ - rtype ur_; \ - \ - if ((X##_s = (r < 0))) \ - r = -(rtype)r; \ - \ - ur_ = (rtype) r; \ - (void)((rsize <= _FP_W_TYPE_SIZE) \ - ? ({ \ - int lz_; \ - __FP_CLZ(lz_, (_FP_W_TYPE)ur_); \ - X##_e = _FP_EXPBIAS_##fs + _FP_W_TYPE_SIZE - 1 - lz_; \ - }) \ - : ((rsize <= 2 * _FP_W_TYPE_SIZE) \ - ? ({ \ - int lz_; \ - __FP_CLZ_2(lz_, (_FP_W_TYPE)(ur_ >> _FP_W_TYPE_SIZE), \ - (_FP_W_TYPE)ur_); \ - X##_e = (_FP_EXPBIAS_##fs + 2 * _FP_W_TYPE_SIZE - 1 \ - - lz_); \ - }) \ - : (abort(), 0))); \ - \ - if (rsize - 1 + _FP_EXPBIAS_##fs >= _FP_EXPMAX_##fs \ - && X##_e >= _FP_EXPMAX_##fs) \ - { \ - /* Exponent too big; overflow to infinity. (May also \ - happen after rounding below.) */ \ - _FP_OVERFLOW_SEMIRAW(fs, wc, X); \ - goto pack_semiraw; \ - } \ - \ - if (rsize <= _FP_FRACBITS_##fs \ - || X##_e < _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs) \ - { \ - /* Exactly representable; shift left. */ \ - _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize); \ - if (_FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1 - X##_e > 0) \ - _FP_FRAC_SLL_##wc(X, (_FP_EXPBIAS_##fs \ - + _FP_FRACBITS_##fs - 1 - X##_e)); \ - } \ - else \ - { \ - /* More bits in integer than in floating type; need to \ - round. */ \ - if (_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 < X##_e) \ - ur_ = ((ur_ >> (X##_e - _FP_EXPBIAS_##fs \ - - _FP_WFRACBITS_##fs + 1)) \ - | ((ur_ << (rsize - (X##_e - _FP_EXPBIAS_##fs \ - - _FP_WFRACBITS_##fs + 1))) \ - != 0)); \ - _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize); \ - if ((_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 - X##_e) > 0) \ - _FP_FRAC_SLL_##wc(X, (_FP_EXPBIAS_##fs \ - + _FP_WFRACBITS_##fs - 1 - X##_e)); \ - _FP_FRAC_HIGH_##fs(X) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \ - pack_semiraw: \ - _FP_PACK_SEMIRAW(fs, wc, X); \ - } \ - } \ - else \ - { \ - X##_s = 0; \ - X##_e = 0; \ - _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ - } \ - } while (0) + while (0) /* Extend from a narrower floating-point format to a wider one. Input and output are raw. */ -#define FP_EXTEND(dfs,sfs,dwc,swc,D,S) \ -do { \ - if (_FP_FRACBITS_##dfs < _FP_FRACBITS_##sfs \ - || (_FP_EXPMAX_##dfs - _FP_EXPBIAS_##dfs \ - < _FP_EXPMAX_##sfs - _FP_EXPBIAS_##sfs) \ - || (_FP_EXPBIAS_##dfs < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1 \ - && _FP_EXPBIAS_##dfs != _FP_EXPBIAS_##sfs)) \ - abort(); \ - D##_s = S##_s; \ - _FP_FRAC_COPY_##dwc##_##swc(D, S); \ - if (_FP_EXP_NORMAL(sfs, swc, S)) \ - { \ - D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \ - _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs - _FP_FRACBITS_##sfs)); \ - } \ - else \ - { \ - if (S##_e == 0) \ - { \ - if (_FP_FRAC_ZEROP_##swc(S)) \ - D##_e = 0; \ - else if (_FP_EXPBIAS_##dfs \ - < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1) \ - { \ - FP_SET_EXCEPTION(FP_EX_DENORM); \ - _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs \ - - _FP_FRACBITS_##sfs)); \ - D##_e = 0; \ - } \ - else \ - { \ - int _lz; \ - FP_SET_EXCEPTION(FP_EX_DENORM); \ - _FP_FRAC_CLZ_##swc(_lz, S); \ - _FP_FRAC_SLL_##dwc(D, \ - _lz + _FP_FRACBITS_##dfs \ - - _FP_FRACTBITS_##sfs); \ - D##_e = (_FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs + 1 \ - + _FP_FRACXBITS_##sfs - _lz); \ - } \ - } \ - else \ - { \ - D##_e = _FP_EXPMAX_##dfs; \ - if (!_FP_FRAC_ZEROP_##swc(S)) \ - { \ - if (_FP_FRAC_SNANP(sfs, S)) \ - FP_SET_EXCEPTION(FP_EX_INVALID); \ - _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs \ - - _FP_FRACBITS_##sfs)); \ - } \ - } \ - } \ -} while (0) +#define FP_EXTEND(dfs,sfs,dwc,swc,D,S) \ + do \ + { \ + if (_FP_FRACBITS_##dfs < _FP_FRACBITS_##sfs \ + || (_FP_EXPMAX_##dfs - _FP_EXPBIAS_##dfs \ + < _FP_EXPMAX_##sfs - _FP_EXPBIAS_##sfs) \ + || (_FP_EXPBIAS_##dfs < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1 \ + && _FP_EXPBIAS_##dfs != _FP_EXPBIAS_##sfs)) \ + abort(); \ + D##_s = S##_s; \ + _FP_FRAC_COPY_##dwc##_##swc(D, S); \ + if (_FP_EXP_NORMAL(sfs, swc, S)) \ + { \ + D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \ + _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs - _FP_FRACBITS_##sfs)); \ + } \ + else \ + { \ + if (S##_e == 0) \ + { \ + if (_FP_FRAC_ZEROP_##swc(S)) \ + D##_e = 0; \ + else if (_FP_EXPBIAS_##dfs \ + < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1) \ + { \ + FP_SET_EXCEPTION(FP_EX_DENORM); \ + _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs \ + - _FP_FRACBITS_##sfs)); \ + D##_e = 0; \ + } \ + else \ + { \ + int _lz; \ + FP_SET_EXCEPTION(FP_EX_DENORM); \ + _FP_FRAC_CLZ_##swc(_lz, S); \ + _FP_FRAC_SLL_##dwc(D, \ + _lz + _FP_FRACBITS_##dfs \ + - _FP_FRACTBITS_##sfs); \ + D##_e = (_FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs + 1 \ + + _FP_FRACXBITS_##sfs - _lz); \ + } \ + } \ + else \ + { \ + D##_e = _FP_EXPMAX_##dfs; \ + if (!_FP_FRAC_ZEROP_##swc(S)) \ + { \ + if (_FP_FRAC_SNANP(sfs, S)) \ + FP_SET_EXCEPTION(FP_EX_INVALID); \ + _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs \ + - _FP_FRACBITS_##sfs)); \ + } \ + } \ + } \ + } \ + while (0) /* Truncate from a wider floating-point format to a narrower one. Input and output are semi-raw. */ -#define FP_TRUNC(dfs,sfs,dwc,swc,D,S) \ -do { \ - if (_FP_FRACBITS_##sfs < _FP_FRACBITS_##dfs \ - || (_FP_EXPBIAS_##sfs < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1 \ - && _FP_EXPBIAS_##sfs != _FP_EXPBIAS_##dfs)) \ - abort(); \ - D##_s = S##_s; \ - if (_FP_EXP_NORMAL(sfs, swc, S)) \ - { \ - D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \ - if (D##_e >= _FP_EXPMAX_##dfs) \ - _FP_OVERFLOW_SEMIRAW(dfs, dwc, D); \ - else \ - { \ - if (D##_e <= 0) \ - { \ - if (D##_e < 1 - _FP_FRACBITS_##dfs) \ - { \ - _FP_FRAC_SET_##swc(S, _FP_ZEROFRAC_##swc); \ - _FP_FRAC_LOW_##swc(S) |= 1; \ - } \ - else \ - { \ - _FP_FRAC_HIGH_##sfs(S) |= _FP_IMPLBIT_SH_##sfs; \ - _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \ - - _FP_WFRACBITS_##dfs + 1 - D##_e), \ - _FP_WFRACBITS_##sfs); \ - } \ - D##_e = 0; \ - } \ - else \ - _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \ - - _FP_WFRACBITS_##dfs), \ - _FP_WFRACBITS_##sfs); \ - _FP_FRAC_COPY_##dwc##_##swc(D, S); \ - } \ - } \ - else \ - { \ - if (S##_e == 0) \ - { \ - D##_e = 0; \ - if (_FP_FRAC_ZEROP_##swc(S)) \ - _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \ - else \ - { \ - FP_SET_EXCEPTION(FP_EX_DENORM); \ - if (_FP_EXPBIAS_##sfs \ - < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1) \ - { \ - _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \ - - _FP_WFRACBITS_##dfs), \ - _FP_WFRACBITS_##sfs); \ - _FP_FRAC_COPY_##dwc##_##swc(D, S); \ - } \ - else \ - { \ - _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \ - _FP_FRAC_LOW_##dwc(D) |= 1; \ - } \ - } \ - } \ - else \ - { \ - D##_e = _FP_EXPMAX_##dfs; \ - if (_FP_FRAC_ZEROP_##swc(S)) \ - _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \ - else \ - { \ - _FP_CHECK_SIGNAN_SEMIRAW(sfs, swc, S); \ - _FP_FRAC_SRL_##swc(S, (_FP_WFRACBITS_##sfs \ - - _FP_WFRACBITS_##dfs)); \ - _FP_FRAC_COPY_##dwc##_##swc(D, S); \ - /* Semi-raw NaN must have all workbits cleared. */ \ - _FP_FRAC_LOW_##dwc(D) \ - &= ~(_FP_W_TYPE) ((1 << _FP_WORKBITS) - 1); \ - _FP_SETQNAN_SEMIRAW(dfs, dwc, D); \ - } \ - } \ - } \ -} while (0) +#define FP_TRUNC(dfs,sfs,dwc,swc,D,S) \ + do \ + { \ + if (_FP_FRACBITS_##sfs < _FP_FRACBITS_##dfs \ + || (_FP_EXPBIAS_##sfs < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1 \ + && _FP_EXPBIAS_##sfs != _FP_EXPBIAS_##dfs)) \ + abort(); \ + D##_s = S##_s; \ + if (_FP_EXP_NORMAL(sfs, swc, S)) \ + { \ + D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \ + if (D##_e >= _FP_EXPMAX_##dfs) \ + _FP_OVERFLOW_SEMIRAW(dfs, dwc, D); \ + else \ + { \ + if (D##_e <= 0) \ + { \ + if (D##_e < 1 - _FP_FRACBITS_##dfs) \ + { \ + _FP_FRAC_SET_##swc(S, _FP_ZEROFRAC_##swc); \ + _FP_FRAC_LOW_##swc(S) |= 1; \ + } \ + else \ + { \ + _FP_FRAC_HIGH_##sfs(S) |= _FP_IMPLBIT_SH_##sfs; \ + _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \ + - _FP_WFRACBITS_##dfs + 1 - D##_e), \ + _FP_WFRACBITS_##sfs); \ + } \ + D##_e = 0; \ + } \ + else \ + _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \ + - _FP_WFRACBITS_##dfs), \ + _FP_WFRACBITS_##sfs); \ + _FP_FRAC_COPY_##dwc##_##swc(D, S); \ + } \ + } \ + else \ + { \ + if (S##_e == 0) \ + { \ + D##_e = 0; \ + if (_FP_FRAC_ZEROP_##swc(S)) \ + _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \ + else \ + { \ + FP_SET_EXCEPTION(FP_EX_DENORM); \ + if (_FP_EXPBIAS_##sfs \ + < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1) \ + { \ + _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \ + - _FP_WFRACBITS_##dfs), \ + _FP_WFRACBITS_##sfs); \ + _FP_FRAC_COPY_##dwc##_##swc(D, S); \ + } \ + else \ + { \ + _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \ + _FP_FRAC_LOW_##dwc(D) |= 1; \ + } \ + } \ + } \ + else \ + { \ + D##_e = _FP_EXPMAX_##dfs; \ + if (_FP_FRAC_ZEROP_##swc(S)) \ + _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \ + else \ + { \ + _FP_CHECK_SIGNAN_SEMIRAW(sfs, swc, S); \ + _FP_FRAC_SRL_##swc(S, (_FP_WFRACBITS_##sfs \ + - _FP_WFRACBITS_##dfs)); \ + _FP_FRAC_COPY_##dwc##_##swc(D, S); \ + /* Semi-raw NaN must have all workbits cleared. */ \ + _FP_FRAC_LOW_##dwc(D) \ + &= ~(_FP_W_TYPE) ((1 << _FP_WORKBITS) - 1); \ + _FP_SETQNAN_SEMIRAW(dfs, dwc, D); \ + } \ + } \ + } \ + } \ + while (0) /* * Helper primitives. @@ -1553,64 +1604,72 @@ do { \ #ifndef __FP_CLZ /* GCC 3.4 and later provide the builtins for us. */ -# define __FP_CLZ(r, x) \ - do { \ - if (sizeof (_FP_W_TYPE) == sizeof (unsigned int)) \ - r = __builtin_clz (x); \ - else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long)) \ - r = __builtin_clzl (x); \ - else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long long)) \ - r = __builtin_clzll (x); \ - else \ - abort (); \ - } while (0) +# define __FP_CLZ(r, x) \ + do \ + { \ + if (sizeof (_FP_W_TYPE) == sizeof (unsigned int)) \ + r = __builtin_clz (x); \ + else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long)) \ + r = __builtin_clzl (x); \ + else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long long)) \ + r = __builtin_clzll (x); \ + else \ + abort (); \ + } \ + while (0) #endif /* ndef __FP_CLZ */ #define _FP_DIV_HELP_imm(q, r, n, d) \ - do { \ - q = n / d, r = n % d; \ - } while (0) + do \ + { \ + q = n / d, r = n % d; \ + } \ + while (0) /* A restoring bit-by-bit division primitive. */ #define _FP_DIV_MEAT_N_loop(fs, wc, R, X, Y) \ - do { \ - int count = _FP_WFRACBITS_##fs; \ - _FP_FRAC_DECL_##wc (u); \ - _FP_FRAC_DECL_##wc (v); \ - _FP_FRAC_COPY_##wc (u, X); \ - _FP_FRAC_COPY_##wc (v, Y); \ - _FP_FRAC_SET_##wc (R, _FP_ZEROFRAC_##wc); \ - /* Normalize U and V. */ \ - _FP_FRAC_SLL_##wc (u, _FP_WFRACXBITS_##fs); \ - _FP_FRAC_SLL_##wc (v, _FP_WFRACXBITS_##fs); \ - /* First round. Since the operands are normalized, either the \ - first or second bit will be set in the fraction. Produce a \ - normalized result by checking which and adjusting the loop \ - count and exponent accordingly. */ \ - if (_FP_FRAC_GE_1 (u, v)) \ - { \ - _FP_FRAC_SUB_##wc (u, u, v); \ - _FP_FRAC_LOW_##wc (R) |= 1; \ - count--; \ - } \ - else \ - R##_e--; \ - /* Subsequent rounds. */ \ - do { \ - int msb = (_FP_WS_TYPE) _FP_FRAC_HIGH_##wc (u) < 0; \ - _FP_FRAC_SLL_##wc (u, 1); \ - _FP_FRAC_SLL_##wc (R, 1); \ - if (msb || _FP_FRAC_GE_1 (u, v)) \ + do \ + { \ + int count = _FP_WFRACBITS_##fs; \ + _FP_FRAC_DECL_##wc (u); \ + _FP_FRAC_DECL_##wc (v); \ + _FP_FRAC_COPY_##wc (u, X); \ + _FP_FRAC_COPY_##wc (v, Y); \ + _FP_FRAC_SET_##wc (R, _FP_ZEROFRAC_##wc); \ + /* Normalize U and V. */ \ + _FP_FRAC_SLL_##wc (u, _FP_WFRACXBITS_##fs); \ + _FP_FRAC_SLL_##wc (v, _FP_WFRACXBITS_##fs); \ + /* First round. Since the operands are normalized, either the \ + first or second bit will be set in the fraction. Produce a \ + normalized result by checking which and adjusting the loop \ + count and exponent accordingly. */ \ + if (_FP_FRAC_GE_1 (u, v)) \ { \ _FP_FRAC_SUB_##wc (u, u, v); \ _FP_FRAC_LOW_##wc (R) |= 1; \ + count--; \ } \ - } while (--count > 0); \ - /* If there's anything left in U, the result is inexact. */ \ - _FP_FRAC_LOW_##wc (R) |= !_FP_FRAC_ZEROP_##wc (u); \ - } while (0) + else \ + R##_e--; \ + /* Subsequent rounds. */ \ + do \ + { \ + int msb = (_FP_WS_TYPE) _FP_FRAC_HIGH_##wc (u) < 0; \ + _FP_FRAC_SLL_##wc (u, 1); \ + _FP_FRAC_SLL_##wc (R, 1); \ + if (msb || _FP_FRAC_GE_1 (u, v)) \ + { \ + _FP_FRAC_SUB_##wc (u, u, v); \ + _FP_FRAC_LOW_##wc (R) |= 1; \ + } \ + } \ + while (--count > 0); \ + /* If there's anything left in U, the result is inexact. */ \ + _FP_FRAC_LOW_##wc (R) |= !_FP_FRAC_ZEROP_##wc (u); \ + } \ + while (0) #define _FP_DIV_MEAT_1_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 1, R, X, Y) #define _FP_DIV_MEAT_2_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 2, R, X, Y) diff --git a/soft-fp/quad.h b/soft-fp/quad.h index af24a5e..a651ad9 100644 --- a/soft-fp/quad.h +++ b/soft-fp/quad.h @@ -72,25 +72,25 @@ typedef float TFtype __attribute__((mode(TF))); union _FP_UNION_Q { - TFtype flt; - struct _FP_STRUCT_LAYOUT - { + TFtype flt; + struct _FP_STRUCT_LAYOUT + { # if __BYTE_ORDER == __BIG_ENDIAN - unsigned sign : 1; - unsigned exp : _FP_EXPBITS_Q; - unsigned long frac3 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0)-(_FP_W_TYPE_SIZE * 3); - unsigned long frac2 : _FP_W_TYPE_SIZE; - unsigned long frac1 : _FP_W_TYPE_SIZE; - unsigned long frac0 : _FP_W_TYPE_SIZE; + unsigned sign : 1; + unsigned exp : _FP_EXPBITS_Q; + unsigned long frac3 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0)-(_FP_W_TYPE_SIZE * 3); + unsigned long frac2 : _FP_W_TYPE_SIZE; + unsigned long frac1 : _FP_W_TYPE_SIZE; + unsigned long frac0 : _FP_W_TYPE_SIZE; # else - unsigned long frac0 : _FP_W_TYPE_SIZE; - unsigned long frac1 : _FP_W_TYPE_SIZE; - unsigned long frac2 : _FP_W_TYPE_SIZE; - unsigned long frac3 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0)-(_FP_W_TYPE_SIZE * 3); - unsigned exp : _FP_EXPBITS_Q; - unsigned sign : 1; + unsigned long frac0 : _FP_W_TYPE_SIZE; + unsigned long frac1 : _FP_W_TYPE_SIZE; + unsigned long frac2 : _FP_W_TYPE_SIZE; + unsigned long frac3 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0)-(_FP_W_TYPE_SIZE * 3); + unsigned exp : _FP_EXPBITS_Q; + unsigned sign : 1; # endif /* not bigendian */ - } bits __attribute__((packed)); + } bits __attribute__((packed)); }; @@ -98,61 +98,79 @@ union _FP_UNION_Q # define FP_UNPACK_RAW_Q(X,val) _FP_UNPACK_RAW_4(Q,X,val) # define FP_UNPACK_RAW_QP(X,val) _FP_UNPACK_RAW_4_P(Q,X,val) # define FP_PACK_RAW_Q(val,X) _FP_PACK_RAW_4(Q,val,X) -# define FP_PACK_RAW_QP(val,X) \ - do { \ - if (!FP_INHIBIT_RESULTS) \ - _FP_PACK_RAW_4_P(Q,val,X); \ - } while (0) - -# define FP_UNPACK_Q(X,val) \ - do { \ - _FP_UNPACK_RAW_4(Q,X,val); \ - _FP_UNPACK_CANONICAL(Q,4,X); \ - } while (0) - -# define FP_UNPACK_QP(X,val) \ - do { \ - _FP_UNPACK_RAW_4_P(Q,X,val); \ - _FP_UNPACK_CANONICAL(Q,4,X); \ - } while (0) - -# define FP_UNPACK_SEMIRAW_Q(X,val) \ - do { \ - _FP_UNPACK_RAW_4(Q,X,val); \ - _FP_UNPACK_SEMIRAW(Q,4,X); \ - } while (0) - -# define FP_UNPACK_SEMIRAW_QP(X,val) \ - do { \ - _FP_UNPACK_RAW_4_P(Q,X,val); \ - _FP_UNPACK_SEMIRAW(Q,4,X); \ - } while (0) - -# define FP_PACK_Q(val,X) \ - do { \ - _FP_PACK_CANONICAL(Q,4,X); \ - _FP_PACK_RAW_4(Q,val,X); \ - } while (0) - -# define FP_PACK_QP(val,X) \ - do { \ - _FP_PACK_CANONICAL(Q,4,X); \ - if (!FP_INHIBIT_RESULTS) \ - _FP_PACK_RAW_4_P(Q,val,X); \ - } while (0) - -# define FP_PACK_SEMIRAW_Q(val,X) \ - do { \ - _FP_PACK_SEMIRAW(Q,4,X); \ - _FP_PACK_RAW_4(Q,val,X); \ - } while (0) - -# define FP_PACK_SEMIRAW_QP(val,X) \ - do { \ - _FP_PACK_SEMIRAW(Q,4,X); \ - if (!FP_INHIBIT_RESULTS) \ - _FP_PACK_RAW_4_P(Q,val,X); \ - } while (0) +# define FP_PACK_RAW_QP(val,X) \ + do \ + { \ + if (!FP_INHIBIT_RESULTS) \ + _FP_PACK_RAW_4_P(Q,val,X); \ + } \ + while (0) + +# define FP_UNPACK_Q(X,val) \ + do \ + { \ + _FP_UNPACK_RAW_4(Q,X,val); \ + _FP_UNPACK_CANONICAL(Q,4,X); \ + } \ + while (0) + +# define FP_UNPACK_QP(X,val) \ + do \ + { \ + _FP_UNPACK_RAW_4_P(Q,X,val); \ + _FP_UNPACK_CANONICAL(Q,4,X); \ + } \ + while (0) + +# define FP_UNPACK_SEMIRAW_Q(X,val) \ + do \ + { \ + _FP_UNPACK_RAW_4(Q,X,val); \ + _FP_UNPACK_SEMIRAW(Q,4,X); \ + } \ + while (0) + +# define FP_UNPACK_SEMIRAW_QP(X,val) \ + do \ + { \ + _FP_UNPACK_RAW_4_P(Q,X,val); \ + _FP_UNPACK_SEMIRAW(Q,4,X); \ + } \ + while (0) + +# define FP_PACK_Q(val,X) \ + do \ + { \ + _FP_PACK_CANONICAL(Q,4,X); \ + _FP_PACK_RAW_4(Q,val,X); \ + } \ + while (0) + +# define FP_PACK_QP(val,X) \ + do \ + { \ + _FP_PACK_CANONICAL(Q,4,X); \ + if (!FP_INHIBIT_RESULTS) \ + _FP_PACK_RAW_4_P(Q,val,X); \ + } \ + while (0) + +# define FP_PACK_SEMIRAW_Q(val,X) \ + do \ + { \ + _FP_PACK_SEMIRAW(Q,4,X); \ + _FP_PACK_RAW_4(Q,val,X); \ + } \ + while (0) + +# define FP_PACK_SEMIRAW_QP(val,X) \ + do \ + { \ + _FP_PACK_SEMIRAW(Q,4,X); \ + if (!FP_INHIBIT_RESULTS) \ + _FP_PACK_RAW_4_P(Q,val,X); \ + } \ + while (0) # define FP_ISSIGNAN_Q(X) _FP_ISSIGNAN(Q,4,X) # define FP_NEG_Q(R,X) _FP_NEG(Q,4,R,X) @@ -180,10 +198,12 @@ union _FP_UNION_Q union _FP_UNION_Q { TFtype flt /* __attribute__((mode(TF))) */ ; - struct _FP_STRUCT_LAYOUT { + struct _FP_STRUCT_LAYOUT + { _FP_W_TYPE a, b; } longs; - struct _FP_STRUCT_LAYOUT { + struct _FP_STRUCT_LAYOUT + { # if __BYTE_ORDER == __BIG_ENDIAN unsigned sign : 1; unsigned exp : _FP_EXPBITS_Q; @@ -202,61 +222,79 @@ union _FP_UNION_Q # define FP_UNPACK_RAW_Q(X,val) _FP_UNPACK_RAW_2(Q,X,val) # define FP_UNPACK_RAW_QP(X,val) _FP_UNPACK_RAW_2_P(Q,X,val) # define FP_PACK_RAW_Q(val,X) _FP_PACK_RAW_2(Q,val,X) -# define FP_PACK_RAW_QP(val,X) \ - do { \ - if (!FP_INHIBIT_RESULTS) \ - _FP_PACK_RAW_2_P(Q,val,X); \ - } while (0) - -# define FP_UNPACK_Q(X,val) \ - do { \ - _FP_UNPACK_RAW_2(Q,X,val); \ - _FP_UNPACK_CANONICAL(Q,2,X); \ - } while (0) - -# define FP_UNPACK_QP(X,val) \ - do { \ - _FP_UNPACK_RAW_2_P(Q,X,val); \ - _FP_UNPACK_CANONICAL(Q,2,X); \ - } while (0) - -# define FP_UNPACK_SEMIRAW_Q(X,val) \ - do { \ - _FP_UNPACK_RAW_2(Q,X,val); \ - _FP_UNPACK_SEMIRAW(Q,2,X); \ - } while (0) - -# define FP_UNPACK_SEMIRAW_QP(X,val) \ - do { \ - _FP_UNPACK_RAW_2_P(Q,X,val); \ - _FP_UNPACK_SEMIRAW(Q,2,X); \ - } while (0) - -# define FP_PACK_Q(val,X) \ - do { \ - _FP_PACK_CANONICAL(Q,2,X); \ - _FP_PACK_RAW_2(Q,val,X); \ - } while (0) - -# define FP_PACK_QP(val,X) \ - do { \ - _FP_PACK_CANONICAL(Q,2,X); \ - if (!FP_INHIBIT_RESULTS) \ - _FP_PACK_RAW_2_P(Q,val,X); \ - } while (0) - -# define FP_PACK_SEMIRAW_Q(val,X) \ - do { \ - _FP_PACK_SEMIRAW(Q,2,X); \ - _FP_PACK_RAW_2(Q,val,X); \ - } while (0) - -# define FP_PACK_SEMIRAW_QP(val,X) \ - do { \ - _FP_PACK_SEMIRAW(Q,2,X); \ - if (!FP_INHIBIT_RESULTS) \ - _FP_PACK_RAW_2_P(Q,val,X); \ - } while (0) +# define FP_PACK_RAW_QP(val,X) \ + do \ + { \ + if (!FP_INHIBIT_RESULTS) \ + _FP_PACK_RAW_2_P(Q,val,X); \ + } \ + while (0) + +# define FP_UNPACK_Q(X,val) \ + do \ + { \ + _FP_UNPACK_RAW_2(Q,X,val); \ + _FP_UNPACK_CANONICAL(Q,2,X); \ + } \ + while (0) + +# define FP_UNPACK_QP(X,val) \ + do \ + { \ + _FP_UNPACK_RAW_2_P(Q,X,val); \ + _FP_UNPACK_CANONICAL(Q,2,X); \ + } \ + while (0) + +# define FP_UNPACK_SEMIRAW_Q(X,val) \ + do \ + { \ + _FP_UNPACK_RAW_2(Q,X,val); \ + _FP_UNPACK_SEMIRAW(Q,2,X); \ + } \ + while (0) + +# define FP_UNPACK_SEMIRAW_QP(X,val) \ + do \ + { \ + _FP_UNPACK_RAW_2_P(Q,X,val); \ + _FP_UNPACK_SEMIRAW(Q,2,X); \ + } \ + while (0) + +# define FP_PACK_Q(val,X) \ + do \ + { \ + _FP_PACK_CANONICAL(Q,2,X); \ + _FP_PACK_RAW_2(Q,val,X); \ + } \ + while (0) + +# define FP_PACK_QP(val,X) \ + do \ + { \ + _FP_PACK_CANONICAL(Q,2,X); \ + if (!FP_INHIBIT_RESULTS) \ + _FP_PACK_RAW_2_P(Q,val,X); \ + } \ + while (0) + +# define FP_PACK_SEMIRAW_Q(val,X) \ + do \ + { \ + _FP_PACK_SEMIRAW(Q,2,X); \ + _FP_PACK_RAW_2(Q,val,X); \ + } \ + while (0) + +# define FP_PACK_SEMIRAW_QP(val,X) \ + do \ + { \ + _FP_PACK_SEMIRAW(Q,2,X); \ + if (!FP_INHIBIT_RESULTS) \ + _FP_PACK_RAW_2_P(Q,val,X); \ + } \ + while (0) # define FP_ISSIGNAN_Q(X) _FP_ISSIGNAN(Q,2,X) # define FP_NEG_Q(R,X) _FP_NEG(Q,2,R,X) diff --git a/soft-fp/single.h b/soft-fp/single.h index 9c52a40..2d1b84b 100644 --- a/soft-fp/single.h +++ b/soft-fp/single.h @@ -68,7 +68,8 @@ typedef float SFtype __attribute__((mode(SF))); union _FP_UNION_S { SFtype flt; - struct _FP_STRUCT_LAYOUT { + struct _FP_STRUCT_LAYOUT + { #if __BYTE_ORDER == __BIG_ENDIAN unsigned sign : 1; unsigned exp : _FP_EXPBITS_S; @@ -85,61 +86,79 @@ union _FP_UNION_S #define FP_UNPACK_RAW_S(X,val) _FP_UNPACK_RAW_1(S,X,val) #define FP_UNPACK_RAW_SP(X,val) _FP_UNPACK_RAW_1_P(S,X,val) #define FP_PACK_RAW_S(val,X) _FP_PACK_RAW_1(S,val,X) -#define FP_PACK_RAW_SP(val,X) \ - do { \ - if (!FP_INHIBIT_RESULTS) \ - _FP_PACK_RAW_1_P(S,val,X); \ - } while (0) - -#define FP_UNPACK_S(X,val) \ - do { \ - _FP_UNPACK_RAW_1(S,X,val); \ - _FP_UNPACK_CANONICAL(S,1,X); \ - } while (0) - -#define FP_UNPACK_SP(X,val) \ - do { \ - _FP_UNPACK_RAW_1_P(S,X,val); \ - _FP_UNPACK_CANONICAL(S,1,X); \ - } while (0) - -#define FP_UNPACK_SEMIRAW_S(X,val) \ - do { \ - _FP_UNPACK_RAW_1(S,X,val); \ - _FP_UNPACK_SEMIRAW(S,1,X); \ - } while (0) - -#define FP_UNPACK_SEMIRAW_SP(X,val) \ - do { \ - _FP_UNPACK_RAW_1_P(S,X,val); \ - _FP_UNPACK_SEMIRAW(S,1,X); \ - } while (0) - -#define FP_PACK_S(val,X) \ - do { \ - _FP_PACK_CANONICAL(S,1,X); \ - _FP_PACK_RAW_1(S,val,X); \ - } while (0) - -#define FP_PACK_SP(val,X) \ - do { \ - _FP_PACK_CANONICAL(S,1,X); \ - if (!FP_INHIBIT_RESULTS) \ - _FP_PACK_RAW_1_P(S,val,X); \ - } while (0) - -#define FP_PACK_SEMIRAW_S(val,X) \ - do { \ - _FP_PACK_SEMIRAW(S,1,X); \ - _FP_PACK_RAW_1(S,val,X); \ - } while (0) - -#define FP_PACK_SEMIRAW_SP(val,X) \ - do { \ - _FP_PACK_SEMIRAW(S,1,X); \ - if (!FP_INHIBIT_RESULTS) \ - _FP_PACK_RAW_1_P(S,val,X); \ - } while (0) +#define FP_PACK_RAW_SP(val,X) \ + do \ + { \ + if (!FP_INHIBIT_RESULTS) \ + _FP_PACK_RAW_1_P(S,val,X); \ + } \ + while (0) + +#define FP_UNPACK_S(X,val) \ + do \ + { \ + _FP_UNPACK_RAW_1(S,X,val); \ + _FP_UNPACK_CANONICAL(S,1,X); \ + } \ + while (0) + +#define FP_UNPACK_SP(X,val) \ + do \ + { \ + _FP_UNPACK_RAW_1_P(S,X,val); \ + _FP_UNPACK_CANONICAL(S,1,X); \ + } \ + while (0) + +#define FP_UNPACK_SEMIRAW_S(X,val) \ + do \ + { \ + _FP_UNPACK_RAW_1(S,X,val); \ + _FP_UNPACK_SEMIRAW(S,1,X); \ + } \ + while (0) + +#define FP_UNPACK_SEMIRAW_SP(X,val) \ + do \ + { \ + _FP_UNPACK_RAW_1_P(S,X,val); \ + _FP_UNPACK_SEMIRAW(S,1,X); \ + } \ + while (0) + +#define FP_PACK_S(val,X) \ + do \ + { \ + _FP_PACK_CANONICAL(S,1,X); \ + _FP_PACK_RAW_1(S,val,X); \ + } \ + while (0) + +#define FP_PACK_SP(val,X) \ + do \ + { \ + _FP_PACK_CANONICAL(S,1,X); \ + if (!FP_INHIBIT_RESULTS) \ + _FP_PACK_RAW_1_P(S,val,X); \ + } \ + while (0) + +#define FP_PACK_SEMIRAW_S(val,X) \ + do \ + { \ + _FP_PACK_SEMIRAW(S,1,X); \ + _FP_PACK_RAW_1(S,val,X); \ + } \ + while (0) + +#define FP_PACK_SEMIRAW_SP(val,X) \ + do \ + { \ + _FP_PACK_SEMIRAW(S,1,X); \ + if (!FP_INHIBIT_RESULTS) \ + _FP_PACK_RAW_1_P(S,val,X); \ + } \ + while (0) #define FP_ISSIGNAN_S(X) _FP_ISSIGNAN(S,1,X) #define FP_NEG_S(R,X) _FP_NEG(S,1,R,X) diff --git a/soft-fp/soft-fp.h b/soft-fp/soft-fp.h index 1b7b3a7..b3f4c30 100644 --- a/soft-fp/soft-fp.h +++ b/soft-fp/soft-fp.h @@ -166,48 +166,56 @@ #endif -#define _FP_ROUND_NEAREST(wc, X) \ -do { \ - if ((_FP_FRAC_LOW_##wc(X) & 15) != _FP_WORK_ROUND) \ - _FP_FRAC_ADDI_##wc(X, _FP_WORK_ROUND); \ -} while (0) +#define _FP_ROUND_NEAREST(wc, X) \ + do \ + { \ + if ((_FP_FRAC_LOW_##wc(X) & 15) != _FP_WORK_ROUND) \ + _FP_FRAC_ADDI_##wc(X, _FP_WORK_ROUND); \ + } \ + while (0) #define _FP_ROUND_ZERO(wc, X) (void)0 -#define _FP_ROUND_PINF(wc, X) \ -do { \ - if (!X##_s && (_FP_FRAC_LOW_##wc(X) & 7)) \ - _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB); \ -} while (0) - -#define _FP_ROUND_MINF(wc, X) \ -do { \ - if (X##_s && (_FP_FRAC_LOW_##wc(X) & 7)) \ - _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB); \ -} while (0) +#define _FP_ROUND_PINF(wc, X) \ + do \ + { \ + if (!X##_s && (_FP_FRAC_LOW_##wc(X) & 7)) \ + _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB); \ + } \ + while (0) + +#define _FP_ROUND_MINF(wc, X) \ + do \ + { \ + if (X##_s && (_FP_FRAC_LOW_##wc(X) & 7)) \ + _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB); \ + } \ + while (0) #define _FP_ROUND(wc, X) \ -do { \ - if (_FP_FRAC_LOW_##wc(X) & 7) \ - { \ - FP_SET_EXCEPTION(FP_EX_INEXACT); \ - switch (FP_ROUNDMODE) \ - { \ - case FP_RND_NEAREST: \ - _FP_ROUND_NEAREST(wc,X); \ - break; \ - case FP_RND_ZERO: \ - _FP_ROUND_ZERO(wc,X); \ - break; \ - case FP_RND_PINF: \ - _FP_ROUND_PINF(wc,X); \ - break; \ - case FP_RND_MINF: \ - _FP_ROUND_MINF(wc,X); \ - break; \ - } \ - } \ -} while (0) + do \ + { \ + if (_FP_FRAC_LOW_##wc(X) & 7) \ + { \ + FP_SET_EXCEPTION(FP_EX_INEXACT); \ + switch (FP_ROUNDMODE) \ + { \ + case FP_RND_NEAREST: \ + _FP_ROUND_NEAREST(wc,X); \ + break; \ + case FP_RND_ZERO: \ + _FP_ROUND_ZERO(wc,X); \ + break; \ + case FP_RND_PINF: \ + _FP_ROUND_PINF(wc,X); \ + break; \ + case FP_RND_MINF: \ + _FP_ROUND_MINF(wc,X); \ + break; \ + } \ + } \ + } \ + while (0) #define FP_CLS_NORMAL 0 #define FP_CLS_ZERO 1 diff --git a/soft-fp/sqrtdf2.c b/soft-fp/sqrtdf2.c index eaa510d..a5ee299 100644 --- a/soft-fp/sqrtdf2.c +++ b/soft-fp/sqrtdf2.c @@ -31,10 +31,12 @@ #include "soft-fp.h" #include "double.h" -DFtype __sqrtdf2(DFtype a) +DFtype +__sqrtdf2(DFtype a) { FP_DECL_EX; - FP_DECL_D(A); FP_DECL_D(R); + FP_DECL_D(A); + FP_DECL_D(R); DFtype r; FP_INIT_ROUNDMODE; diff --git a/soft-fp/sqrtsf2.c b/soft-fp/sqrtsf2.c index eb6c4c8..30e2672 100644 --- a/soft-fp/sqrtsf2.c +++ b/soft-fp/sqrtsf2.c @@ -31,10 +31,12 @@ #include "soft-fp.h" #include "single.h" -SFtype __sqrtsf2(SFtype a) +SFtype +__sqrtsf2(SFtype a) { FP_DECL_EX; - FP_DECL_S(A); FP_DECL_S(R); + FP_DECL_S(A); + FP_DECL_S(R); SFtype r; FP_INIT_ROUNDMODE; diff --git a/soft-fp/sqrttf2.c b/soft-fp/sqrttf2.c index 40b3583..0e43d3d 100644 --- a/soft-fp/sqrttf2.c +++ b/soft-fp/sqrttf2.c @@ -31,10 +31,12 @@ #include "soft-fp.h" #include "quad.h" -TFtype __sqrttf2(TFtype a) +TFtype +__sqrttf2(TFtype a) { FP_DECL_EX; - FP_DECL_Q(A); FP_DECL_Q(R); + FP_DECL_Q(A); + FP_DECL_Q(R); TFtype r; FP_INIT_ROUNDMODE; diff --git a/soft-fp/subdf3.c b/soft-fp/subdf3.c index 032ac0f..8898f9f 100644 --- a/soft-fp/subdf3.c +++ b/soft-fp/subdf3.c @@ -31,10 +31,13 @@ #include "soft-fp.h" #include "double.h" -DFtype __subdf3(DFtype a, DFtype b) +DFtype +__subdf3(DFtype a, DFtype b) { FP_DECL_EX; - FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R); + FP_DECL_D(A); + FP_DECL_D(B); + FP_DECL_D(R); DFtype r; FP_INIT_ROUNDMODE; diff --git a/soft-fp/subsf3.c b/soft-fp/subsf3.c index c9f56c7..05c933b 100644 --- a/soft-fp/subsf3.c +++ b/soft-fp/subsf3.c @@ -31,10 +31,13 @@ #include "soft-fp.h" #include "single.h" -SFtype __subsf3(SFtype a, SFtype b) +SFtype +__subsf3(SFtype a, SFtype b) { FP_DECL_EX; - FP_DECL_S(A); FP_DECL_S(B); FP_DECL_S(R); + FP_DECL_S(A); + FP_DECL_S(B); + FP_DECL_S(R); SFtype r; FP_INIT_ROUNDMODE; diff --git a/soft-fp/subtf3.c b/soft-fp/subtf3.c index a111d57..68d41e6 100644 --- a/soft-fp/subtf3.c +++ b/soft-fp/subtf3.c @@ -31,10 +31,13 @@ #include "soft-fp.h" #include "quad.h" -TFtype __subtf3(TFtype a, TFtype b) +TFtype +__subtf3(TFtype a, TFtype b) { FP_DECL_EX; - FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(R); + FP_DECL_Q(A); + FP_DECL_Q(B); + FP_DECL_Q(R); TFtype r; FP_INIT_ROUNDMODE; diff --git a/soft-fp/truncdfsf2.c b/soft-fp/truncdfsf2.c index e9a7223..f8b7d17 100644 --- a/soft-fp/truncdfsf2.c +++ b/soft-fp/truncdfsf2.c @@ -32,7 +32,8 @@ #include "single.h" #include "double.h" -SFtype __truncdfsf2(DFtype a) +SFtype +__truncdfsf2(DFtype a) { FP_DECL_EX; FP_DECL_D(A); diff --git a/soft-fp/trunctfdf2.c b/soft-fp/trunctfdf2.c index 35c6496..2f61705 100644 --- a/soft-fp/trunctfdf2.c +++ b/soft-fp/trunctfdf2.c @@ -32,7 +32,8 @@ #include "double.h" #include "quad.h" -DFtype __trunctfdf2(TFtype a) +DFtype +__trunctfdf2(TFtype a) { FP_DECL_EX; FP_DECL_Q(A); diff --git a/soft-fp/trunctfsf2.c b/soft-fp/trunctfsf2.c index 751c7c8..aa4e7b3 100644 --- a/soft-fp/trunctfsf2.c +++ b/soft-fp/trunctfsf2.c @@ -32,7 +32,8 @@ #include "single.h" #include "quad.h" -SFtype __trunctfsf2(TFtype a) +SFtype +__trunctfsf2(TFtype a) { FP_DECL_EX; FP_DECL_Q(A); diff --git a/soft-fp/trunctfxf2.c b/soft-fp/trunctfxf2.c index 54bd673..37b73b2 100644 --- a/soft-fp/trunctfxf2.c +++ b/soft-fp/trunctfxf2.c @@ -31,7 +31,8 @@ #include "extended.h" #include "quad.h" -XFtype __trunctfxf2(TFtype a) +XFtype +__trunctfxf2(TFtype a) { FP_DECL_EX; FP_DECL_Q(A); diff --git a/soft-fp/unorddf2.c b/soft-fp/unorddf2.c index bc4efa3..9c8e2f9 100644 --- a/soft-fp/unorddf2.c +++ b/soft-fp/unorddf2.c @@ -30,10 +30,12 @@ #include "soft-fp.h" #include "double.h" -CMPtype __unorddf2(DFtype a, DFtype b) +CMPtype +__unorddf2(DFtype a, DFtype b) { FP_DECL_EX; - FP_DECL_D(A); FP_DECL_D(B); + FP_DECL_D(A); + FP_DECL_D(B); CMPtype r; FP_INIT_EXCEPTIONS; diff --git a/soft-fp/unordsf2.c b/soft-fp/unordsf2.c index 217975f..fd47599 100644 --- a/soft-fp/unordsf2.c +++ b/soft-fp/unordsf2.c @@ -30,7 +30,8 @@ #include "soft-fp.h" #include "single.h" -CMPtype __unordsf2(SFtype a, SFtype b) +CMPtype +__unordsf2(SFtype a, SFtype b) { FP_DECL_EX; FP_DECL_S(A); diff --git a/soft-fp/unordtf2.c b/soft-fp/unordtf2.c index 3650cf4..443cd79 100644 --- a/soft-fp/unordtf2.c +++ b/soft-fp/unordtf2.c @@ -30,7 +30,8 @@ #include "soft-fp.h" #include "quad.h" -CMPtype __unordtf2(TFtype a, TFtype b) +CMPtype +__unordtf2(TFtype a, TFtype b) { FP_DECL_EX; FP_DECL_Q(A); |