OSDN Git Service

* configure.ac (gcc_cv_ld_eh_gc_sections): Redirect objdump errors
[pf3gnuchains/gcc-fork.git] / libdecnumber / decCommon.c
index fa16e79..add1f2e 100644 (file)
@@ -1,32 +1,27 @@
 /* Common code for fixed-size types in the decNumber C Library.
-   Copyright (C) 2007 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2009 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
-   Software Foundation; either version 2, or (at your option) any later
+   Software Foundation; either version 3, or (at your option) any later
    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.
 
-   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         */
@@ -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    */
-/* 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)    */
 /*                                                                   */
-/*   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)  */
-/*   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)             */
@@ -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     */
-/* 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,
@@ -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,
-  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};
 
@@ -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  */
-/* 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).                */
 /*                                                                   */
@@ -248,8 +243,9 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
                              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 */
 
@@ -275,11 +271,11 @@ static decFloat * decFinalize(decFloat *df, bcdnum *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) {
-      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 */
       }
@@ -305,12 +301,12 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
        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 */
-       ulsd=roundat-1;                      /* new LSD */
+       ulsd=roundat-1;                      /* new LSD */
        }
        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++) {
-         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] */
            }
@@ -331,7 +327,7 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
        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 */
@@ -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 */
-          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) {
@@ -382,13 +378,15 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
            #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;
-         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) */
@@ -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 */
-       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: {
@@ -453,12 +451,12 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
            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;                    /* .. */
          }
-        else {                         /* return Nmax */
+        else {                         /* return Nmax */
          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); */
-         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;
@@ -492,23 +490,23 @@ static decFloat * decFinalize(decFloat *df, bcdnum *num,
   /*------------------------------------------------------------------*/
   /* 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);
-    }
+    } /* 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 */
-    /* [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] */
-  /* [coefficient length here will be < DECPMAX] */
-
   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] */
-  #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];}
@@ -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
-    getDPD(dpd, 1);
+    getDPDt(dpd, 1);
     encode|=dpd<<10;
-    getDPD(dpd, 0);
+    getDPDt(dpd, 0);
     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;
-    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
-    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;
-    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;
-    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;
-    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); */
-  /* decFloatShow(df, "final"); */
+  /* decFloatShow(df, "final2"); */
   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                       */
-/*  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.             */
-/*    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            */
-/*  returns df, which will be canonical                                      */
+/*  returns df, which will be canonical                              */
 /*                                                                   */
 /* 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. */
 
-  #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
-    getDPDf(dpd, 1);
+    getDPDb(dpd, 1);
     encode|=dpd<<10;
-    getDPDf(dpd, 0);
+    getDPDb(dpd, 0);
     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;
-    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
-    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;
-    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;
-    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;
-    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
-  /* decFloatShow(df, "final"); */
+  /* decFloatShow(df, "fromB"); */
   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.                                       */
-/*  returns df, which will be canonical                                      */
+/*  returns df, which will be canonical                              */
 /*                                                                   */
 /* 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--;                                        /* -> sign byte */
+  op--;                                /* -> sign byte */
   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 */
 
 /* ------------------------------------------------------------------ */
-/* 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 acccepted.                  */
+/*                                                                   */
+/* 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                                            */
@@ -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.                           */
-/*  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       */
-/* 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.  */
@@ -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 */
-  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;                      /* .. */
+  uInt  uiwork;                   /* for macros */
   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' */
