x86: SYSENTER/SYSEXIT are unavailable in 64-bit mode on AMD
[deliverable/binutils-gdb.git] / libdecnumber / decCommon.c
index fa16e792e668058f37129685c06f72502f3426af..8fc1798e4272516019e4584c5a60dc67f6fc7e91 100644 (file)
@@ -1,32 +1,27 @@
 /* Common code for fixed-size types in the decNumber C Library.
 /* Common code for fixed-size types in the decNumber C Library.
-   Copyright (C) 2007 Free Software Foundation, Inc.
+   Copyright (C) 2007-2018 Free Software Foundation, Inc.
    Contributed by IBM Corporation.  Author Mike Cowlishaw.
 
    This file is part of GCC.
 
    GCC is free software; you can redistribute it and/or modify it under
    the terms of the GNU General Public License as published by the Free
    Contributed by IBM Corporation.  Author Mike Cowlishaw.
 
    This file is part of GCC.
 
    GCC is free software; you can redistribute it and/or modify it under
    the terms of the GNU General Public License as published by the Free
-   Software Foundation; either version 2, or (at your option) any later
+   Software Foundation; either version 3, or (at your option) any later
    version.
 
    version.
 
-   In addition to the permissions in the GNU General Public License,
-   the Free Software Foundation gives you unlimited permission to link
-   the compiled version of this file into combinations with other
-   programs, and to distribute those combinations without any
-   restriction coming from the use of this file.  (The General Public
-   License restrictions do apply in other respects; for example, they
-   cover modification of the file, and distribution when not linked
-   into a combine executable.)
-
    GCC is distributed in the hope that it will be useful, but WITHOUT ANY
    WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    for more details.
 
    GCC is distributed in the hope that it will be useful, but WITHOUT ANY
    WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    for more details.
 
-   You should have received a copy of the GNU General Public License
-   along with GCC; see the file COPYING.  If not, write to the Free
-   Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.  */
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
 
 /* ------------------------------------------------------------------ */
 /* decCommon.c -- common code for all three fixed-size types         */
 
 /* ------------------------------------------------------------------ */
 /* decCommon.c -- common code for all three fixed-size types         */
@@ -104,15 +99,15 @@ static decFloat * decFinalize(decFloat *, bcdnum *, decContext *);
 static Flag decBiStr(const char *, const char *, const char *);
 
 /* Macros and private tables; those which are not format-dependent    */
 static Flag decBiStr(const char *, const char *, const char *);
 
 /* Macros and private tables; those which are not format-dependent    */
-/* are only included if decQuad is being built.                              */
+/* are only included if decQuad is being built.                      */
 
 /* ------------------------------------------------------------------ */
 /* Combination field lookup tables (uInts to save measurable work)    */
 /*                                                                   */
 
 /* ------------------------------------------------------------------ */
 /* Combination field lookup tables (uInts to save measurable work)    */
 /*                                                                   */
-/*   DECCOMBEXP         - 2 most-significant-bits of exponent (00, 01, or    */
+/*   DECCOMBEXP  - 2 most-significant-bits of exponent (00, 01, or    */
 /*                10), shifted left for format, or DECFLOAT_Inf/NaN  */
 /*   DECCOMBWEXP - The same, for the next-wider format (unless QUAD)  */
 /*                10), shifted left for format, or DECFLOAT_Inf/NaN  */
 /*   DECCOMBWEXP - The same, for the next-wider format (unless QUAD)  */
-/*   DECCOMBMSD         - 4-bit most-significant-digit                       */
+/*   DECCOMBMSD  - 4-bit most-significant-digit                      */
 /*                [0 if the index is a special (Infinity or NaN)]    */
 /*   DECCOMBFROM - 5-bit combination field from EXP top bits and MSD  */
 /*                (placed in uInt so no shift is needed)             */
 /*                [0 if the index is a special (Infinity or NaN)]    */
 /*   DECCOMBFROM - 5-bit combination field from EXP top bits and MSD  */
 /*                (placed in uInt so no shift is needed)             */
@@ -123,7 +118,7 @@ static Flag decBiStr(const char *, const char *, const char *);
 /* DECCOMBFROM is indexed by expTopTwoBits*16 + msd                  */
 /*                                                                   */
 /* DECCOMBMSD and DECCOMBFROM are not format-dependent and so are     */
 /* DECCOMBFROM is indexed by expTopTwoBits*16 + msd                  */
 /*                                                                   */
 /* DECCOMBMSD and DECCOMBFROM are not format-dependent and so are     */
