cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

decimal128.c (22372B)


      1/* Decimal 128-bit format module for the decNumber C Library.
      2   Copyright (C) 2005, 2007 Free Software Foundation, Inc.
      3   Contributed by IBM Corporation.  Author Mike Cowlishaw.
      4
      5   This file is part of GCC.
      6
      7   GCC is free software; you can redistribute it and/or modify it under
      8   the terms of the GNU General Public License as published by the Free
      9   Software Foundation; either version 2, or (at your option) any later
     10   version.
     11
     12   In addition to the permissions in the GNU General Public License,
     13   the Free Software Foundation gives you unlimited permission to link
     14   the compiled version of this file into combinations with other
     15   programs, and to distribute those combinations without any
     16   restriction coming from the use of this file.  (The General Public
     17   License restrictions do apply in other respects; for example, they
     18   cover modification of the file, and distribution when not linked
     19   into a combine executable.)
     20
     21   GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     22   WARRANTY; without even the implied warranty of MERCHANTABILITY or
     23   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     24   for more details.
     25
     26   You should have received a copy of the GNU General Public License
     27   along with GCC; see the file COPYING.  If not, write to the Free
     28   Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
     29   02110-1301, USA.  */
     30
     31/* ------------------------------------------------------------------ */
     32/* Decimal 128-bit format module				      */
     33/* ------------------------------------------------------------------ */
     34/* This module comprises the routines for decimal128 format numbers.  */
     35/* Conversions are supplied to and from decNumber and String.	      */
     36/*								      */
     37/* This is used when decNumber provides operations, either for all    */
     38/* operations or as a proxy between decNumber and decSingle.	      */
     39/*								      */
     40/* Error handling is the same as decNumber (qv.).		      */
     41/* ------------------------------------------------------------------ */
     42#include "qemu/osdep.h"
     43
     44#include "libdecnumber/dconfig.h"
     45#define	 DECNUMDIGITS 34      /* make decNumbers with space for 34 */
     46#include "libdecnumber/decNumber.h"
     47#include "libdecnumber/decNumberLocal.h"
     48#include "libdecnumber/dpd/decimal128.h"
     49
     50/* Utility routines and tables [in decimal64.c] */
     51extern const uInt   COMBEXP[32], COMBMSD[32];
     52extern const uByte  BIN2CHAR[4001];
     53
     54extern void decDigitsFromDPD(decNumber *, const uInt *, Int);
     55extern void decDigitsToDPD(const decNumber *, uInt *, Int);
     56
     57#if DECTRACE || DECCHECK
     58void decimal128Show(const decimal128 *);	  /* for debug */
     59extern void decNumberShow(const decNumber *);	  /* .. */
     60#endif
     61
     62/* Useful macro */
     63/* Clear a structure (e.g., a decNumber) */
     64#define DEC_clear(d) memset(d, 0, sizeof(*d))
     65
     66/* ------------------------------------------------------------------ */
     67/* decimal128FromNumber -- convert decNumber to decimal128	      */
     68/*								      */
     69/*   ds is the target decimal128				      */
     70/*   dn is the source number (assumed valid)			      */
     71/*   set is the context, used only for reporting errors		      */
     72/*								      */
     73/* The set argument is used only for status reporting and for the     */
     74/* rounding mode (used if the coefficient is more than DECIMAL128_Pmax*/
     75/* digits or an overflow is detected).	If the exponent is out of the */
     76/* valid range then Overflow or Underflow will be raised.	      */
     77/* After Underflow a subnormal result is possible.		      */
     78/*								      */
     79/* DEC_Clamped is set if the number has to be 'folded down' to fit,   */
     80/* by reducing its exponent and multiplying the coefficient by a      */
     81/* power of ten, or if the exponent on a zero had to be clamped.      */
     82/* ------------------------------------------------------------------ */
     83decimal128 * decimal128FromNumber(decimal128 *d128, const decNumber *dn,
     84				  decContext *set) {
     85  uInt status=0;		   /* status accumulator */
     86  Int ae;			   /* adjusted exponent */
     87  decNumber  dw;		   /* work */
     88  decContext dc;		   /* .. */
     89  uInt *pu;			   /* .. */
     90  uInt comb, exp;		   /* .. */
     91  uInt targar[4]={0,0,0,0};	   /* target 128-bit */
     92  #define targhi targar[3]	   /* name the word with the sign */
     93  #define targmh targar[2]	   /* name the words */
     94  #define targml targar[1]	   /* .. */
     95  #define targlo targar[0]	   /* .. */
     96
     97  /* If the number has too many digits, or the exponent could be */
     98  /* out of range then reduce the number under the appropriate */
     99  /* constraints.  This could push the number to Infinity or zero, */
    100  /* so this check and rounding must be done before generating the */
    101  /* decimal128] */
    102  ae=dn->exponent+dn->digits-1;		     /* [0 if special] */
    103  if (dn->digits>DECIMAL128_Pmax	     /* too many digits */
    104   || ae>DECIMAL128_Emax		     /* likely overflow */
    105   || ae<DECIMAL128_Emin) {		     /* likely underflow */
    106    decContextDefault(&dc, DEC_INIT_DECIMAL128); /* [no traps] */
    107    dc.round=set->round;		     /* use supplied rounding */
    108    decNumberPlus(&dw, dn, &dc);	     /* (round and check) */
    109    /* [this changes -0 to 0, so enforce the sign...] */
    110    dw.bits|=dn->bits&DECNEG;
    111    status=dc.status;			     /* save status */
    112    dn=&dw;				     /* use the work number */
    113    } /* maybe out of range */
    114
    115  if (dn->bits&DECSPECIAL) {			  /* a special value */
    116    if (dn->bits&DECINF) targhi=DECIMAL_Inf<<24;
    117     else {					  /* sNaN or qNaN */
    118      if ((*dn->lsu!=0 || dn->digits>1)		  /* non-zero coefficient */
    119       && (dn->digits<DECIMAL128_Pmax)) {	  /* coefficient fits */
    120	decDigitsToDPD(dn, targar, 0);
    121	}
    122      if (dn->bits&DECNAN) targhi|=DECIMAL_NaN<<24;
    123       else targhi|=DECIMAL_sNaN<<24;
    124      } /* a NaN */
    125    } /* special */
    126
    127   else { /* is finite */
    128    if (decNumberIsZero(dn)) {		     /* is a zero */
    129      /* set and clamp exponent */
    130      if (dn->exponent<-DECIMAL128_Bias) {
    131	exp=0;				     /* low clamp */
    132	status|=DEC_Clamped;
    133	}
    134       else {
    135	exp=dn->exponent+DECIMAL128_Bias;    /* bias exponent */
    136	if (exp>DECIMAL128_Ehigh) {	     /* top clamp */
    137	  exp=DECIMAL128_Ehigh;
    138	  status|=DEC_Clamped;
    139	  }
    140	}
    141      comb=(exp>>9) & 0x18;		/* msd=0, exp top 2 bits .. */
    142      }
    143     else {				/* non-zero finite number */
    144      uInt msd;				/* work */
    145      Int pad=0;			/* coefficient pad digits */
    146
    147      /* the dn is known to fit, but it may need to be padded */
    148      exp=(uInt)(dn->exponent+DECIMAL128_Bias);	   /* bias exponent */
    149      if (exp>DECIMAL128_Ehigh) {		   /* fold-down case */
    150	pad=exp-DECIMAL128_Ehigh;
    151	exp=DECIMAL128_Ehigh;			   /* [to maximum] */
    152	status|=DEC_Clamped;
    153	}
    154
    155      /* [fastpath for common case is not a win, here] */
    156      decDigitsToDPD(dn, targar, pad);
    157      /* save and clear the top digit */
    158      msd=targhi>>14;
    159      targhi&=0x00003fff;
    160
    161      /* create the combination field */
    162      if (msd>=8) comb=0x18 | ((exp>>11) & 0x06) | (msd & 0x01);
    163	     else comb=((exp>>9) & 0x18) | msd;
    164      }
    165    targhi|=comb<<26;		   /* add combination field .. */
    166    targhi|=(exp&0xfff)<<14;	   /* .. and exponent continuation */
    167    } /* finite */
    168
    169  if (dn->bits&DECNEG) targhi|=0x80000000; /* add sign bit */
    170
    171  /* now write to storage; this is endian */
    172  pu=(uInt *)d128->bytes;	   /* overlay */
    173  if (DECLITEND) {
    174    pu[0]=targlo;		   /* directly store the low int */
    175    pu[1]=targml;		   /* then the mid-low */
    176    pu[2]=targmh;		   /* then the mid-high */
    177    pu[3]=targhi;		   /* then the high int */
    178    }
    179   else {
    180    pu[0]=targhi;		   /* directly store the high int */
    181    pu[1]=targmh;		   /* then the mid-high */
    182    pu[2]=targml;		   /* then the mid-low */
    183    pu[3]=targlo;		   /* then the low int */
    184    }
    185
    186  if (status!=0) decContextSetStatus(set, status); /* pass on status */
    187  /* decimal128Show(d128); */
    188  return d128;
    189  } /* decimal128FromNumber */
    190
    191/* ------------------------------------------------------------------ */
    192/* decimal128ToNumber -- convert decimal128 to decNumber	      */
    193/*   d128 is the source decimal128				      */
    194/*   dn is the target number, with appropriate space		      */
    195/* No error is possible.					      */
    196/* ------------------------------------------------------------------ */
    197decNumber * decimal128ToNumber(const decimal128 *d128, decNumber *dn) {
    198  uInt msd;			   /* coefficient MSD */
    199  uInt exp;			   /* exponent top two bits */
    200  uInt comb;			   /* combination field */
    201  const uInt *pu;		   /* work */
    202  Int  need;			   /* .. */
    203  uInt sourar[4];		   /* source 128-bit */
    204  #define sourhi sourar[3]	   /* name the word with the sign */
    205  #define sourmh sourar[2]	   /* and the mid-high word */
    206  #define sourml sourar[1]	   /* and the mod-low word */
    207  #define sourlo sourar[0]	   /* and the lowest word */
    208
    209  /* load source from storage; this is endian */
    210  pu=(const uInt *)d128->bytes;	   /* overlay */
    211  if (DECLITEND) {
    212    sourlo=pu[0];		   /* directly load the low int */
    213    sourml=pu[1];		   /* then the mid-low */
    214    sourmh=pu[2];		   /* then the mid-high */
    215    sourhi=pu[3];		   /* then the high int */
    216    }
    217   else {
    218    sourhi=pu[0];		   /* directly load the high int */
    219    sourmh=pu[1];		   /* then the mid-high */
    220    sourml=pu[2];		   /* then the mid-low */
    221    sourlo=pu[3];		   /* then the low int */
    222    }
    223
    224  comb=(sourhi>>26)&0x1f;	   /* combination field */
    225
    226  decNumberZero(dn);		   /* clean number */
    227  if (sourhi&0x80000000) dn->bits=DECNEG; /* set sign if negative */
    228
    229  msd=COMBMSD[comb];		   /* decode the combination field */
    230  exp=COMBEXP[comb];		   /* .. */
    231
    232  if (exp==3) {			   /* is a special */
    233    if (msd==0) {
    234      dn->bits|=DECINF;
    235      return dn;		   /* no coefficient needed */
    236      }
    237    else if (sourhi&0x02000000) dn->bits|=DECSNAN;
    238    else dn->bits|=DECNAN;
    239    msd=0;			   /* no top digit */
    240    }
    241   else {			   /* is a finite number */
    242    dn->exponent=(exp<<12)+((sourhi>>14)&0xfff)-DECIMAL128_Bias; /* unbiased */
    243    }
    244
    245  /* get the coefficient */
    246  sourhi&=0x00003fff;		   /* clean coefficient continuation */
    247  if (msd) {			   /* non-zero msd */
    248    sourhi|=msd<<14;		   /* prefix to coefficient */
    249    need=12;			   /* process 12 declets */
    250    }
    251   else { /* msd=0 */
    252    if (sourhi) need=11;	   /* declets to process */
    253     else if (sourmh) need=10;
    254     else if (sourml) need=7;
    255     else if (sourlo) need=4;
    256     else return dn;		   /* easy: coefficient is 0 */
    257    } /*msd=0 */
    258
    259  decDigitsFromDPD(dn, sourar, need);	/* process declets */
    260  /* decNumberShow(dn); */
    261  return dn;
    262  } /* decimal128ToNumber */
    263
    264/* ------------------------------------------------------------------ */
    265/* to-scientific-string -- conversion to numeric string		      */
    266/* to-engineering-string -- conversion to numeric string	      */
    267/*								      */
    268/*   decimal128ToString(d128, string);				      */
    269/*   decimal128ToEngString(d128, string);			      */
    270/*								      */
    271/*  d128 is the decimal128 format number to convert		      */
    272/*  string is the string where the result will be laid out	      */
    273/*								      */
    274/*  string must be at least 24 characters			      */
    275/*								      */
    276/*  No error is possible, and no status can be set.		      */
    277/* ------------------------------------------------------------------ */
    278char * decimal128ToEngString(const decimal128 *d128, char *string){
    279  decNumber dn;				/* work */
    280  decimal128ToNumber(d128, &dn);
    281  decNumberToEngString(&dn, string);
    282  return string;
    283  } /* decimal128ToEngString */
    284
    285char * decimal128ToString(const decimal128 *d128, char *string){
    286  uInt msd;			   /* coefficient MSD */
    287  Int  exp;			   /* exponent top two bits or full */
    288  uInt comb;			   /* combination field */
    289  char *cstart;			   /* coefficient start */
    290  char *c;			   /* output pointer in string */
    291  const uInt *pu;		   /* work */
    292  char *s, *t;			   /* .. (source, target) */
    293  Int  dpd;			   /* .. */
    294  Int  pre, e;			   /* .. */
    295  const uByte *u;		   /* .. */
    296
    297  uInt sourar[4];		   /* source 128-bit */
    298  #define sourhi sourar[3]	   /* name the word with the sign */
    299  #define sourmh sourar[2]	   /* and the mid-high word */
    300  #define sourml sourar[1]	   /* and the mod-low word */
    301  #define sourlo sourar[0]	   /* and the lowest word */
    302
    303  /* load source from storage; this is endian */
    304  pu=(const uInt *)d128->bytes;	   /* overlay */
    305  if (DECLITEND) {
    306    sourlo=pu[0];		   /* directly load the low int */
    307    sourml=pu[1];		   /* then the mid-low */
    308    sourmh=pu[2];		   /* then the mid-high */
    309    sourhi=pu[3];		   /* then the high int */
    310    }
    311   else {
    312    sourhi=pu[0];		   /* directly load the high int */
    313    sourmh=pu[1];		   /* then the mid-high */
    314    sourml=pu[2];		   /* then the mid-low */
    315    sourlo=pu[3];		   /* then the low int */
    316    }
    317
    318  c=string;			   /* where result will go */
    319  if (((Int)sourhi)<0) *c++='-';   /* handle sign */
    320
    321  comb=(sourhi>>26)&0x1f;	   /* combination field */
    322  msd=COMBMSD[comb];		   /* decode the combination field */
    323  exp=COMBEXP[comb];		   /* .. */
    324
    325  if (exp==3) {
    326    if (msd==0) {		   /* infinity */
    327      strcpy(c,	  "Inf");
    328      strcpy(c+3, "inity");
    329      return string;		   /* easy */
    330      }
    331    if (sourhi&0x02000000) *c++='s'; /* sNaN */
    332    strcpy(c, "NaN");		   /* complete word */
    333    c+=3;			   /* step past */
    334    if (sourlo==0 && sourml==0 && sourmh==0
    335     && (sourhi&0x0003ffff)==0) return string; /* zero payload */
    336    /* otherwise drop through to add integer; set correct exp */
    337    exp=0; msd=0;		   /* setup for following code */
    338    }
    339   else exp=(exp<<12)+((sourhi>>14)&0xfff)-DECIMAL128_Bias; /* unbiased */
    340
    341  /* convert 34 digits of significand to characters */
    342  cstart=c;			   /* save start of coefficient */
    343  if (msd) *c++='0'+(char)msd;	   /* non-zero most significant digit */
    344
    345  /* Now decode the declets.  After extracting each one, it is */
    346  /* decoded to binary and then to a 4-char sequence by table lookup; */
    347  /* the 4-chars are a 1-char length (significant digits, except 000 */
    348  /* has length 0).  This allows us to left-align the first declet */
    349  /* with non-zero content, then remaining ones are full 3-char */
    350  /* length.  We use fixed-length memcpys because variable-length */
    351  /* causes a subroutine call in GCC.  (These are length 4 for speed */
    352  /* and are safe because the array has an extra terminator byte.) */
    353  #define dpd2char u=&BIN2CHAR[DPD2BIN[dpd]*4];			  \
    354		   if (c!=cstart) {memcpy(c, u+1, 4); c+=3;}	  \
    355		    else if (*u)  {memcpy(c, u+4-*u, 4); c+=*u;}
    356  dpd=(sourhi>>4)&0x3ff;		     /* declet 1 */
    357  dpd2char;
    358  dpd=((sourhi&0xf)<<6) | (sourmh>>26);	     /* declet 2 */
    359  dpd2char;
    360  dpd=(sourmh>>16)&0x3ff;		     /* declet 3 */
    361  dpd2char;
    362  dpd=(sourmh>>6)&0x3ff;		     /* declet 4 */
    363  dpd2char;
    364  dpd=((sourmh&0x3f)<<4) | (sourml>>28);     /* declet 5 */
    365  dpd2char;
    366  dpd=(sourml>>18)&0x3ff;		     /* declet 6 */
    367  dpd2char;
    368  dpd=(sourml>>8)&0x3ff;		     /* declet 7 */
    369  dpd2char;
    370  dpd=((sourml&0xff)<<2) | (sourlo>>30);     /* declet 8 */
    371  dpd2char;
    372  dpd=(sourlo>>20)&0x3ff;		     /* declet 9 */
    373  dpd2char;
    374  dpd=(sourlo>>10)&0x3ff;		     /* declet 10 */
    375  dpd2char;
    376  dpd=(sourlo)&0x3ff;			     /* declet 11 */
    377  dpd2char;
    378
    379  if (c==cstart) *c++='0';	   /* all zeros -- make 0 */
    380
    381  if (exp==0) {			   /* integer or NaN case -- easy */
    382    *c='\0';			   /* terminate */
    383    return string;
    384    }
    385
    386  /* non-0 exponent */
    387  e=0;				   /* assume no E */
    388  pre=c-cstart+exp;
    389  /* [here, pre-exp is the digits count (==1 for zero)] */
    390  if (exp>0 || pre<-5) {	   /* need exponential form */
    391    e=pre-1;			   /* calculate E value */
    392    pre=1;			   /* assume one digit before '.' */
    393    } /* exponential form */
    394
    395  /* modify the coefficient, adding 0s, '.', and E+nn as needed */
    396  s=c-1;			   /* source (LSD) */
    397  if (pre>0) {			   /* ddd.ddd (plain), perhaps with E */
    398    char *dotat=cstart+pre;
    399    if (dotat<c) {		   /* if embedded dot needed... */
    400      t=c;				/* target */
    401      for (; s>=dotat; s--, t--) *t=*s; /* open the gap; leave t at gap */
    402      *t='.';				/* insert the dot */
    403      c++;				/* length increased by one */
    404      }
    405
    406    /* finally add the E-part, if needed; it will never be 0, and has */
    407    /* a maximum length of 4 digits */
    408    if (e!=0) {
    409      *c++='E';			   /* starts with E */
    410      *c++='+';			   /* assume positive */
    411      if (e<0) {
    412	*(c-1)='-';		   /* oops, need '-' */
    413	e=-e;			   /* uInt, please */
    414	}
    415      if (e<1000) {		   /* 3 (or fewer) digits case */
    416	u=&BIN2CHAR[e*4];	   /* -> length byte */
    417	memcpy(c, u+4-*u, 4);	   /* copy fixed 4 characters [is safe] */
    418	c+=*u;			   /* bump pointer appropriately */
    419	}
    420       else {			   /* 4-digits */
    421	Int thou=((e>>3)*1049)>>17; /* e/1000 */
    422	Int rem=e-(1000*thou);	    /* e%1000 */
    423	*c++='0'+(char)thou;
    424	u=&BIN2CHAR[rem*4];	   /* -> length byte */
    425	memcpy(c, u+1, 4);	   /* copy fixed 3+1 characters [is safe] */
    426	c+=3;			   /* bump pointer, always 3 digits */
    427	}
    428      }
    429    *c='\0';			   /* add terminator */
    430    /*printf("res %s\n", string); */
    431    return string;
    432    } /* pre>0 */
    433
    434  /* -5<=pre<=0: here for plain 0.ddd or 0.000ddd forms (can never have E) */
    435  t=c+1-pre;
    436  *(t+1)='\0';				/* can add terminator now */
    437  for (; s>=cstart; s--, t--) *t=*s;	/* shift whole coefficient right */
    438  c=cstart;
    439  *c++='0';				/* always starts with 0. */
    440  *c++='.';
    441  for (; pre<0; pre++) *c++='0';	/* add any 0's after '.' */
    442  /*printf("res %s\n", string); */
    443  return string;
    444  } /* decimal128ToString */
    445
    446/* ------------------------------------------------------------------ */
    447/* to-number -- conversion from numeric string			      */
    448/*								      */
    449/*   decimal128FromString(result, string, set);			      */
    450/*								      */
    451/*  result  is the decimal128 format number which gets the result of  */
    452/*	    the conversion					      */
    453/*  *string is the character string which should contain a valid      */
    454/*	    number (which may be a special value)		      */
    455/*  set	    is the context					      */
    456/*								      */
    457/* The context is supplied to this routine is used for error handling */
    458/* (setting of status and traps) and for the rounding mode, only.     */
    459/* If an error occurs, the result will be a valid decimal128 NaN.     */
    460/* ------------------------------------------------------------------ */
    461decimal128 * decimal128FromString(decimal128 *result, const char *string,
    462				  decContext *set) {
    463  decContext dc;			     /* work */
    464  decNumber dn;				     /* .. */
    465
    466  decContextDefault(&dc, DEC_INIT_DECIMAL128); /* no traps, please */
    467  dc.round=set->round;			       /* use supplied rounding */
    468
    469  decNumberFromString(&dn, string, &dc);     /* will round if needed */
    470  decimal128FromNumber(result, &dn, &dc);
    471  if (dc.status!=0) {			     /* something happened */
    472    decContextSetStatus(set, dc.status);     /* .. pass it on */
    473    }
    474  return result;
    475  } /* decimal128FromString */
    476
    477/* ------------------------------------------------------------------ */
    478/* decimal128IsCanonical -- test whether encoding is canonical	      */
    479/*   d128 is the source decimal128				      */
    480/*   returns 1 if the encoding of d128 is canonical, 0 otherwise      */
    481/* No error is possible.					      */
    482/* ------------------------------------------------------------------ */
    483uint32_t decimal128IsCanonical(const decimal128 *d128) {
    484  decNumber dn;				/* work */
    485  decimal128 canon;			 /* .. */
    486  decContext dc;			/* .. */
    487  decContextDefault(&dc, DEC_INIT_DECIMAL128);
    488  decimal128ToNumber(d128, &dn);
    489  decimal128FromNumber(&canon, &dn, &dc);/* canon will now be canonical */
    490  return memcmp(d128, &canon, DECIMAL128_Bytes)==0;
    491  } /* decimal128IsCanonical */
    492
    493/* ------------------------------------------------------------------ */
    494/* decimal128Canonical -- copy an encoding, ensuring it is canonical  */
    495/*   d128 is the source decimal128				      */
    496/*   result is the target (may be the same decimal128)		      */
    497/*   returns result						      */
    498/* No error is possible.					      */
    499/* ------------------------------------------------------------------ */
    500decimal128 * decimal128Canonical(decimal128 *result, const decimal128 *d128) {
    501  decNumber dn;				/* work */
    502  decContext dc;			/* .. */
    503  decContextDefault(&dc, DEC_INIT_DECIMAL128);
    504  decimal128ToNumber(d128, &dn);
    505  decimal128FromNumber(result, &dn, &dc);/* result will now be canonical */
    506  return result;
    507  } /* decimal128Canonical */
    508
    509#if DECTRACE || DECCHECK
    510/* Macros for accessing decimal128 fields.  These assume the argument
    511   is a reference (pointer) to the decimal128 structure, and the
    512   decimal128 is in network byte order (big-endian) */
    513/* Get sign */
    514#define decimal128Sign(d)	((unsigned)(d)->bytes[0]>>7)
    515
    516/* Get combination field */
    517#define decimal128Comb(d)	(((d)->bytes[0] & 0x7c)>>2)
    518
    519/* Get exponent continuation [does not remove bias] */
    520#define decimal128ExpCon(d)	((((d)->bytes[0] & 0x03)<<10)	      \
    521			      | ((unsigned)(d)->bytes[1]<<2)	      \
    522			      | ((unsigned)(d)->bytes[2]>>6))
    523
    524/* Set sign [this assumes sign previously 0] */
    525#define decimal128SetSign(d, b) {				      \
    526  (d)->bytes[0]|=((unsigned)(b)<<7);}
    527
    528/* Set exponent continuation [does not apply bias] */
    529/* This assumes range has been checked and exponent previously 0; */
    530/* type of exponent must be unsigned */
    531#define decimal128SetExpCon(d, e) {				      \
    532  (d)->bytes[0]|=(uint8_t)((e)>>10);				      \
    533  (d)->bytes[1] =(uint8_t)(((e)&0x3fc)>>2);			      \
    534  (d)->bytes[2]|=(uint8_t)(((e)&0x03)<<6);}
    535
    536/* ------------------------------------------------------------------ */
    537/* decimal128Show -- display a decimal128 in hexadecimal [debug aid]  */
    538/*   d128 -- the number to show					      */
    539/* ------------------------------------------------------------------ */
    540/* Also shows sign/cob/expconfields extracted */
    541void decimal128Show(const decimal128 *d128) {
    542  char buf[DECIMAL128_Bytes*2+1];
    543  Int i, j=0;
    544
    545  if (DECLITEND) {
    546    for (i=0; i<DECIMAL128_Bytes; i++, j+=2) {
    547      sprintf(&buf[j], "%02x", d128->bytes[15-i]);
    548      }
    549    printf(" D128> %s [S:%d Cb:%02x Ec:%02x] LittleEndian\n", buf,
    550	   d128->bytes[15]>>7, (d128->bytes[15]>>2)&0x1f,
    551	   ((d128->bytes[15]&0x3)<<10)|(d128->bytes[14]<<2)|
    552	   (d128->bytes[13]>>6));
    553    }
    554   else {
    555    for (i=0; i<DECIMAL128_Bytes; i++, j+=2) {
    556      sprintf(&buf[j], "%02x", d128->bytes[i]);
    557      }
    558    printf(" D128> %s [S:%d Cb:%02x Ec:%02x] BigEndian\n", buf,
    559	   decimal128Sign(d128), decimal128Comb(d128),
    560	   decimal128ExpCon(d128));
    561    }
    562  } /* decimal128Show */
    563#endif