-    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, */
@@ -810,7 +873,7 @@ decFloat * decFloatFromString(decFloat *result, const char *string,
        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 */
@@ -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 */
-            && (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;
@@ -846,7 +909,7 @@ decFloat * decFloatFromString(decFloat *result, const char *string,
            }
          } /* 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 */
@@ -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!='0') {              /* non-zero found */
+           if (*cfirst!='0') {              /* non-zero found */
              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 */
-          && (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;
@@ -881,7 +944,7 @@ decFloat * decFloatFromString(decFloat *result, const char *string,
          *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 */
@@ -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 */
-         num.lsd=ub-1;                 /* record new LSD */
+         num.lsd=ub-1;                 /* record new LSD */
          }
        } /* 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;
-    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"); */
@@ -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 */
-/*  set            is the context                                            */
+/*  set     is the context                                           */
 /*  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 */
-  uByte         bcdar[DECWPMAX];               /* room for wider coefficient */
+  uByte  bcdar[DECWPMAX];              /* room for wider coefficient */
   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 */
-  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 */
@@ -1001,7 +1064,7 @@ decFloat * decFloatFromWider(decFloat *result, const decFloatWider *wider,
 /*  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.                                        */
 /* ------------------------------------------------------------------ */
@@ -1015,12 +1078,12 @@ Int decFloatGetCoefficient(const decFloat *df, uByte *bcdar) {
   } /* decFloatGetCoefficient */
 
 /* ------------------------------------------------------------------ */
-/* decFloatGetExponent -- get unbiased exponent                              */
+/* decFloatGetExponent -- get unbiased exponent                      */
 /*                                                                   */
 /*  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).  */
@@ -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)  */
-/*  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            */
-/*  returns df, which will be canonical                                      */
+/*  returns df, which will be canonical                              */
 /*                                                                   */
 /* No error is possible, and no status will be set.                  */
 /* ------------------------------------------------------------------ */
@@ -1060,18 +1123,18 @@ decFloat * decFloatSetCoefficient(decFloat *df, const uByte *bcdar,
   } /* 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                                */
-/*  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) {
-  uByte         bcdcopy[DECPMAX];         /* for coefficient */
+  uByte  bcdcopy[DECPMAX];        /* for 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 */
 
+#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 */
-  char buff[DECSTRING];                        /* for value in decimal */
+  char buff[DECSTRING];                /* for value in decimal */
   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 */
+#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      */
-/*    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           */
@@ -1156,7 +1221,7 @@ Int decFloatToBCD(const decFloat *df, Int *exp, uByte *bcdar) {
 /* ------------------------------------------------------------------ */
 /* 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    */
@@ -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 */
-  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;                 /* .. */
+  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 */
@@ -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 */
-  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 */
-      strcpy(c,          "Inf");
+      strcpy(c,   "Inf");
       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 */
-  /* 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 */
-  /* 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];       \
-        if (c!=cstart) {UINTAT(c)=UINTAT(u)|CHARMASK; c+=3;}    \
+        if (c!=cstart) {UBFROMUI(c, UBTOUI(u)|CHARMASK); c+=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
-  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(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(sourmh>>16);                        /* declet 3 */
+  dpd2char(sourmh>>16);                /* declet 3 */
   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(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" */
 
-  if (exp==0) {                           /* integer or NaN case -- easy */
+  if (exp==0) {                   /* integer or NaN case -- easy */
     *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 (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 */
@@ -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 */
-      /* 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? */
@@ -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 */
-    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 */
-    /* 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) {
-      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';
-      USHORTAT(cstart)=USHORTAT("0.");
+      memcpy(cstart, "0.", 2);
       }
     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) {
-    USHORTAT(c)=USHORTAT("E+");                /* starts with E, assume + */
+    memcpy(c, "E+", 2);                /* starts with E, assume + */
     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
-      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 */
-      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 */
-       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 */
@@ -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 */
-       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
@@ -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      */
-/*    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    */
@@ -1432,7 +1500,7 @@ Int decFloatToPacked(const decFloat *df, Int *exp, uByte *packed) {
 /* ------------------------------------------------------------------ */
 /* 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    */
@@ -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 */
-  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;                 /* .. */
+  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 */
@@ -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 */
-  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 */
@@ -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 */
     }
-   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 */
@@ -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 */
-  /* 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 */
-  /* 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];       \
-        if (c!=cstart) {UINTAT(c)=UINTAT(u)|CHARMASK; c+=3;}    \
+        if (c!=cstart) {UBFROMUI(c, UBTOUI(u)|CHARMASK); c+=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
-  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(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(sourmh>>16);                        /* declet 3 */
+  dpd2char(sourmh>>16);                /* declet 3 */
   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(sourlo>>20);                        /* declet 9 */
-  dpd2char(sourlo>>10);                        /* declet 10 */
+  dpd2char(sourlo>>20);                /* declet 9 */
+  dpd2char(sourlo>>10);                /* declet 10 */
   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... */
+      /* [memmove is a disaster, here] */
       /* 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 */
-      /* 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? */
@@ -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) {
-      USHORTAT(c)=USHORTAT("E+");      /* starts with E, assume + */
+      memcpy(c, "E+", 2);              /* starts with E, assume + */
       c++;
       if (e<0) {
-       *c='-';                         /* oops, need '-' */
+       *c='-';                         /* oops, need '-' */
        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 */
-       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 */
-         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 */
+        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 */
-         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
       }
@@ -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 */
-  /* 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 */
+  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';
-    USHORTAT(cstart)=USHORTAT("0.");
+    memcpy(cstart, "0.", 2);
     }
   *(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 */
-    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
@@ -1723,6 +1796,7 @@ decFloat * decFloatZero(decFloat *df){
   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);
@@ -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 */
-       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 */
@@ -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 */
-       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 */