-/* only included once, when QUAD is being built                              */
+/* only included once, when QUAD is being built                      */
 /* ------------------------------------------------------------------ */
 static const uInt DECCOMBEXP[64]={
   0, 0, 0, 0, 0, 0, 0, 0,
 /* ------------------------------------------------------------------ */
 static const uInt DECCOMBEXP[64]={
   0, 0, 0, 0, 0, 0, 0, 0,
@@ -161,7 +156,7 @@ static const uInt DECCOMBWEXP[64]={
 #if QUAD
 const uInt DECCOMBMSD[64]={
   0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7,
 #if QUAD
 const uInt DECCOMBMSD[64]={
   0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7,
-  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 9, 8, 9, 0, 1,
+  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 9, 8, 9, 0, 0,
   0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7,
   0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 9, 8, 9, 0, 0};
 
   0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7,
   0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 9, 8, 9, 0, 0};
 
@@ -223,7 +218,7 @@ static Flag decBiStr(const char *targ, const char *str1, const char *str2) {
 /*  returns df                                                       */
 /*                                                                   */
 /* The num descriptor may point to a bcd8 string of any length; this  */
 /*  returns df                                                       */
 /*                                                                   */
 /* The num descriptor may point to a bcd8 string of any length; this  */
-/* string may have leading insignificant zeros.         If it has more than  */
+/* string may have leading insignificant zeros.  If it has more than  */
 /* DECPMAX digits then the final digit can be a round-for-reround     */
 /* digit (i.e., it may include a sticky bit residue).                */
 /*                                                                   */
 /* DECPMAX digits then the final digit can be a round-for-reround     */
 /* digit (i.e., it may include a sticky bit residue).                */
 /*                                                                   */
@@ -248,8 +243,9 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
                              decContext *set) {
   uByte *ub;                 /* work */
   uInt  dpd;                 /* .. */
                              decContext *set) {
   uByte *ub;                 /* work */
   uInt  dpd;                 /* .. */
-  uByte *umsd=num->msd;              /* local copy */
-  uByte *ulsd=num->lsd;              /* .. */
+  uInt  uiwork;              /* for macros */
+  uByte *umsd=num->msd;       /* local copy */
+  uByte *ulsd=num->lsd;       /* .. */
   uInt  encode;              /* encoding accumulator */
   Int   length;              /* coefficient length */
 
   uInt  encode;              /* encoding accumulator */
   Int   length;              /* coefficient length */
 
@@ -275,11 +271,11 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
   length=(uInt)(ulsd-umsd+1);               /* coefficient length */
 
   if (!NUMISSPECIAL(num)) {
   length=(uInt)(ulsd-umsd+1);               /* coefficient length */
 
   if (!NUMISSPECIAL(num)) {
-    Int          drop;                              /* digits to be dropped */
+    Int   drop;                             /* digits to be dropped */
     /* skip leading insignificant zeros to calculate an exact length */
     /* [this is quite expensive] */
     if (*umsd==0) {
     /* skip leading insignificant zeros to calculate an exact length */
     /* [this is quite expensive] */
     if (*umsd==0) {
-      for (; UINTAT(umsd)==0 && umsd+3<ulsd;) umsd+=4;
+      for (; umsd+3<ulsd && UBTOUI(umsd)==0;) umsd+=4;
       for (; *umsd==0 && umsd<ulsd;) umsd++;
       length=ulsd-umsd+1;                   /* recalculate */
       }
       for (; *umsd==0 && umsd<ulsd;) umsd++;
       length=ulsd-umsd+1;                   /* recalculate */
       }
@@ -305,12 +301,12 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
        roundat=umsd+length-drop;
        reround=*roundat;
        for (ub=roundat+1; ub<=ulsd; ub++) {
        roundat=umsd+length-drop;
        reround=*roundat;
        for (ub=roundat+1; ub<=ulsd; ub++) {
-         if (*ub!=0) {                      /* non-zero to be discarded */
+         if (*ub!=0) {                      /* non-zero to be discarded */
            reround=DECSTICKYTAB[reround];   /* apply sticky bit */
            break;                           /* [remainder don't-care] */
            }
          } /* check stickies */
            reround=DECSTICKYTAB[reround];   /* apply sticky bit */
            break;                           /* [remainder don't-care] */
            }
          } /* check stickies */
-       ulsd=roundat-1;                      /* new LSD */
+       ulsd=roundat-1;                      /* new LSD */
        }
        else {                               /* edge case */
        if (drop==length) {
        }
        else {                               /* edge case */
        if (drop==length) {
@@ -322,7 +318,7 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
          reround=0;
          }
        for (ub=roundat+1; ub<=ulsd; ub++) {
          reround=0;
          }
        for (ub=roundat+1; ub<=ulsd; ub++) {
-         if (*ub!=0) {                      /* non-zero to be discarded */
+         if (*ub!=0) {                      /* non-zero to be discarded */
            reround=DECSTICKYTAB[reround];   /* apply sticky bit */
            break;                           /* [remainder don't-care] */
            }
            reround=DECSTICKYTAB[reround];   /* apply sticky bit */
            break;                           /* [remainder don't-care] */
            }
@@ -331,7 +327,7 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
        ulsd=umsd;                           /* .. */
        }
 
        ulsd=umsd;                           /* .. */
        }
 
-      if (reround!=0) {                             /* discarding non-zero */
+      if (reround!=0) {                     /* discarding non-zero */
        uInt bump=0;
        set->status|=DEC_Inexact;
        /* if adjusted exponent [exp+digits-1] is < EMIN then num is */
        uInt bump=0;
        set->status|=DEC_Inexact;
        /* if adjusted exponent [exp+digits-1] is < EMIN then num is */
@@ -342,7 +338,7 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
        /* next decide whether increment of the coefficient is needed */
        if (set->round==DEC_ROUND_HALF_EVEN) {    /* fastpath slowest case */
          if (reround>5) bump=1;                  /* >0.5 goes up */
        /* next decide whether increment of the coefficient is needed */
        if (set->round==DEC_ROUND_HALF_EVEN) {    /* fastpath slowest case */
          if (reround>5) bump=1;                  /* >0.5 goes up */
-          else if (reround==5)                   /* exactly 0.5000 .. */
+          else if (reround==5)                   /* exactly 0.5000 .. */
            bump=*ulsd & 0x01;                    /* .. up iff [new] lsd is odd */
          } /* r-h-e */
         else switch (set->round) {
            bump=*ulsd & 0x01;                    /* .. up iff [new] lsd is odd */
          } /* r-h-e */
         else switch (set->round) {
@@ -382,13 +378,15 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
            #endif
            break;}
          } /* switch (not r-h-e) */
            #endif
            break;}
          } /* switch (not r-h-e) */
-       /* printf("ReRound: %ld  bump: %ld\n", (LI)reround, (LI)bump); */
+       /* printf("ReRound: %ld  bump: %ld\n", (LI)reround, (LI)bump); */
 
        if (bump!=0) {                       /* need increment */
          /* increment the coefficient; this might end up with 1000... */
          /* (after the all nines case) */
          ub=ulsd;
 
        if (bump!=0) {                       /* need increment */
          /* increment the coefficient; this might end up with 1000... */
          /* (after the all nines case) */
          ub=ulsd;
-         for(; ub-3>=umsd && UINTAT(ub-3)==0x09090909; ub-=4) UINTAT(ub-3)=0;
+         for(; ub-3>=umsd && UBTOUI(ub-3)==0x09090909; ub-=4)  {
+           UBFROMUI(ub-3, 0);               /* to 00000000 */
+           }
          /* [note ub could now be to left of msd, and it is not safe */
          /* to write to the the left of the msd] */
          /* now at most 3 digits left to non-9 (usually just the one) */
          /* [note ub could now be to left of msd, and it is not safe */
          /* to write to the the left of the msd] */
          /* now at most 3 digits left to non-9 (usually just the one) */
@@ -436,7 +434,7 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
        else if ((num->exponent+length-1)>DECEMAX) { /* > Nmax */
        /* Overflow -- these could go straight to encoding, here, but */
        /* instead num is adjusted to keep the code cleaner */
        else if ((num->exponent+length-1)>DECEMAX) { /* > Nmax */
        /* Overflow -- these could go straight to encoding, here, but */
        /* instead num is adjusted to keep the code cleaner */
-       Flag needmax=0;                 /* 1 for finite result */
+       Flag needmax=0;                 /* 1 for finite result */
        set->status|=(DEC_Overflow | DEC_Inexact);
        switch (set->round) {
          case DEC_ROUND_DOWN: {
        set->status|=(DEC_Overflow | DEC_Inexact);
        switch (set->round) {
          case DEC_ROUND_DOWN: {
@@ -453,12 +451,12 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
            break;} /* r-f */
          default: break;               /* Infinity in all other cases */
          }
            break;} /* r-f */
          default: break;               /* Infinity in all other cases */
          }
-       if (!needmax) {                 /* easy .. set Infinity */
+       if (!needmax) {                 /* easy .. set Infinity */
          num->exponent=DECFLOAT_Inf;
          *umsd=0;                      /* be clean: coefficient to 0 */
          ulsd=umsd;                    /* .. */
          }
          num->exponent=DECFLOAT_Inf;
          *umsd=0;                      /* be clean: coefficient to 0 */
          ulsd=umsd;                    /* .. */
          }
-        else {                         /* return Nmax */
+        else {                         /* return Nmax */
          umsd=allnines;                /* use constant array */
          ulsd=allnines+DECPMAX-1;
          num->exponent=DECEMAX-(DECPMAX-1);
          umsd=allnines;                /* use constant array */
          ulsd=allnines+DECPMAX-1;
          num->exponent=DECEMAX-(DECPMAX-1);
@@ -475,8 +473,8 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
          uByte *t=buffer;              /* safe target */
          uByte *tlsd=buffer+(ulsd-umsd)+shift; /* target LSD */
          /* printf("folddown shift=%ld\n", (LI)shift); */
          uByte *t=buffer;              /* safe target */
          uByte *tlsd=buffer+(ulsd-umsd)+shift; /* target LSD */
          /* printf("folddown shift=%ld\n", (LI)shift); */
-         for (; s<=ulsd; s+=4, t+=4) UINTAT(t)=UINTAT(s);
-         for (t=tlsd-shift+1; t<=tlsd; t+=4) UINTAT(t)=0;  /* pad */
+         for (; s<=ulsd; s+=4, t+=4) UBFROMUI(t, UBTOUI(s));
+         for (t=tlsd-shift+1; t<=tlsd; t+=4) UBFROMUI(t, 0);  /* pad 0s */
          num->exponent-=shift;
          umsd=buffer;
          ulsd=tlsd;
          num->exponent-=shift;
          umsd=buffer;
          ulsd=tlsd;
@@ -492,23 +490,23 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
   /*------------------------------------------------------------------*/
   /* Following code does not alter coefficient (could be allnines array) */
 
   /*------------------------------------------------------------------*/
   /* Following code does not alter coefficient (could be allnines array) */
 
+  /* fast path possible when DECPMAX digits */
   if (length==DECPMAX) {
     return decFloatFromBCD(df, num->exponent, umsd, num->sign);
   if (length==DECPMAX) {
     return decFloatFromBCD(df, num->exponent, umsd, num->sign);
-    }
+    } /* full-length */
 
 
-  /* Here when length is short */
+  /* slower path when not a full-length number; must care about length */
+  /* [coefficient length here will be < DECPMAX] */
   if (!NUMISSPECIAL(num)) {            /* is still finite */
     /* encode the combination field and exponent continuation */
     uInt uexp=(uInt)(num->exponent+DECBIAS); /* biased exponent */
     uInt code=(uexp>>DECECONL)<<4;     /* top two bits of exp */
   if (!NUMISSPECIAL(num)) {            /* is still finite */
     /* encode the combination field and exponent continuation */
     uInt uexp=(uInt)(num->exponent+DECBIAS); /* biased exponent */
     uInt code=(uexp>>DECECONL)<<4;     /* top two bits of exp */
-    /* [msd=0] */
+    /* [msd==0] */
     /* look up the combination field and make high word */
     encode=DECCOMBFROM[code];          /* indexed by (0-2)*16+msd */
     encode|=(uexp<<(32-6-DECECONL)) & 0x03ffffff; /* exponent continuation */
     }
    else encode=num->exponent;          /* special [already in word] */
     /* look up the combination field and make high word */
     encode=DECCOMBFROM[code];          /* indexed by (0-2)*16+msd */
     encode|=(uexp<<(32-6-DECECONL)) & 0x03ffffff; /* exponent continuation */
     }
    else encode=num->exponent;          /* special [already in word] */
-  /* [coefficient length here will be < DECPMAX] */
-
   encode|=num->sign;                   /* add sign */
 
   /* private macro to extract a declet, n (where 0<=n<DECLETS and 0 */
   encode|=num->sign;                   /* add sign */
 
   /* private macro to extract a declet, n (where 0<=n<DECLETS and 0 */
@@ -519,7 +517,7 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
   /* working pointer, uInt *ub. */
   /* As not full-length then chances are there are many leading zeros */
   /* [and there may be a partial triad] */
   /* working pointer, uInt *ub. */
   /* As not full-length then chances are there are many leading zeros */
   /* [and there may be a partial triad] */
-  #define getDPD(dpd, n) ub=ulsd-(3*(n))-2;                          \
+  #define getDPDt(dpd, n) ub=ulsd-(3*(n))-2;                         \
     if (ub<umsd-2) dpd=0;                                            \
      else if (ub>=umsd) dpd=BCD2DPD[(*ub*256)+(*(ub+1)*16)+*(ub+2)];  \
      else {dpd=*(ub+2); if (ub+1==umsd) dpd+=*(ub+1)*16; dpd=BCD2DPD[dpd];}
     if (ub<umsd-2) dpd=0;                                            \
      else if (ub>=umsd) dpd=BCD2DPD[(*ub*256)+(*(ub+1)*16)+*(ub+2)];  \
      else {dpd=*(ub+2); if (ub+1==umsd) dpd+=*(ub+1)*16; dpd=BCD2DPD[dpd];}
@@ -528,48 +526,48 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
   /* according to endianness; in all cases complete the sign word */
   /* first */
   #if DECPMAX==7
   /* according to endianness; in all cases complete the sign word */
   /* first */
   #if DECPMAX==7
-    getDPD(dpd, 1);
+    getDPDt(dpd, 1);
     encode|=dpd<<10;
     encode|=dpd<<10;
-    getDPD(dpd, 0);
+    getDPDt(dpd, 0);
     encode|=dpd;
     DFWORD(df, 0)=encode;     /* just the one word */
 
   #elif DECPMAX==16
     encode|=dpd;
     DFWORD(df, 0)=encode;     /* just the one word */
 
   #elif DECPMAX==16
-    getDPD(dpd, 4); encode|=dpd<<8;
-    getDPD(dpd, 3); encode|=dpd>>2;
+    getDPDt(dpd, 4); encode|=dpd<<8;
+    getDPDt(dpd, 3); encode|=dpd>>2;
     DFWORD(df, 0)=encode;
     encode=dpd<<30;
     DFWORD(df, 0)=encode;
     encode=dpd<<30;
-    getDPD(dpd, 2); encode|=dpd<<20;
-    getDPD(dpd, 1); encode|=dpd<<10;
-    getDPD(dpd, 0); encode|=dpd;
+    getDPDt(dpd, 2); encode|=dpd<<20;
+    getDPDt(dpd, 1); encode|=dpd<<10;
+    getDPDt(dpd, 0); encode|=dpd;
     DFWORD(df, 1)=encode;
 
   #elif DECPMAX==34
     DFWORD(df, 1)=encode;
 
   #elif DECPMAX==34
-    getDPD(dpd,10); encode|=dpd<<4;
-    getDPD(dpd, 9); encode|=dpd>>6;
+    getDPDt(dpd,10); encode|=dpd<<4;
+    getDPDt(dpd, 9); encode|=dpd>>6;
     DFWORD(df, 0)=encode;
 
     encode=dpd<<26;
     DFWORD(df, 0)=encode;
 
     encode=dpd<<26;
-    getDPD(dpd, 8); encode|=dpd<<16;
-    getDPD(dpd, 7); encode|=dpd<<6;
-    getDPD(dpd, 6); encode|=dpd>>4;
+    getDPDt(dpd, 8); encode|=dpd<<16;
+    getDPDt(dpd, 7); encode|=dpd<<6;
+    getDPDt(dpd, 6); encode|=dpd>>4;
     DFWORD(df, 1)=encode;
 
     encode=dpd<<28;
     DFWORD(df, 1)=encode;
 
     encode=dpd<<28;
-    getDPD(dpd, 5); encode|=dpd<<18;
-    getDPD(dpd, 4); encode|=dpd<<8;
-    getDPD(dpd, 3); encode|=dpd>>2;
+    getDPDt(dpd, 5); encode|=dpd<<18;
+    getDPDt(dpd, 4); encode|=dpd<<8;
+    getDPDt(dpd, 3); encode|=dpd>>2;
     DFWORD(df, 2)=encode;
 
     encode=dpd<<30;
     DFWORD(df, 2)=encode;
 
     encode=dpd<<30;
-    getDPD(dpd, 2); encode|=dpd<<20;
-    getDPD(dpd, 1); encode|=dpd<<10;
-    getDPD(dpd, 0); encode|=dpd;
+    getDPDt(dpd, 2); encode|=dpd<<20;
+    getDPDt(dpd, 1); encode|=dpd<<10;
+    getDPDt(dpd, 0); encode|=dpd;
     DFWORD(df, 3)=encode;
   #endif
 
   /* printf("Status: %08lx\n", (LI)set->status); */
     DFWORD(df, 3)=encode;
   #endif
 
   /* printf("Status: %08lx\n", (LI)set->status); */
-  /* decFloatShow(df, "final"); */
+  /* decFloatShow(df, "final2"); */
   return df;
   } /* decFinalize */
 
   return df;
   } /* decFinalize */
 
@@ -579,12 +577,12 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
 /*  df is the target decFloat                                        */
 /*  exp is the in-range unbiased exponent, q, or a special value in   */
 /*    the form returned by decFloatGetExponent                       */
 /*  df is the target decFloat                                        */
 /*  exp is the in-range unbiased exponent, q, or a special value in   */
 /*    the form returned by decFloatGetExponent                       */
-/*  bcdar holds DECPMAX digits to set the coefficient from, one              */
+/*  bcdar holds DECPMAX digits to set the coefficient from, one       */
 /*    digit in each byte (BCD8 encoding); the first (MSD) is ignored  */
 /*    if df is a NaN; all are ignored if df is infinite.             */
 /*    digit in each byte (BCD8 encoding); the first (MSD) is ignored  */
 /*    if df is a NaN; all are ignored if df is infinite.             */
-/*    All bytes must be in 0-9; results undefined otherwise.         */
+/*    All bytes must be in 0-9; results are undefined otherwise.      */
 /*  sig is DECFLOAT_Sign to set the sign bit, 0 otherwise            */
 /*  sig is DECFLOAT_Sign to set the sign bit, 0 otherwise            */
-/*  returns df, which will be canonical                                      */
+/*  returns df, which will be canonical                              */
 /*                                                                   */
 /* No error is possible, and no status will be set.                  */
 /* ------------------------------------------------------------------ */
 /*                                                                   */
 /* No error is possible, and no status will be set.                  */
 /* ------------------------------------------------------------------ */
@@ -609,53 +607,53 @@ decFloat * decFloatFromBCD(decFloat *df, Int exp, const uByte *bcdar,
   /* and put the corresponding DPD code into dpd. */
   /* Use of a working pointer, uInt *ub, is assumed. */
 
   /* and put the corresponding DPD code into dpd. */
   /* Use of a working pointer, uInt *ub, is assumed. */
 
-  #define getDPDf(dpd, n) ub=bcdar+DECPMAX-1-(3*(n))-2;            \
+  #define getDPDb(dpd, n) ub=bcdar+DECPMAX-1-(3*(n))-2;     \
     dpd=BCD2DPD[(*ub*256)+(*(ub+1)*16)+*(ub+2)];
 
   /* place the declets in the encoding words and copy to result (df), */
   /* according to endianness; in all cases complete the sign word */
   /* first */
   #if DECPMAX==7
     dpd=BCD2DPD[(*ub*256)+(*(ub+1)*16)+*(ub+2)];
 
   /* place the declets in the encoding words and copy to result (df), */
   /* according to endianness; in all cases complete the sign word */
   /* first */
   #if DECPMAX==7
-    getDPDf(dpd, 1);
+    getDPDb(dpd, 1);
     encode|=dpd<<10;
     encode|=dpd<<10;
-    getDPDf(dpd, 0);
+    getDPDb(dpd, 0);
     encode|=dpd;
     DFWORD(df, 0)=encode;     /* just the one word */
 
   #elif DECPMAX==16
     encode|=dpd;
     DFWORD(df, 0)=encode;     /* just the one word */
 
   #elif DECPMAX==16
-    getDPDf(dpd, 4); encode|=dpd<<8;
-    getDPDf(dpd, 3); encode|=dpd>>2;
+    getDPDb(dpd, 4); encode|=dpd<<8;
+    getDPDb(dpd, 3); encode|=dpd>>2;
     DFWORD(df, 0)=encode;
     encode=dpd<<30;
     DFWORD(df, 0)=encode;
     encode=dpd<<30;
-    getDPDf(dpd, 2); encode|=dpd<<20;
-    getDPDf(dpd, 1); encode|=dpd<<10;
-    getDPDf(dpd, 0); encode|=dpd;
+    getDPDb(dpd, 2); encode|=dpd<<20;
+    getDPDb(dpd, 1); encode|=dpd<<10;
+    getDPDb(dpd, 0); encode|=dpd;
     DFWORD(df, 1)=encode;
 
   #elif DECPMAX==34
     DFWORD(df, 1)=encode;
 
   #elif DECPMAX==34
-    getDPDf(dpd,10); encode|=dpd<<4;
-    getDPDf(dpd, 9); encode|=dpd>>6;
+    getDPDb(dpd,10); encode|=dpd<<4;
+    getDPDb(dpd, 9); encode|=dpd>>6;
     DFWORD(df, 0)=encode;
 
     encode=dpd<<26;
     DFWORD(df, 0)=encode;
 
     encode=dpd<<26;
-    getDPDf(dpd, 8); encode|=dpd<<16;
-    getDPDf(dpd, 7); encode|=dpd<<6;
-    getDPDf(dpd, 6); encode|=dpd>>4;
+    getDPDb(dpd, 8); encode|=dpd<<16;
+    getDPDb(dpd, 7); encode|=dpd<<6;
+    getDPDb(dpd, 6); encode|=dpd>>4;
     DFWORD(df, 1)=encode;
 
     encode=dpd<<28;
     DFWORD(df, 1)=encode;
 
     encode=dpd<<28;
-    getDPDf(dpd, 5); encode|=dpd<<18;
-    getDPDf(dpd, 4); encode|=dpd<<8;
-    getDPDf(dpd, 3); encode|=dpd>>2;
+    getDPDb(dpd, 5); encode|=dpd<<18;
+    getDPDb(dpd, 4); encode|=dpd<<8;
+    getDPDb(dpd, 3); encode|=dpd>>2;
     DFWORD(df, 2)=encode;
 
     encode=dpd<<30;
     DFWORD(df, 2)=encode;
 
     encode=dpd<<30;
-    getDPDf(dpd, 2); encode|=dpd<<20;
-    getDPDf(dpd, 1); encode|=dpd<<10;
-    getDPDf(dpd, 0); encode|=dpd;
+    getDPDb(dpd, 2); encode|=dpd<<20;
+    getDPDb(dpd, 1); encode|=dpd<<10;
+    getDPDb(dpd, 0); encode|=dpd;
     DFWORD(df, 3)=encode;
   #endif
     DFWORD(df, 3)=encode;
   #endif
-  /* decFloatShow(df, "final"); */
+  /* decFloatShow(df, "fromB"); */
   return df;
   } /* decFloatFromBCD */
 
   return df;
   } /* decFloatFromBCD */
 
@@ -671,7 +669,7 @@ decFloat * decFloatFromBCD(decFloat *df, Int exp, const uByte *bcdar,
 /*    and QUAD the first (pad) nibble is also ignored in all cases.   */
 /*    All coefficient nibbles must be in 0-9 and sign in A-F; results */
 /*    are undefined otherwise.                                       */
 /*    and QUAD the first (pad) nibble is also ignored in all cases.   */
 /*    All coefficient nibbles must be in 0-9 and sign in A-F; results */
 /*    are undefined otherwise.                                       */
-/*  returns df, which will be canonical                                      */
+/*  returns df, which will be canonical                              */
 /*                                                                   */
 /* No error is possible, and no status will be set.                  */
 /* ------------------------------------------------------------------ */
 /*                                                                   */
 /* No error is possible, and no status will be set.                  */
 /* ------------------------------------------------------------------ */
@@ -691,7 +689,7 @@ decFloat * decFloatFromPacked(decFloat *df, Int exp, const uByte *packed) {
     *op++=*ip>>4;
     *op++=(uByte)(*ip&0x0f);           /* [final nibble is sign] */
     }
     *op++=*ip>>4;
     *op++=(uByte)(*ip&0x0f);           /* [final nibble is sign] */
     }
-  op--;                                        /* -> sign byte */
+  op--;                                /* -> sign byte */
   if (*op==DECPMINUS || *op==DECPMINUSALT) sig=DECFLOAT_Sign;
 
   if (EXPISSPECIAL(exp)) {             /* Infinity or NaN */
   if (*op==DECPMINUS || *op==DECPMINUSALT) sig=DECFLOAT_Sign;
 
   if (EXPISSPECIAL(exp)) {             /* Infinity or NaN */
@@ -702,7 +700,71 @@ decFloat * decFloatFromPacked(decFloat *df, Int exp, const uByte *packed) {
   } /* decFloatFromPacked */
 
 /* ------------------------------------------------------------------ */
   } /* decFloatFromPacked */
 
 /* ------------------------------------------------------------------ */
-/* decFloatFromString -- conversion from numeric string                      */
+/* decFloatFromPackedChecked -- set from exponent and packed; checked */
+/*                                                                   */
+/*  df is the target decFloat                                        */
+/*  exp is the in-range unbiased exponent, q, or a special value in   */
+/*    the form returned by decFloatGetExponent                       */
+/*  packed holds DECPMAX packed decimal digits plus a sign nibble     */
+/*    (all 6 codes are OK); the first (MSD) must be 0 if df is a NaN  */
+/*    and all digits must be 0 if df is infinite.  For DOUBLE and     */
+/*    QUAD the first (pad) nibble must be 0.                         */
+/*    All coefficient nibbles must be in 0-9 and sign in A-F.        */
+/*  returns df, which will be canonical or NULL if any of the        */
+/*    requirements are not met (if this case df is unchanged); that   */
+/*    is, the input data must be as returned by decFloatToPacked,     */
+/*    except that all six sign codes are accepted.                   */
+/*                                                                   */
+/* No status will be set.                                            */
+/* ------------------------------------------------------------------ */
+decFloat * decFloatFromPackedChecked(decFloat *df, Int exp,
+                                    const uByte *packed) {
+  uByte bcdar[DECPMAX+2];              /* work [+1 for pad, +1 for sign] */
+  const uByte *ip;                     /* .. */
+  uByte *op;                           /* .. */
+  Int  sig=0;                          /* sign */
+
+  /* expand coefficient and sign to BCDAR */
+  #if SINGLE
+  op=bcdar+1;                          /* no pad digit */
+  #else
+  op=bcdar;                            /* first (pad) digit here */
+  #endif
+  for (ip=packed; ip<packed+((DECPMAX+2)/2); ip++) {
+    *op=*ip>>4;
+    if (*op>9) return NULL;
+    op++;
+    *op=(uByte)(*ip&0x0f);             /* [final nibble is sign] */
+    if (*op>9 && ip<packed+((DECPMAX+2)/2)-1) return NULL;
+    op++;
+    }
+  op--;                                /* -> sign byte */
+  if (*op<=9) return NULL;             /* bad sign */
+  if (*op==DECPMINUS || *op==DECPMINUSALT) sig=DECFLOAT_Sign;
+
+  #if !SINGLE
+  if (bcdar[0]!=0) return NULL;        /* bad pad nibble */
+  #endif
+
+  if (EXPISNAN(exp)) {                 /* a NaN */
+    if (bcdar[1]!=0) return NULL;      /* bad msd */
+    } /* NaN */
+   else if (EXPISINF(exp)) {           /* is infinite */
+    Int i;
+    for (i=0; i<DECPMAX; i++) {
+      if (bcdar[i+1]!=0) return NULL;  /* should be all zeros */
+      }
+    } /* infinity */
+   else {                              /* finite */
+    /* check the exponent is in range */
+    if (exp>DECEMAX-DECPMAX+1) return NULL;
+    if (exp<DECEMIN-DECPMAX+1) return NULL;
+    }
+  return decFloatFromBCD(df, exp, bcdar+1, sig);
+  } /* decFloatFromPacked */
+
+/* ------------------------------------------------------------------ */
+/* decFloatFromString -- conversion from numeric string              */
 /*                                                                   */
 /*  result  is the decFloat format number which gets the result of    */
 /*         the conversion                                            */
 /*                                                                   */
 /*  result  is the decFloat format number which gets the result of    */
 /*         the conversion                                            */
@@ -710,12 +772,12 @@ decFloat * decFloatFromPacked(decFloat *df, Int exp, const uByte *packed) {
 /*         number (which may be a special value), \0-terminated      */
 /*         If there are too many significant digits in the           */
 /*         coefficient it will be rounded.                           */
 /*         number (which may be a special value), \0-terminated      */
 /*         If there are too many significant digits in the           */
 /*         coefficient it will be rounded.                           */
-/*  set            is the context                                            */
+/*  set     is the context                                           */
 /*  returns result                                                   */
 /*                                                                   */
 /* The length of the coefficient and the size of the exponent are     */
 /* checked by this routine, so the correct error (Underflow or       */
 /*  returns result                                                   */
 /*                                                                   */
 /* The length of the coefficient and the size of the exponent are     */
 /* checked by this routine, so the correct error (Underflow or       */
-/* Overflow) can be reported or rounding applied, as necessary.              */
+/* Overflow) can be reported or rounding applied, as necessary.       */
 /*                                                                   */
 /* There is no limit to the coefficient length for finite inputs;     */
 /* NaN payloads must be integers with no more than DECPMAX-1 digits.  */
 /*                                                                   */
 /* There is no limit to the coefficient length for finite inputs;     */
 /* NaN payloads must be integers with no more than DECPMAX-1 digits.  */
@@ -726,20 +788,21 @@ decFloat * decFloatFromPacked(decFloat *df, Int exp, const uByte *packed) {
 decFloat * decFloatFromString(decFloat *result, const char *string,
                              decContext *set) {
   Int   digits;                   /* count of digits in coefficient */
 decFloat * decFloatFromString(decFloat *result, const char *string,
                              decContext *set) {
   Int   digits;                   /* count of digits in coefficient */
-  const         char *dotchar=NULL;       /* where dot was found [NULL if none] */
-  const         char *cfirst=string;      /* -> first character of decimal part */
-  const         char *c;                  /* work */
+  const  char *dotchar=NULL;      /* where dot was found [NULL if none] */
+  const  char *cfirst=string;     /* -> first character of decimal part */
+  const  char *c;                 /* work */
   uByte *ub;                      /* .. */
   uByte *ub;                      /* .. */
+  uInt  uiwork;                   /* for macros */
   bcdnum num;                     /* collects data for finishing */
   uInt  error=DEC_Conversion_syntax;   /* assume the worst */
   bcdnum num;                     /* collects data for finishing */
   uInt  error=DEC_Conversion_syntax;   /* assume the worst */
-  uByte         buffer[ROUNDUP(DECSTRING+11, 8)]; /* room for most coefficents, */
+  uByte  buffer[ROUNDUP(DECSTRING+11, 8)]; /* room for most coefficents, */
                                   /* some common rounding, +3, & pad */
   #if DECTRACE
   /* printf("FromString %s ...\n", string); */
   #endif
 
   for(;;) {                            /* once-only 'loop' */
                                   /* some common rounding, +3, & pad */
   #if DECTRACE
   /* printf("FromString %s ...\n", string); */
   #endif
 
   for(;;) {                            /* once-only 'loop' */
-    num.sign=0;                                /* assume non-negative */
+    num.sign=0;                        /* assume non-negative */
     num.msd=buffer;                    /* MSD is here always */
 
     /* detect and validate the coefficient, including any leading, */
     num.msd=buffer;                    /* MSD is here always */
 
     /* detect and validate the coefficient, including any leading, */
@@ -810,7 +873,7 @@ decFloat * decFloatFromString(decFloat *result, const char *string,
        exp-=(Int)(clast-dotchar);      /* adjust exponent */
        /* [the '.' can now be ignored] */
        }
        exp-=(Int)(clast-dotchar);      /* adjust exponent */
        /* [the '.' can now be ignored] */
        }
-      num.exponent=exp;                        /* exponent is good; store it */
+      num.exponent=exp;                /* exponent is good; store it */
 
       /* Here when whole string has been inspected and syntax is good */
       /* cfirst->first digit or dot, clast->last digit or dot */
 
       /* Here when whole string has been inspected and syntax is good */
       /* cfirst->first digit or dot, clast->last digit or dot */
@@ -832,8 +895,8 @@ decFloat * decFloatFromString(decFloat *result, const char *string,
            /* as usual, go by fours when safe; NB it has been asserted */
            /* that a '.' does not have the same mask as a digit */
            if (c<=clast-3                             /* safe for four */
            /* as usual, go by fours when safe; NB it has been asserted */
            /* that a '.' does not have the same mask as a digit */
            if (c<=clast-3                             /* safe for four */
-            && (UINTAT(c)&0xf0f0f0f0)==CHARMASK) {    /* test four */
-             UINTAT(ub)=UINTAT(c)&0x0f0f0f0f;         /* to BCD8 */
+            && (UBTOUI(c)&0xf0f0f0f0)==CHARMASK) {    /* test four */
+             UBFROMUI(ub, UBTOUI(c)&0x0f0f0f0f);      /* to BCD8 */
              ub+=4;
              c+=4;
              continue;
              ub+=4;
              c+=4;
              continue;
@@ -846,7 +909,7 @@ decFloat * decFloatFromString(decFloat *result, const char *string,
            }
          } /* had dot */
        /* Now no dot; do this by fours (where safe) */
            }
          } /* had dot */
        /* Now no dot; do this by fours (where safe) */
-       for (; c<=clast-3; c+=4, ub+=4) UINTAT(ub)=UINTAT(c)&0x0f0f0f0f;
+       for (; c<=clast-3; c+=4, ub+=4) UBFROMUI(ub, UBTOUI(c)&0x0f0f0f0f);
        for (; c<=clast; c++, ub++) *ub=(uByte)(*c-'0');
        num.lsd=buffer+digits-1;             /* record new LSD */
        } /* fits */
        for (; c<=clast; c++, ub++) *ub=(uByte)(*c-'0');
        num.lsd=buffer+digits-1;             /* record new LSD */
        } /* fits */
@@ -857,7 +920,7 @@ decFloat * decFloatFromString(decFloat *result, const char *string,
        if (*cfirst=='.') cfirst++;          /* step past dot at start */
        if (*cfirst=='0') {                  /* [cfirst always -> digit] */
          for (; cfirst<clast; cfirst++) {
        if (*cfirst=='.') cfirst++;          /* step past dot at start */
        if (*cfirst=='0') {                  /* [cfirst always -> digit] */
          for (; cfirst<clast; cfirst++) {
-           if (*cfirst!='0') {              /* non-zero found */
+           if (*cfirst!='0') {              /* non-zero found */
              if (*cfirst=='.') continue;    /* [ignore] */
              break;                         /* done */
              }
              if (*cfirst=='.') continue;    /* [ignore] */
              break;                         /* done */
              }
@@ -871,8 +934,8 @@ decFloat * decFloatFromString(decFloat *result, const char *string,
        for (c=cfirst; c<=clast && ub<=buffer+DECPMAX; c++) {
          /* (see commentary just above) */
          if (c<=clast-3                          /* safe for four */
        for (c=cfirst; c<=clast && ub<=buffer+DECPMAX; c++) {
          /* (see commentary just above) */
          if (c<=clast-3                          /* safe for four */
-          && (UINTAT(c)&0xf0f0f0f0)==CHARMASK) { /* four digits */
-           UINTAT(ub)=UINTAT(c)&0x0f0f0f0f;      /* to BCD8 */
+          && (UBTOUI(c)&0xf0f0f0f0)==CHARMASK) { /* four digits */
+           UBFROMUI(ub, UBTOUI(c)&0x0f0f0f0f);   /* to BCD8 */
            ub+=4;
            c+=3;                            /* [will become 4] */
            continue;
            ub+=4;
            c+=3;                            /* [will become 4] */
            continue;
@@ -881,7 +944,7 @@ decFloat * decFloatFromString(decFloat *result, const char *string,
          *ub++=(uByte)(*c-'0');
          }
        ub--;                                /* -> LSD */
          *ub++=(uByte)(*c-'0');
          }
        ub--;                                /* -> LSD */
-       for (; c<=clast; c++) {              /* inspect remaining chars */
+       for (; c<=clast; c++) {              /* inspect remaining chars */
          if (*c!='0') {                     /* sticky bit needed */
            if (*c=='.') continue;           /* [ignore] */
            *ub=DECSTICKYTAB[*ub];           /* update round-for-reround */
          if (*c!='0') {                     /* sticky bit needed */
            if (*c=='.') continue;           /* [ignore] */
            *ub=DECSTICKYTAB[*ub];           /* update round-for-reround */
@@ -925,7 +988,7 @@ decFloat * decFloatFromString(decFloat *result, const char *string,
            *ub=(uByte)(*c-'0');        /* good bcd8 */
            }
          if (*c!='\0') break;          /* not all digits, or too many */
            *ub=(uByte)(*c-'0');        /* good bcd8 */
            }
          if (*c!='\0') break;          /* not all digits, or too many */
-         num.lsd=ub-1;                 /* record new LSD */
+         num.lsd=ub-1;                 /* record new LSD */
          }
        } /* NaN or sNaN */
       error=0;                         /* syntax is OK */
          }
        } /* NaN or sNaN */
       error=0;                         /* syntax is OK */
@@ -938,8 +1001,8 @@ decFloat * decFloatFromString(decFloat *result, const char *string,
 
   if (error!=0) {
     set->status|=error;
 
   if (error!=0) {
     set->status|=error;
-    num.exponent=DECFLOAT_qNaN;                /* set up quiet NaN */
-    num.sign=0;                                /* .. with 0 sign */
+    num.exponent=DECFLOAT_qNaN;        /* set up quiet NaN */
+    num.sign=0;                        /* .. with 0 sign */
     buffer[0]=0;                       /* .. and coefficient */
     num.lsd=buffer;                    /* .. */
     /* decShowNum(&num, "oops"); */
     buffer[0]=0;                       /* .. and coefficient */
     num.lsd=buffer;                    /* .. */
     /* decShowNum(&num, "oops"); */
@@ -957,7 +1020,7 @@ decFloat * decFloatFromString(decFloat *result, const char *string,
 /*  result  is the decFloat format number which gets the result of    */
 /*         the conversion                                            */
 /*  wider   is the decFloatWider format number which will be narrowed */
 /*  result  is the decFloat format number which gets the result of    */
 /*         the conversion                                            */
 /*  wider   is the decFloatWider format number which will be narrowed */
-/*  set            is the context                                            */
+/*  set     is the context                                           */
 /*  returns result                                                   */
 /*                                                                   */
 /* Narrowing can cause rounding, overflow, etc., but not Invalid      */
 /*  returns result                                                   */
 /*                                                                   */
 /* Narrowing can cause rounding, overflow, etc., but not Invalid      */
@@ -968,7 +1031,7 @@ decFloat * decFloatFromString(decFloat *result, const char *string,
 decFloat * decFloatFromWider(decFloat *result, const decFloatWider *wider,
                             decContext *set) {
   bcdnum num;                          /* collects data for finishing */
 decFloat * decFloatFromWider(decFloat *result, const decFloatWider *wider,
                             decContext *set) {
   bcdnum num;                          /* collects data for finishing */
-  uByte         bcdar[DECWPMAX];               /* room for wider coefficient */
+  uByte  bcdar[DECWPMAX];              /* room for wider coefficient */
   uInt  widerhi=DFWWORD(wider, 0);     /* top word */
   Int   exp;
 
   uInt  widerhi=DFWWORD(wider, 0);     /* top word */
   Int   exp;
 
@@ -979,7 +1042,7 @@ decFloat * decFloatFromWider(decFloat *result, const decFloatWider *wider,
   num.sign=widerhi&0x80000000;         /* extract sign [DECFLOAT_Sign=Neg] */
 
   /* decode the wider combination field to exponent */
   num.sign=widerhi&0x80000000;         /* extract sign [DECFLOAT_Sign=Neg] */
 
   /* decode the wider combination field to exponent */
-  exp=DECCOMBWEXP[widerhi>>26];                /* decode from wider combination field */
+  exp=DECCOMBWEXP[widerhi>>26];        /* decode from wider combination field */
   /* if it is a special there's nothing to do unless sNaN; if it's */
   /* finite then add the (wider) exponent continuation and unbias */
   if (EXPISSPECIAL(exp)) exp=widerhi&0x7e000000; /* include sNaN selector */
   /* if it is a special there's nothing to do unless sNaN; if it's */
   /* finite then add the (wider) exponent continuation and unbias */
   if (EXPISSPECIAL(exp)) exp=widerhi&0x7e000000; /* include sNaN selector */
@@ -1001,7 +1064,7 @@ decFloat * decFloatFromWider(decFloat *result, const decFloatWider *wider,
 /*  returns the sign of the coefficient (DECFLOAT_Sign if negative,   */
 /*    0 otherwise)                                                   */
 /*                                                                   */
 /*  returns the sign of the coefficient (DECFLOAT_Sign if negative,   */
 /*    0 otherwise)                                                   */
 /*                                                                   */
-/* No error is possible, and no status will be set.  If df is a              */
+/* No error is possible, and no status will be set.  If df is a       */
 /* special value the array is set to zeros (for Infinity) or to the   */
 /* payload of a qNaN or sNaN.                                        */
 /* ------------------------------------------------------------------ */
 /* special value the array is set to zeros (for Infinity) or to the   */
 /* payload of a qNaN or sNaN.                                        */
 /* ------------------------------------------------------------------ */
@@ -1015,12 +1078,12 @@ Int decFloatGetCoefficient(const decFloat *df, uByte *bcdar) {
   } /* decFloatGetCoefficient */
 
 /* ------------------------------------------------------------------ */
   } /* decFloatGetCoefficient */
 
 /* ------------------------------------------------------------------ */
-/* decFloatGetExponent -- get unbiased exponent                              */
+/* decFloatGetExponent -- get unbiased exponent                      */
 /*                                                                   */
 /*  df is the decFloat from which to extract the exponent            */
 /*  returns the exponent, q.                                         */
 /*                                                                   */
 /*                                                                   */
 /*  df is the decFloat from which to extract the exponent            */
 /*  returns the exponent, q.                                         */
 /*                                                                   */
-/* No error is possible, and no status will be set.  If df is a              */
+/* No error is possible, and no status will be set.  If df is a       */
 /* special value the first seven bits of the decFloat are returned,   */
 /* left adjusted and with the first (sign) bit set to 0 (followed by  */
 /* 25 0 bits). e.g., -sNaN would return 0x7e000000 (DECFLOAT_sNaN).  */
 /* special value the first seven bits of the decFloat are returned,   */
 /* left adjusted and with the first (sign) bit set to 0 (followed by  */
 /* 25 0 bits). e.g., -sNaN would return 0x7e000000 (DECFLOAT_sNaN).  */
@@ -1034,11 +1097,11 @@ Int decFloatGetExponent(const decFloat *df) {
 /* decFloatSetCoefficient -- set coefficient from BCD8               */
 /*                                                                   */
 /*  df is the target decFloat (and source of exponent/special value)  */
 /* decFloatSetCoefficient -- set coefficient from BCD8               */
 /*                                                                   */
 /*  df is the target decFloat (and source of exponent/special value)  */
-/*  bcdar holds DECPMAX digits to set the coefficient from, one              */
+/*  bcdar holds DECPMAX digits to set the coefficient from, one       */
 /*    digit in each byte (BCD8 encoding); the first (MSD) is ignored  */
 /*    if df is a NaN; all are ignored if df is infinite.             */
 /*  sig is DECFLOAT_Sign to set the sign bit, 0 otherwise            */
 /*    digit in each byte (BCD8 encoding); the first (MSD) is ignored  */
 /*    if df is a NaN; all are ignored if df is infinite.             */
 /*  sig is DECFLOAT_Sign to set the sign bit, 0 otherwise            */
-/*  returns df, which will be canonical                                      */
+/*  returns df, which will be canonical                              */
 /*                                                                   */
 /* No error is possible, and no status will be set.                  */
 /* ------------------------------------------------------------------ */
 /*                                                                   */
 /* No error is possible, and no status will be set.                  */
 /* ------------------------------------------------------------------ */
@@ -1060,18 +1123,18 @@ decFloat * decFloatSetCoefficient(decFloat *df, const uByte *bcdar,
   } /* decFloatSetCoefficient */
 
 /* ------------------------------------------------------------------ */
   } /* decFloatSetCoefficient */
 
 /* ------------------------------------------------------------------ */
-/* decFloatSetExponent -- set exponent or special value                      */
+/* decFloatSetExponent -- set exponent or special value              */
 /*                                                                   */
 /*  df is the target decFloat (and source of coefficient/payload)    */
 /*  set is the context for reporting status                          */
 /*  exp is the unbiased exponent, q, or a special value in the form   */
 /*    returned by decFloatGetExponent                                */
 /*                                                                   */
 /*  df is the target decFloat (and source of coefficient/payload)    */
 /*  set is the context for reporting status                          */
 /*  exp is the unbiased exponent, q, or a special value in the form   */
 /*    returned by decFloatGetExponent                                */
-/*  returns df, which will be canonical                                      */
+/*  returns df, which will be canonical                              */
 /*                                                                   */
 /*                                                                   */
-/* No error is possible, but Overflow or Underflow might occur.              */
+/* No error is possible, but Overflow or Underflow might occur.       */
 /* ------------------------------------------------------------------ */
 decFloat * decFloatSetExponent(decFloat *df, decContext *set, Int exp) {
 /* ------------------------------------------------------------------ */
 decFloat * decFloatSetExponent(decFloat *df, decContext *set, Int exp) {
-  uByte         bcdcopy[DECPMAX];         /* for coefficient */
+  uByte  bcdcopy[DECPMAX];        /* for coefficient */
   bcdnum num;                     /* work */
   num.exponent=exp;
   num.sign=decFloatGetCoefficient(df, bcdcopy); /* extract coefficient */
   bcdnum num;                     /* work */
   num.exponent=exp;
   num.sign=decFloatGetCoefficient(df, bcdcopy); /* extract coefficient */
@@ -1094,16 +1157,17 @@ uInt decFloatRadix(const decFloat *df) {
   return 10;
   } /* decFloatRadix */
 
   return 10;
   } /* decFloatRadix */
 
+#if (DECCHECK || DECTRACE)
 /* ------------------------------------------------------------------ */
 /* ------------------------------------------------------------------ */
-/* decFloatShow -- printf a decFloat in hexadecimal and decimal              */
-/*   df         is the decFloat to show                                      */
+/* decFloatShow -- printf a decFloat in hexadecimal and decimal       */
+/*   df  is the decFloat to show                                     */
 /*   tag is a tag string displayed with the number                   */
 /*                                                                   */
 /* This is a debug aid; the precise format of the string may change.  */
 /* ------------------------------------------------------------------ */
 void decFloatShow(const decFloat *df, const char *tag) {
   char hexbuf[DECBYTES*2+DECBYTES/4+1]; /* NB blank after every fourth */
 /*   tag is a tag string displayed with the number                   */
 /*                                                                   */
 /* This is a debug aid; the precise format of the string may change.  */
 /* ------------------------------------------------------------------ */
 void decFloatShow(const decFloat *df, const char *tag) {
   char hexbuf[DECBYTES*2+DECBYTES/4+1]; /* NB blank after every fourth */
-  char buff[DECSTRING];                        /* for value in decimal */
+  char buff[DECSTRING];                /* for value in decimal */
   Int i, j=0;
 
   for (i=0; i<DECBYTES; i++) {
   Int i, j=0;
 
   for (i=0; i<DECBYTES; i++) {
@@ -1120,13 +1184,14 @@ void decFloatShow(const decFloat *df, const char *tag) {
   printf(">%s> %s [big-endian] %s\n", tag, hexbuf, buff);
   return;
   } /* decFloatShow */
   printf(">%s> %s [big-endian] %s\n", tag, hexbuf, buff);
   return;
   } /* decFloatShow */
+#endif
 
 /* ------------------------------------------------------------------ */
 /* decFloatToBCD -- get sign, exponent, and BCD8 from a decFloat      */
 /*                                                                   */
 /*  df is the source decFloat                                        */
 /*  exp will be set to the unbiased exponent, q, or to a special      */
 
 /* ------------------------------------------------------------------ */
 /* decFloatToBCD -- get sign, exponent, and BCD8 from a decFloat      */
 /*                                                                   */
 /*  df is the source decFloat                                        */
 /*  exp will be set to the unbiased exponent, q, or to a special      */
-/*    value in the form returned by decFloatGetExponent                      */
+/*    value in the form returned by decFloatGetExponent              */
 /*  bcdar is where DECPMAX bytes will be written, one BCD digit in    */
 /*    each byte (BCD8 encoding); if df is a NaN the first byte will   */
 /*    be zero, and if it is infinite they will all be zero           */
 /*  bcdar is where DECPMAX bytes will be written, one BCD digit in    */
 /*    each byte (BCD8 encoding); if df is a NaN the first byte will   */
 /*    be zero, and if it is infinite they will all be zero           */
@@ -1156,7 +1221,7 @@ Int decFloatToBCD(const decFloat *df, Int *exp, uByte *bcdar) {
 /* ------------------------------------------------------------------ */
 /* decFloatToEngString -- conversion to numeric string, engineering   */
 /*                                                                   */
 /* ------------------------------------------------------------------ */
 /* decFloatToEngString -- conversion to numeric string, engineering   */
 /*                                                                   */
-/*  df is the decFloat format number to convert                              */
+/*  df is the decFloat format number to convert                      */
 /*  string is the string where the result will be laid out           */
 /*                                                                   */
 /* string must be at least DECPMAX+9 characters (the worst case is    */
 /*  string is the string where the result will be laid out           */
 /*                                                                   */
 /* string must be at least DECPMAX+9 characters (the worst case is    */
@@ -1169,11 +1234,14 @@ char * decFloatToEngString(const decFloat *df, char *string){
   uInt msd;                       /* coefficient MSD */
   Int  exp;                       /* exponent top two bits or full */
   uInt comb;                      /* combination field */
   uInt msd;                       /* coefficient MSD */
   Int  exp;                       /* exponent top two bits or full */
   uInt comb;                      /* combination field */
-  char *cstart;                           /* coefficient start */
+  char *cstart;                   /* coefficient start */
   char *c;                        /* output pointer in string */
   char *s, *t;                    /* .. (source, target) */
   Int  pre, e;                    /* work */
   const uByte *u;                 /* .. */
   char *c;                        /* output pointer in string */
   char *s, *t;                    /* .. (source, target) */
   Int  pre, e;                    /* work */
   const uByte *u;                 /* .. */
+  uInt uiwork;                    /* for macros [one compiler needs */
+                                  /* volatile here to avoid bug, but */
+                                  /* that doubles execution time] */
 
   /* Source words; macro handles endianness */
   uInt sourhi=DFWORD(df, 0);      /* word with sign */
 
   /* Source words; macro handles endianness */
   uInt sourhi=DFWORD(df, 0);      /* word with sign */
@@ -1188,12 +1256,12 @@ char * decFloatToEngString(const decFloat *df, char *string){
   c=string;                       /* where result will go */
   if (((Int)sourhi)<0) *c++='-';   /* handle sign */
   comb=sourhi>>26;                /* sign+combination field */
   c=string;                       /* where result will go */
   if (((Int)sourhi)<0) *c++='-';   /* handle sign */
   comb=sourhi>>26;                /* sign+combination field */
-  msd=DECCOMBMSD[comb];                   /* decode the combination field */
-  exp=DECCOMBEXP[comb];                   /* .. */
+  msd=DECCOMBMSD[comb];           /* decode the combination field */
+  exp=DECCOMBEXP[comb];           /* .. */
 
   if (EXPISSPECIAL(exp)) {        /* special */
     if (exp==DECFLOAT_Inf) {      /* infinity */
 
   if (EXPISSPECIAL(exp)) {        /* special */
     if (exp==DECFLOAT_Inf) {      /* infinity */
-      strcpy(c,          "Inf");
+      strcpy(c,   "Inf");
       strcpy(c+3, "inity");
       return string;              /* easy */
       }
       strcpy(c+3, "inity");
       return string;              /* easy */
       }
@@ -1225,44 +1293,44 @@ char * decFloatToEngString(const decFloat *df, char *string){
   /* are the three encoded BCD8 digits followed by a 1-byte length */
   /* (significant digits, except that 000 has length 0).  This allows */
   /* us to left-align the first declet with non-zero content, then */
   /* are the three encoded BCD8 digits followed by a 1-byte length */
   /* (significant digits, except that 000 has length 0).  This allows */
   /* us to left-align the first declet with non-zero content, then */
-  /* the remaining ones are full 3-char length.         Fixed-length copies */
+  /* the remaining ones are full 3-char length.  Fixed-length copies */
   /* are used because variable-length memcpy causes a subroutine call */
   /* are used because variable-length memcpy causes a subroutine call */
-  /* in at least two compilers.         (The copies are length 4 for speed */
+  /* in at least two compilers.  (The copies are length 4 for speed */
   /* and are safe because the last item in the array is of length */
   /* three and has the length byte following.) */
   #define dpd2char(dpdin) u=&DPD2BCD8[((dpdin)&0x3ff)*4];       \
   /* and are safe because the last item in the array is of length */
   /* three and has the length byte following.) */
   #define dpd2char(dpdin) u=&DPD2BCD8[((dpdin)&0x3ff)*4];       \
-        if (c!=cstart) {UINTAT(c)=UINTAT(u)|CHARMASK; c+=3;}    \
+        if (c!=cstart) {UBFROMUI(c, UBTOUI(u)|CHARMASK); c+=3;} \
          else if (*(u+3)) {                                     \
          else if (*(u+3)) {                                     \
-          UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; c+=*(u+3);}
+          UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); c+=*(u+3);}
 
   #if DECPMAX==7
 
   #if DECPMAX==7
-  dpd2char(sourhi>>10);                        /* declet 1 */
+  dpd2char(sourhi>>10);                /* declet 1 */
   dpd2char(sourhi);                    /* declet 2 */
 
   #elif DECPMAX==16
   dpd2char(sourhi>>8);                 /* declet 1 */
   dpd2char((sourhi<<2) | (sourlo>>30)); /* declet 2 */
   dpd2char(sourhi);                    /* declet 2 */
 
   #elif DECPMAX==16
   dpd2char(sourhi>>8);                 /* declet 1 */
   dpd2char((sourhi<<2) | (sourlo>>30)); /* declet 2 */
-  dpd2char(sourlo>>20);                        /* declet 3 */
-  dpd2char(sourlo>>10);                        /* declet 4 */
+  dpd2char(sourlo>>20);                /* declet 3 */
+  dpd2char(sourlo>>10);                /* declet 4 */
   dpd2char(sourlo);                    /* declet 5 */
 
   #elif DECPMAX==34
   dpd2char(sourhi>>4);                 /* declet 1 */
   dpd2char((sourhi<<6) | (sourmh>>26)); /* declet 2 */
   dpd2char(sourlo);                    /* declet 5 */
 
   #elif DECPMAX==34
   dpd2char(sourhi>>4);                 /* declet 1 */
   dpd2char((sourhi<<6) | (sourmh>>26)); /* declet 2 */
-  dpd2char(sourmh>>16);                        /* declet 3 */
+  dpd2char(sourmh>>16);                /* declet 3 */
   dpd2char(sourmh>>6);                 /* declet 4 */
   dpd2char((sourmh<<4) | (sourml>>28)); /* declet 5 */
   dpd2char(sourmh>>6);                 /* declet 4 */
   dpd2char((sourmh<<4) | (sourml>>28)); /* declet 5 */
-  dpd2char(sourml>>18);                        /* declet 6 */
+  dpd2char(sourml>>18);                /* declet 6 */
   dpd2char(sourml>>8);                 /* declet 7 */
   dpd2char((sourml<<2) | (sourlo>>30)); /* declet 8 */
   dpd2char(sourml>>8);                 /* declet 7 */
   dpd2char((sourml<<2) | (sourlo>>30)); /* declet 8 */
-  dpd2char(sourlo>>20);                        /* declet 9 */
-  dpd2char(sourlo>>10);                        /* declet 10 */
+  dpd2char(sourlo>>20);                /* declet 9 */
+  dpd2char(sourlo>>10);                /* declet 10 */
   dpd2char(sourlo);                    /* declet 11 */
   #endif
 
   if (c==cstart) *c++='0';        /* all zeros, empty -- make "0" */
 
   dpd2char(sourlo);                    /* declet 11 */
   #endif
 
   if (c==cstart) *c++='0';        /* all zeros, empty -- make "0" */
 
-  if (exp==0) {                           /* integer or NaN case -- easy */
+  if (exp==0) {                   /* integer or NaN case -- easy */
     *c='\0';                      /* terminate */
     return string;
     }
     *c='\0';                      /* terminate */
     return string;
     }
@@ -1275,7 +1343,7 @@ char * decFloatToEngString(const decFloat *df, char *string){
   if (exp>0 || pre<-5) {          /* need exponential form */
     e=pre-1;                      /* calculate E value */
     pre=1;                        /* assume one digit before '.' */
   if (exp>0 || pre<-5) {          /* need exponential form */
     e=pre-1;                      /* calculate E value */
     pre=1;                        /* assume one digit before '.' */
-    if (e!=0) {                           /* engineering: may need to adjust */
+    if (e!=0) {                   /* engineering: may need to adjust */
       Int adj;                    /* adjustment */
       /* The C remainder operator is undefined for negative numbers, so */
       /* a positive remainder calculation must be used here */
       Int adj;                    /* adjustment */
       /* The C remainder operator is undefined for negative numbers, so */
       /* a positive remainder calculation must be used here */
@@ -1310,8 +1378,8 @@ char * decFloatToEngString(const decFloat *df, char *string){
       /* because there is still space for exponent */
       s=dotat+ROUNDDOWN4(c-dotat);     /* source */
       t=s+1;                           /* target */
       /* because there is still space for exponent */
       s=dotat+ROUNDDOWN4(c-dotat);     /* source */
       t=s+1;                           /* target */
-      /* open the gap */
-      for (; s>=dotat; s-=4, t-=4) UINTAT(t)=UINTAT(s);
+      /* open the gap [cannot use memcpy] */
+      for (; s>=dotat; s-=4, t-=4) UBFROMUI(t, UBTOUI(s));
       *dotat='.';
       c++;                             /* length increased by one */
       } /* need dot? */
       *dotat='.';
       c++;                             /* length increased by one */
       } /* need dot? */
@@ -1321,24 +1389,24 @@ char * decFloatToEngString(const decFloat *df, char *string){
     /* -5<=pre<=0: here for plain 0.ddd or 0.000ddd forms (may have
        E, but only for 0.00E+3 kind of case -- with plenty of spare
        space in this case */
     /* -5<=pre<=0: here for plain 0.ddd or 0.000ddd forms (may have
        E, but only for 0.00E+3 kind of case -- with plenty of spare
        space in this case */
-    pre=-pre+2;                                /* gap width, including "0." */
+    pre=-pre+2;                        /* gap width, including "0." */
     t=cstart+ROUNDDOWN4(c-cstart)+pre; /* preferred first target point */
     /* backoff if too far to the right */
     if (t>string+DECSTRING-5) t=string+DECSTRING-5; /* adjust to fit */
     /* now shift the entire coefficient to the right, being careful not */
     t=cstart+ROUNDDOWN4(c-cstart)+pre; /* preferred first target point */
     /* backoff if too far to the right */
     if (t>string+DECSTRING-5) t=string+DECSTRING-5; /* adjust to fit */
     /* now shift the entire coefficient to the right, being careful not */
-    /* to access to the left of string */
-    for (s=t-pre; s>=string; s-=4, t-=4) UINTAT(t)=UINTAT(s);
+    /* to access to the left of string [cannot use memcpy] */
+    for (s=t-pre; s>=string; s-=4, t-=4) UBFROMUI(t, UBTOUI(s));
     /* for Quads and Singles there may be a character or two left... */
     s+=3;                              /* where next would come from */
     for(; s>=cstart; s--, t--) *(t+3)=*(s);
     /* now have fill 0. through 0.00000; use overlaps to avoid tests */
     if (pre>=4) {
     /* for Quads and Singles there may be a character or two left... */
     s+=3;                              /* where next would come from */
     for(; s>=cstart; s--, t--) *(t+3)=*(s);
     /* now have fill 0. through 0.00000; use overlaps to avoid tests */
     if (pre>=4) {
-      UINTAT(cstart+pre-4)=UINTAT("0000");
-      UINTAT(cstart)=UINTAT("0.00");
+      memcpy(cstart+pre-4, "0000", 4);
+      memcpy(cstart, "0.00", 4);
       }
      else { /* 2 or 3 */
       *(cstart+pre-1)='0';
       }
      else { /* 2 or 3 */
       *(cstart+pre-1)='0';
-      USHORTAT(cstart)=USHORTAT("0.");
+      memcpy(cstart, "0.", 2);
       }
     c+=pre;                            /* to end */
     }
       }
     c+=pre;                            /* to end */
     }
@@ -1346,7 +1414,7 @@ char * decFloatToEngString(const decFloat *df, char *string){
   /* finally add the E-part, if needed; it will never be 0, and has */
   /* a maximum length of 3 or 4 digits (asserted above) */
   if (e!=0) {
   /* finally add the E-part, if needed; it will never be 0, and has */
   /* a maximum length of 3 or 4 digits (asserted above) */
   if (e!=0) {
-    USHORTAT(c)=USHORTAT("E+");                /* starts with E, assume + */
+    memcpy(c, "E+", 2);                /* starts with E, assume + */
     c++;
     if (e<0) {
       *c='-';                          /* oops, need '-' */
     c++;
     if (e<0) {
       *c='-';                          /* oops, need '-' */
@@ -1355,15 +1423,15 @@ char * decFloatToEngString(const decFloat *df, char *string){
     c++;
     /* Three-character exponents are easy; 4-character a little trickier */
     #if DECEMAXD<=3
     c++;
     /* Three-character exponents are easy; 4-character a little trickier */
     #if DECEMAXD<=3
-      u=&BIN2BCD8[e*4];                        /* -> 3 digits + length byte */
+      u=&BIN2BCD8[e*4];                /* -> 3 digits + length byte */
       /* copy fixed 4 characters [is safe], starting at non-zero */
       /* and with character mask to convert BCD to char */
       /* copy fixed 4 characters [is safe], starting at non-zero */
       /* and with character mask to convert BCD to char */
-      UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK;
+      UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK);
       c+=*(u+3);                       /* bump pointer appropriately */
     #elif DECEMAXD==4
       if (e<1000) {                    /* 3 (or fewer) digits case */
        u=&BIN2BCD8[e*4];               /* -> 3 digits + length byte */
       c+=*(u+3);                       /* bump pointer appropriately */
     #elif DECEMAXD==4
       if (e<1000) {                    /* 3 (or fewer) digits case */
        u=&BIN2BCD8[e*4];               /* -> 3 digits + length byte */
-       UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; /* [as above] */
+       UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); /* [as above] */
        c+=*(u+3);                      /* bump pointer appropriately */
        }
        else {                          /* 4-digits */
        c+=*(u+3);                      /* bump pointer appropriately */
        }
        else {                          /* 4-digits */
@@ -1371,7 +1439,7 @@ char * decFloatToEngString(const decFloat *df, char *string){
        Int rem=e-(1000*thou);          /* e%1000 */
        *c++=(char)('0'+(char)thou);    /* the thousands digit */
        u=&BIN2BCD8[rem*4];             /* -> 3 digits + length byte */
        Int rem=e-(1000*thou);          /* e%1000 */
        *c++=(char)('0'+(char)thou);    /* the thousands digit */
        u=&BIN2BCD8[rem*4];             /* -> 3 digits + length byte */
-       UINTAT(c)=UINTAT(u)|CHARMASK;   /* copy fixed 3+1 characters [is safe] */
+       UBFROMUI(c, UBTOUI(u)|CHARMASK);/* copy fixed 3+1 characters [is safe] */
        c+=3;                           /* bump pointer, always 3 digits */
        }
     #endif
        c+=3;                           /* bump pointer, always 3 digits */
        }
     #endif
@@ -1386,7 +1454,7 @@ char * decFloatToEngString(const decFloat *df, char *string){
 /*                                                                   */
 /*  df is the source decFloat                                        */
 /*  exp will be set to the unbiased exponent, q, or to a special      */
 /*                                                                   */
 /*  df is the source decFloat                                        */
 /*  exp will be set to the unbiased exponent, q, or to a special      */
-/*    value in the form returned by decFloatGetExponent                      */
+/*    value in the form returned by decFloatGetExponent              */
 /*  packed is where DECPMAX nibbles will be written with the sign as  */
 /*    final nibble (0x0c for +, 0x0d for -); a NaN has a first nibble */
 /*    of zero, and an infinity is all zeros. decDouble and decQuad    */
 /*  packed is where DECPMAX nibbles will be written with the sign as  */
 /*    final nibble (0x0c for +, 0x0d for -); a NaN has a first nibble */
 /*    of zero, and an infinity is all zeros. decDouble and decQuad    */
@@ -1432,7 +1500,7 @@ Int decFloatToPacked(const decFloat *df, Int *exp, uByte *packed) {
 /* ------------------------------------------------------------------ */
 /* decFloatToString -- conversion to numeric string                  */
 /*                                                                   */
 /* ------------------------------------------------------------------ */
 /* decFloatToString -- conversion to numeric string                  */
 /*                                                                   */
-/*  df is the decFloat format number to convert                              */
+/*  df is the decFloat format number to convert                      */
 /*  string is the string where the result will be laid out           */
 /*                                                                   */
 /* string must be at least DECPMAX+9 characters (the worst case is    */
 /*  string is the string where the result will be laid out           */
 /*                                                                   */
 /* string must be at least DECPMAX+9 characters (the worst case is    */
@@ -1445,11 +1513,14 @@ char * decFloatToString(const decFloat *df, char *string){
   uInt msd;                       /* coefficient MSD */
   Int  exp;                       /* exponent top two bits or full */
   uInt comb;                      /* combination field */
   uInt msd;                       /* coefficient MSD */
   Int  exp;                       /* exponent top two bits or full */
   uInt comb;                      /* combination field */
-  char *cstart;                           /* coefficient start */
+  char *cstart;                   /* coefficient start */
   char *c;                        /* output pointer in string */
   char *s, *t;                    /* .. (source, target) */
   Int  pre, e;                    /* work */
   const uByte *u;                 /* .. */
   char *c;                        /* output pointer in string */
   char *s, *t;                    /* .. (source, target) */
   Int  pre, e;                    /* work */
   const uByte *u;                 /* .. */
+  uInt uiwork;                    /* for macros [one compiler needs */
+                                  /* volatile here to avoid bug, but */
+                                  /* that doubles execution time] */
 
   /* Source words; macro handles endianness */
   uInt sourhi=DFWORD(df, 0);      /* word with sign */
 
   /* Source words; macro handles endianness */
   uInt sourhi=DFWORD(df, 0);      /* word with sign */
@@ -1464,10 +1535,14 @@ char * decFloatToString(const decFloat *df, char *string){
   c=string;                       /* where result will go */
   if (((Int)sourhi)<0) *c++='-';   /* handle sign */
   comb=sourhi>>26;                /* sign+combination field */
   c=string;                       /* where result will go */
   if (((Int)sourhi)<0) *c++='-';   /* handle sign */
   comb=sourhi>>26;                /* sign+combination field */
-  msd=DECCOMBMSD[comb];                   /* decode the combination field */
-  exp=DECCOMBEXP[comb];                   /* .. */
+  msd=DECCOMBMSD[comb];           /* decode the combination field */
+  exp=DECCOMBEXP[comb];           /* .. */
 
 
-  if (EXPISSPECIAL(exp)) {        /* special */
+  if (!EXPISSPECIAL(exp)) {       /* finite */
+    /* complete exponent; top two bits are in place */
+    exp+=GETECON(df)-DECBIAS;     /* .. + continuation and unbias */
+    }
+   else {                         /* IS special */
     if (exp==DECFLOAT_Inf) {      /* infinity */
       strcpy(c, "Infinity");
       return string;              /* easy */
     if (exp==DECFLOAT_Inf) {      /* infinity */
       strcpy(c, "Infinity");
       return string;              /* easy */
@@ -1487,9 +1562,6 @@ char * decFloatToString(const decFloat *df, char *string){
     /* otherwise drop through to add integer; set correct exp etc. */
     exp=0; msd=0;                 /* setup for following code */
     }
     /* otherwise drop through to add integer; set correct exp etc. */
     exp=0; msd=0;                 /* setup for following code */
     }
-   else { /* complete exponent; top two bits are in place */
-    exp+=GETECON(df)-DECBIAS;     /* .. + continuation and unbias */
-    }
 
   /* convert the digits of the significand to characters */
   cstart=c;                       /* save start of coefficient */
 
   /* convert the digits of the significand to characters */
   cstart=c;                       /* save start of coefficient */
@@ -1500,38 +1572,38 @@ char * decFloatToString(const decFloat *df, char *string){
   /* are the three encoded BCD8 digits followed by a 1-byte length */
   /* (significant digits, except that 000 has length 0).  This allows */
   /* us to left-align the first declet with non-zero content, then */
   /* are the three encoded BCD8 digits followed by a 1-byte length */
   /* (significant digits, except that 000 has length 0).  This allows */
   /* us to left-align the first declet with non-zero content, then */
-  /* the remaining ones are full 3-char length.         Fixed-length copies */
+  /* the remaining ones are full 3-char length.  Fixed-length copies */
   /* are used because variable-length memcpy causes a subroutine call */
   /* are used because variable-length memcpy causes a subroutine call */
-  /* in at least two compilers.         (The copies are length 4 for speed */
+  /* in at least two compilers.  (The copies are length 4 for speed */
   /* and are safe because the last item in the array is of length */
   /* three and has the length byte following.) */
   #define dpd2char(dpdin) u=&DPD2BCD8[((dpdin)&0x3ff)*4];       \
   /* and are safe because the last item in the array is of length */
   /* three and has the length byte following.) */
   #define dpd2char(dpdin) u=&DPD2BCD8[((dpdin)&0x3ff)*4];       \
-        if (c!=cstart) {UINTAT(c)=UINTAT(u)|CHARMASK; c+=3;}    \
+        if (c!=cstart) {UBFROMUI(c, UBTOUI(u)|CHARMASK); c+=3;} \
          else if (*(u+3)) {                                     \
          else if (*(u+3)) {                                     \
-          UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; c+=*(u+3);}
+          UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); c+=*(u+3);}
 
   #if DECPMAX==7
 
   #if DECPMAX==7
-  dpd2char(sourhi>>10);                        /* declet 1 */
+  dpd2char(sourhi>>10);                /* declet 1 */
   dpd2char(sourhi);                    /* declet 2 */
 
   #elif DECPMAX==16
   dpd2char(sourhi>>8);                 /* declet 1 */
   dpd2char((sourhi<<2) | (sourlo>>30)); /* declet 2 */
   dpd2char(sourhi);                    /* declet 2 */
 
   #elif DECPMAX==16
   dpd2char(sourhi>>8);                 /* declet 1 */
   dpd2char((sourhi<<2) | (sourlo>>30)); /* declet 2 */
-  dpd2char(sourlo>>20);                        /* declet 3 */
-  dpd2char(sourlo>>10);                        /* declet 4 */
+  dpd2char(sourlo>>20);                /* declet 3 */
+  dpd2char(sourlo>>10);                /* declet 4 */
   dpd2char(sourlo);                    /* declet 5 */
 
   #elif DECPMAX==34
   dpd2char(sourhi>>4);                 /* declet 1 */
   dpd2char((sourhi<<6) | (sourmh>>26)); /* declet 2 */
   dpd2char(sourlo);                    /* declet 5 */
 
   #elif DECPMAX==34
   dpd2char(sourhi>>4);                 /* declet 1 */
   dpd2char((sourhi<<6) | (sourmh>>26)); /* declet 2 */
-  dpd2char(sourmh>>16);                        /* declet 3 */
+  dpd2char(sourmh>>16);                /* declet 3 */
   dpd2char(sourmh>>6);                 /* declet 4 */
   dpd2char((sourmh<<4) | (sourml>>28)); /* declet 5 */
   dpd2char(sourmh>>6);                 /* declet 4 */
   dpd2char((sourmh<<4) | (sourml>>28)); /* declet 5 */
-  dpd2char(sourml>>18);                        /* declet 6 */
+  dpd2char(sourml>>18);                /* declet 6 */
   dpd2char(sourml>>8);                 /* declet 7 */
   dpd2char((sourml<<2) | (sourlo>>30)); /* declet 8 */
   dpd2char(sourml>>8);                 /* declet 7 */
   dpd2char((sourml<<2) | (sourlo>>30)); /* declet 8 */
-  dpd2char(sourlo>>20);                        /* declet 9 */
-  dpd2char(sourlo>>10);                        /* declet 10 */
+  dpd2char(sourlo>>20);                /* declet 9 */
+  dpd2char(sourlo>>10);                /* declet 10 */
   dpd2char(sourlo);                    /* declet 11 */
   #endif
 
   dpd2char(sourlo);                    /* declet 11 */
   #endif
 
@@ -1556,12 +1628,13 @@ char * decFloatToString(const decFloat *df, char *string){
   if (pre>0) {                    /* ddd.ddd (plain), perhaps with E */
     char *dotat=cstart+pre;
     if (dotat<c) {                     /* if embedded dot needed... */
   if (pre>0) {                    /* ddd.ddd (plain), perhaps with E */
     char *dotat=cstart+pre;
     if (dotat<c) {                     /* if embedded dot needed... */
+      /* [memmove is a disaster, here] */
       /* move by fours; there must be space for junk at the end */
       /* move by fours; there must be space for junk at the end */
-      /* because there is still space for exponent */
+      /* because exponent is still possible */
       s=dotat+ROUNDDOWN4(c-dotat);     /* source */
       t=s+1;                           /* target */
       s=dotat+ROUNDDOWN4(c-dotat);     /* source */
       t=s+1;                           /* target */
-      /* open the gap */
-      for (; s>=dotat; s-=4, t-=4) UINTAT(t)=UINTAT(s);
+      /* open the gap [cannot use memcpy] */
+      for (; s>=dotat; s-=4, t-=4) UBFROMUI(t, UBTOUI(s));
       *dotat='.';
       c++;                             /* length increased by one */
       } /* need dot? */
       *dotat='.';
       c++;                             /* length increased by one */
       } /* need dot? */
@@ -1569,10 +1642,10 @@ char * decFloatToString(const decFloat *df, char *string){
     /* finally add the E-part, if needed; it will never be 0, and has */
     /* a maximum length of 3 or 4 digits (asserted above) */
     if (e!=0) {
     /* finally add the E-part, if needed; it will never be 0, and has */
     /* a maximum length of 3 or 4 digits (asserted above) */
     if (e!=0) {
-      USHORTAT(c)=USHORTAT("E+");      /* starts with E, assume + */
+      memcpy(c, "E+", 2);              /* starts with E, assume + */
       c++;
       if (e<0) {
       c++;
       if (e<0) {
-       *c='-';                         /* oops, need '-' */
+       *c='-';                         /* oops, need '-' */
        e=-e;                           /* uInt, please */
        }
       c++;
        e=-e;                           /* uInt, please */
        }
       c++;
@@ -1581,21 +1654,21 @@ char * decFloatToString(const decFloat *df, char *string){
        u=&BIN2BCD8[e*4];               /* -> 3 digits + length byte */
        /* copy fixed 4 characters [is safe], starting at non-zero */
        /* and with character mask to convert BCD to char */
        u=&BIN2BCD8[e*4];               /* -> 3 digits + length byte */
        /* copy fixed 4 characters [is safe], starting at non-zero */
        /* and with character mask to convert BCD to char */
-       UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK;
+       UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK);
        c+=*(u+3);                      /* bump pointer appropriately */
       #elif DECEMAXD==4
        if (e<1000) {                   /* 3 (or fewer) digits case */
          u=&BIN2BCD8[e*4];             /* -> 3 digits + length byte */
        c+=*(u+3);                      /* bump pointer appropriately */
       #elif DECEMAXD==4
        if (e<1000) {                   /* 3 (or fewer) digits case */
          u=&BIN2BCD8[e*4];             /* -> 3 digits + length byte */
-         UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; /* [as above] */
+         UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); /* [as above] */
          c+=*(u+3);                    /* bump pointer appropriately */
          }
          c+=*(u+3);                    /* bump pointer appropriately */
          }
-        else {                         /* 4-digits */
+        else {                         /* 4-digits */
          Int thou=((e>>3)*1049)>>17;   /* e/1000 */
          Int rem=e-(1000*thou);        /* e%1000 */
          *c++=(char)('0'+(char)thou);  /* the thousands digit */
          u=&BIN2BCD8[rem*4];           /* -> 3 digits + length byte */
          Int thou=((e>>3)*1049)>>17;   /* e/1000 */
          Int rem=e-(1000*thou);        /* e%1000 */
          *c++=(char)('0'+(char)thou);  /* the thousands digit */
          u=&BIN2BCD8[rem*4];           /* -> 3 digits + length byte */
-         UINTAT(c)=UINTAT(u)|CHARMASK; /* copy fixed 3+1 characters [is safe] */
-         c+=3;                         /* bump pointer, always 3 digits */
+         UBFROMUI(c, UBTOUI(u)|CHARMASK); /* copy fixed 3+1 characters [is safe] */
+         c+=3;                         /* bump pointer, always 3 digits */
          }
       #endif
       }
          }
       #endif
       }
@@ -1618,19 +1691,19 @@ char * decFloatToString(const decFloat *df, char *string){
   /* backoff if too far to the right */
   if (t>string+DECSTRING-5) t=string+DECSTRING-5; /* adjust to fit */
   /* now shift the entire coefficient to the right, being careful not */
   /* backoff if too far to the right */
   if (t>string+DECSTRING-5) t=string+DECSTRING-5; /* adjust to fit */
   /* now shift the entire coefficient to the right, being careful not */
-  /* to access to the left of string */
-  for (s=t-pre; s>=string; s-=4, t-=4) UINTAT(t)=UINTAT(s);
+  /* to access to the left of string [cannot use memcpy] */
+  for (s=t-pre; s>=string; s-=4, t-=4) UBFROMUI(t, UBTOUI(s));
   /* for Quads and Singles there may be a character or two left... */
   /* for Quads and Singles there may be a character or two left... */
-  s+=3;                                        /* where next would come from */
+  s+=3;                                /* where next would come from */
   for(; s>=cstart; s--, t--) *(t+3)=*(s);
   /* now have fill 0. through 0.00000; use overlaps to avoid tests */
   if (pre>=4) {
   for(; s>=cstart; s--, t--) *(t+3)=*(s);
   /* now have fill 0. through 0.00000; use overlaps to avoid tests */
   if (pre>=4) {
-    UINTAT(cstart+pre-4)=UINTAT("0000");
-    UINTAT(cstart)=UINTAT("0.00");
+    memcpy(cstart+pre-4, "0000", 4);
+    memcpy(cstart, "0.00", 4);
     }
    else { /* 2 or 3 */
     *(cstart+pre-1)='0';
     }
    else { /* 2 or 3 */
     *(cstart+pre-1)='0';
-    USHORTAT(cstart)=USHORTAT("0.");
+    memcpy(cstart, "0.", 2);
     }
   *(c+pre)='\0';                       /* terminate */
   return string;
     }
   *(c+pre)='\0';                       /* terminate */
   return string;
@@ -1665,7 +1738,7 @@ decFloatWider * decFloatToWider(const decFloat *source, decFloatWider *wider) {
     code|=(exp<<(32-6-DECWECONL)) & 0x03ffffff; /* add exponent continuation */
     code|=DFWORD(source, 0)&0x80000000; /* add sign */
     DFWWORD(wider, 0)=code;            /* .. and place top word in wider */
     code|=(exp<<(32-6-DECWECONL)) & 0x03ffffff; /* add exponent continuation */
     code|=DFWORD(source, 0)&0x80000000; /* add sign */
     DFWWORD(wider, 0)=code;            /* .. and place top word in wider */
-    msd=GETMSD(source);                        /* get source coefficient MSD [0-9] */
+    msd=GETMSD(source);                /* get source coefficient MSD [0-9] */
     }
   /* Copy the coefficient and clear any 'unused' words to left */
   #if SINGLE
     }
   /* Copy the coefficient and clear any 'unused' words to left */
   #if SINGLE
@@ -1723,6 +1796,7 @@ decFloat * decFloatZero(decFloat *df){
   void decShowNum(const bcdnum *num, const char *tag) {
     const char *csign="+";             /* sign character */
     uByte *ub;                         /* work */
   void decShowNum(const bcdnum *num, const char *tag) {
     const char *csign="+";             /* sign character */
     uByte *ub;                         /* work */
+    uInt  uiwork;                      /* for macros */
     if (num->sign==DECFLOAT_Sign) csign="-";
 
     printf(">%s> ", tag);
     if (num->sign==DECFLOAT_Sign) csign="-";
 
     printf(">%s> ", tag);
@@ -1747,7 +1821,7 @@ decFloat * decFloatZero(decFloat *df){
      if (e==0) *c++='0';               /* 0-length case */
       else if (e<1000) {               /* 3 (or fewer) digits case */
        u=&BIN2BCD8[e*4];               /* -> 3 digits + length byte */
      if (e==0) *c++='0';               /* 0-length case */
       else if (e<1000) {               /* 3 (or fewer) digits case */
        u=&BIN2BCD8[e*4];               /* -> 3 digits + length byte */
-       UINTAT(c)=UINTAT(u+3-*(u+3))|CHARMASK; /* [as above] */
+       UBFROMUI(c, UBTOUI(u+3-*(u+3))|CHARMASK); /* [as above] */
        c+=*(u+3);                      /* bump pointer appropriately */
        }
       else {                           /* 4-digits */
        c+=*(u+3);                      /* bump pointer appropriately */
        }
       else {                           /* 4-digits */
@@ -1755,7 +1829,7 @@ decFloat * decFloatZero(decFloat *df){
        Int rem=e-(1000*thou);          /* e%1000 */
        *c++=(char)('0'+(char)thou);    /* the thousands digit */
        u=&BIN2BCD8[rem*4];             /* -> 3 digits + length byte */
        Int rem=e-(1000*thou);          /* e%1000 */
        *c++=(char)('0'+(char)thou);    /* the thousands digit */
        u=&BIN2BCD8[rem*4];             /* -> 3 digits + length byte */
-       UINTAT(c)=UINTAT(u)|CHARMASK;   /* copy fixed 3+1 characters [is safe] */
+       UBFROMUI(c, UBTOUI(u)|CHARMASK); /* copy fixed 3+1 characters [is safe] */
        c+=3;                           /* bump pointer, always 3 digits */
        }
      *c='\0';                          /* add terminator */
        c+=3;                           /* bump pointer, always 3 digits */
        }
      *c='\0';                          /* add terminator */
This page took 0.044398 seconds and 4 git commands to generate.