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

decContext.c (19796B)


      1/* Decimal context 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 Context module					      */
     33/* ------------------------------------------------------------------ */
     34/* This module comprises the routines for handling arithmetic	      */
     35/* context structures.						      */
     36/* ------------------------------------------------------------------ */
     37
     38#include "qemu/osdep.h"
     39#include "libdecnumber/dconfig.h"
     40#include "libdecnumber/decContext.h"
     41#include "libdecnumber/decNumberLocal.h"
     42
     43#if DECCHECK
     44/* compile-time endian tester [assumes sizeof(Int)>1] */
     45static	const  Int mfcone=1;		     /* constant 1 */
     46static	const  Flag *mfctop=(Flag *)&mfcone; /* -> top byte */
     47#define LITEND *mfctop		   /* named flag; 1=little-endian */
     48#endif
     49
     50/* ------------------------------------------------------------------ */
     51/* round-for-reround digits					      */
     52/* ------------------------------------------------------------------ */
     53const uByte DECSTICKYTAB[10]={1,1,2,3,4,6,6,7,8,9}; /* used if sticky */
     54
     55/* ------------------------------------------------------------------ */
     56/* Powers of ten (powers[n]==10**n, 0<=n<=9)			      */
     57/* ------------------------------------------------------------------ */
     58const uLong DECPOWERS[19] = {1, 10, 100, 1000, 10000, 100000, 1000000,
     59  10000000, 100000000, 1000000000, 10000000000ULL, 100000000000ULL,
     60  1000000000000ULL, 10000000000000ULL, 100000000000000ULL, 1000000000000000ULL,
     61  10000000000000000ULL, 100000000000000000ULL, 1000000000000000000ULL, };
     62
     63/* ------------------------------------------------------------------ */
     64/* decContextClearStatus -- clear bits in current status	      */
     65/*								      */
     66/*  context is the context structure to be queried		      */
     67/*  mask indicates the bits to be cleared (the status bit that	      */
     68/*    corresponds to each 1 bit in the mask is cleared)		      */
     69/*  returns context						      */
     70/*								      */
     71/* No error is possible.					      */
     72/* ------------------------------------------------------------------ */
     73decContext *decContextClearStatus(decContext *context, uInt mask) {
     74  context->status&=~mask;
     75  return context;
     76  } /* decContextClearStatus */
     77
     78/* ------------------------------------------------------------------ */
     79/* decContextDefault -- initialize a context structure		      */
     80/*								      */
     81/*  context is the structure to be initialized			      */
     82/*  kind selects the required set of default values, one of:	      */
     83/*	DEC_INIT_BASE	    -- select ANSI X3-274 defaults	      */
     84/*	DEC_INIT_DECIMAL32  -- select IEEE 754r defaults, 32-bit      */
     85/*	DEC_INIT_DECIMAL64  -- select IEEE 754r defaults, 64-bit      */
     86/*	DEC_INIT_DECIMAL128 -- select IEEE 754r defaults, 128-bit     */
     87/*	For any other value a valid context is returned, but with     */
     88/*	Invalid_operation set in the status field.		      */
     89/*  returns a context structure with the appropriate initial values.  */
     90/* ------------------------------------------------------------------ */
     91decContext * decContextDefault(decContext *context, Int kind) {
     92  /* set defaults... */
     93  context->digits=9;			     /* 9 digits */
     94  context->emax=DEC_MAX_EMAX;		     /* 9-digit exponents */
     95  context->emin=DEC_MIN_EMIN;		     /* .. balanced */
     96  context->round=DEC_ROUND_HALF_UP;	     /* 0.5 rises */
     97  context->traps=DEC_Errors;		     /* all but informational */
     98  context->status=0;			     /* cleared */
     99  context->clamp=0;			     /* no clamping */
    100  #if DECSUBSET
    101  context->extended=0;			     /* cleared */
    102  #endif
    103  switch (kind) {
    104    case DEC_INIT_BASE:
    105      /* [use defaults] */
    106      break;
    107    case DEC_INIT_DECIMAL32:
    108      context->digits=7;		     /* digits */
    109      context->emax=96;			     /* Emax */
    110      context->emin=-95;		     /* Emin */
    111      context->round=DEC_ROUND_HALF_EVEN;    /* 0.5 to nearest even */
    112      context->traps=0;			     /* no traps set */
    113      context->clamp=1;			     /* clamp exponents */
    114      #if DECSUBSET
    115      context->extended=1;		     /* set */
    116      #endif
    117      break;
    118    case DEC_INIT_DECIMAL64:
    119      context->digits=16;		     /* digits */
    120      context->emax=384;		     /* Emax */
    121      context->emin=-383;		     /* Emin */
    122      context->round=DEC_ROUND_HALF_EVEN;    /* 0.5 to nearest even */
    123      context->traps=0;			     /* no traps set */
    124      context->clamp=1;			     /* clamp exponents */
    125      #if DECSUBSET
    126      context->extended=1;		     /* set */
    127      #endif
    128      break;
    129    case DEC_INIT_DECIMAL128:
    130      context->digits=34;		     /* digits */
    131      context->emax=6144;		     /* Emax */
    132      context->emin=-6143;		     /* Emin */
    133      context->round=DEC_ROUND_HALF_EVEN;    /* 0.5 to nearest even */
    134      context->traps=0;			     /* no traps set */
    135      context->clamp=1;			     /* clamp exponents */
    136      #if DECSUBSET
    137      context->extended=1;		     /* set */
    138      #endif
    139      break;
    140
    141    default:				     /* invalid Kind */
    142      /* use defaults, and .. */
    143      decContextSetStatus(context, DEC_Invalid_operation); /* trap */
    144    }
    145
    146  #if DECCHECK
    147  if (LITEND!=DECLITEND) {
    148    const char *adj;
    149    if (LITEND) adj="little";
    150	   else adj="big";
    151    printf("Warning: DECLITEND is set to %d, but this computer appears to be %s-endian\n",
    152	   DECLITEND, adj);
    153    }
    154  #endif
    155  return context;} /* decContextDefault */
    156
    157/* ------------------------------------------------------------------ */
    158/* decContextGetRounding -- return current rounding mode	      */
    159/*								      */
    160/*  context is the context structure to be queried		      */
    161/*  returns the rounding mode					      */
    162/*								      */
    163/* No error is possible.					      */
    164/* ------------------------------------------------------------------ */
    165enum rounding decContextGetRounding(decContext *context) {
    166  return context->round;
    167  } /* decContextGetRounding */
    168
    169/* ------------------------------------------------------------------ */
    170/* decContextGetStatus -- return current status			      */
    171/*								      */
    172/*  context is the context structure to be queried		      */
    173/*  returns status						      */
    174/*								      */
    175/* No error is possible.					      */
    176/* ------------------------------------------------------------------ */
    177uInt decContextGetStatus(decContext *context) {
    178  return context->status;
    179  } /* decContextGetStatus */
    180
    181/* ------------------------------------------------------------------ */
    182/* decContextRestoreStatus -- restore bits in current status	      */
    183/*								      */
    184/*  context is the context structure to be updated		      */
    185/*  newstatus is the source for the bits to be restored		      */
    186/*  mask indicates the bits to be restored (the status bit that	      */
    187/*    corresponds to each 1 bit in the mask is set to the value of    */
    188/*    the corresponding bit in newstatus)			      */
    189/*  returns context						      */
    190/*								      */
    191/* No error is possible.					      */
    192/* ------------------------------------------------------------------ */
    193decContext *decContextRestoreStatus(decContext *context,
    194				    uInt newstatus, uInt mask) {
    195  context->status&=~mask;		/* clear the selected bits */
    196  context->status|=(mask&newstatus);	/* or in the new bits */
    197  return context;
    198  } /* decContextRestoreStatus */
    199
    200/* ------------------------------------------------------------------ */
    201/* decContextSaveStatus -- save bits in current status		      */
    202/*								      */
    203/*  context is the context structure to be queried		      */
    204/*  mask indicates the bits to be saved (the status bits that	      */
    205/*    correspond to each 1 bit in the mask are saved)		      */
    206/*  returns the AND of the mask and the current status		      */
    207/*								      */
    208/* No error is possible.					      */
    209/* ------------------------------------------------------------------ */
    210uInt decContextSaveStatus(decContext *context, uInt mask) {
    211  return context->status&mask;
    212  } /* decContextSaveStatus */
    213
    214/* ------------------------------------------------------------------ */
    215/* decContextSetRounding -- set current rounding mode		      */
    216/*								      */
    217/*  context is the context structure to be updated		      */
    218/*  newround is the value which will replace the current mode	      */
    219/*  returns context						      */
    220/*								      */
    221/* No error is possible.					      */
    222/* ------------------------------------------------------------------ */
    223decContext *decContextSetRounding(decContext *context,
    224				  enum rounding newround) {
    225  context->round=newround;
    226  return context;
    227  } /* decContextSetRounding */
    228
    229/* ------------------------------------------------------------------ */
    230/* decContextSetStatus -- set status and raise trap if appropriate    */
    231/*								      */
    232/*  context is the context structure to be updated		      */
    233/*  status  is the DEC_ exception code				      */
    234/*  returns the context structure				      */
    235/*								      */
    236/* Control may never return from this routine, if there is a signal   */
    237/* handler and it takes a long jump.				      */
    238/* ------------------------------------------------------------------ */
    239decContext * decContextSetStatus(decContext *context, uInt status) {
    240  context->status|=status;
    241  if (status & context->traps) raise(SIGFPE);
    242  return context;} /* decContextSetStatus */
    243
    244/* ------------------------------------------------------------------ */
    245/* decContextSetStatusFromString -- set status from a string + trap   */
    246/*								      */
    247/*  context is the context structure to be updated		      */
    248/*  string is a string exactly equal to one that might be returned    */
    249/*	      by decContextStatusToString			      */
    250/*								      */
    251/*  The status bit corresponding to the string is set, and a trap     */
    252/*  is raised if appropriate.					      */
    253/*								      */
    254/*  returns the context structure, unless the string is equal to      */
    255/*    DEC_Condition_MU or is not recognized.  In these cases NULL is  */
    256/*    returned.							      */
    257/* ------------------------------------------------------------------ */
    258decContext * decContextSetStatusFromString(decContext *context,
    259					   const char *string) {
    260  if (strcmp(string, DEC_Condition_CS)==0)
    261    return decContextSetStatus(context, DEC_Conversion_syntax);
    262  if (strcmp(string, DEC_Condition_DZ)==0)
    263    return decContextSetStatus(context, DEC_Division_by_zero);
    264  if (strcmp(string, DEC_Condition_DI)==0)
    265    return decContextSetStatus(context, DEC_Division_impossible);
    266  if (strcmp(string, DEC_Condition_DU)==0)
    267    return decContextSetStatus(context, DEC_Division_undefined);
    268  if (strcmp(string, DEC_Condition_IE)==0)
    269    return decContextSetStatus(context, DEC_Inexact);
    270  if (strcmp(string, DEC_Condition_IS)==0)
    271    return decContextSetStatus(context, DEC_Insufficient_storage);
    272  if (strcmp(string, DEC_Condition_IC)==0)
    273    return decContextSetStatus(context, DEC_Invalid_context);
    274  if (strcmp(string, DEC_Condition_IO)==0)
    275    return decContextSetStatus(context, DEC_Invalid_operation);
    276  #if DECSUBSET
    277  if (strcmp(string, DEC_Condition_LD)==0)
    278    return decContextSetStatus(context, DEC_Lost_digits);
    279  #endif
    280  if (strcmp(string, DEC_Condition_OV)==0)
    281    return decContextSetStatus(context, DEC_Overflow);
    282  if (strcmp(string, DEC_Condition_PA)==0)
    283    return decContextSetStatus(context, DEC_Clamped);
    284  if (strcmp(string, DEC_Condition_RO)==0)
    285    return decContextSetStatus(context, DEC_Rounded);
    286  if (strcmp(string, DEC_Condition_SU)==0)
    287    return decContextSetStatus(context, DEC_Subnormal);
    288  if (strcmp(string, DEC_Condition_UN)==0)
    289    return decContextSetStatus(context, DEC_Underflow);
    290  if (strcmp(string, DEC_Condition_ZE)==0)
    291    return context;
    292  return NULL;	/* Multiple status, or unknown */
    293  } /* decContextSetStatusFromString */
    294
    295/* ------------------------------------------------------------------ */
    296/* decContextSetStatusFromStringQuiet -- set status from a string     */
    297/*								      */
    298/*  context is the context structure to be updated		      */
    299/*  string is a string exactly equal to one that might be returned    */
    300/*	      by decContextStatusToString			      */
    301/*								      */
    302/*  The status bit corresponding to the string is set; no trap is     */
    303/*  raised.							      */
    304/*								      */
    305/*  returns the context structure, unless the string is equal to      */
    306/*    DEC_Condition_MU or is not recognized.  In these cases NULL is  */
    307/*    returned.							      */
    308/* ------------------------------------------------------------------ */
    309decContext * decContextSetStatusFromStringQuiet(decContext *context,
    310						const char *string) {
    311  if (strcmp(string, DEC_Condition_CS)==0)
    312    return decContextSetStatusQuiet(context, DEC_Conversion_syntax);
    313  if (strcmp(string, DEC_Condition_DZ)==0)
    314    return decContextSetStatusQuiet(context, DEC_Division_by_zero);
    315  if (strcmp(string, DEC_Condition_DI)==0)
    316    return decContextSetStatusQuiet(context, DEC_Division_impossible);
    317  if (strcmp(string, DEC_Condition_DU)==0)
    318    return decContextSetStatusQuiet(context, DEC_Division_undefined);
    319  if (strcmp(string, DEC_Condition_IE)==0)
    320    return decContextSetStatusQuiet(context, DEC_Inexact);
    321  if (strcmp(string, DEC_Condition_IS)==0)
    322    return decContextSetStatusQuiet(context, DEC_Insufficient_storage);
    323  if (strcmp(string, DEC_Condition_IC)==0)
    324    return decContextSetStatusQuiet(context, DEC_Invalid_context);
    325  if (strcmp(string, DEC_Condition_IO)==0)
    326    return decContextSetStatusQuiet(context, DEC_Invalid_operation);
    327  #if DECSUBSET
    328  if (strcmp(string, DEC_Condition_LD)==0)
    329    return decContextSetStatusQuiet(context, DEC_Lost_digits);
    330  #endif
    331  if (strcmp(string, DEC_Condition_OV)==0)
    332    return decContextSetStatusQuiet(context, DEC_Overflow);
    333  if (strcmp(string, DEC_Condition_PA)==0)
    334    return decContextSetStatusQuiet(context, DEC_Clamped);
    335  if (strcmp(string, DEC_Condition_RO)==0)
    336    return decContextSetStatusQuiet(context, DEC_Rounded);
    337  if (strcmp(string, DEC_Condition_SU)==0)
    338    return decContextSetStatusQuiet(context, DEC_Subnormal);
    339  if (strcmp(string, DEC_Condition_UN)==0)
    340    return decContextSetStatusQuiet(context, DEC_Underflow);
    341  if (strcmp(string, DEC_Condition_ZE)==0)
    342    return context;
    343  return NULL;	/* Multiple status, or unknown */
    344  } /* decContextSetStatusFromStringQuiet */
    345
    346/* ------------------------------------------------------------------ */
    347/* decContextSetStatusQuiet -- set status without trap		      */
    348/*								      */
    349/*  context is the context structure to be updated		      */
    350/*  status  is the DEC_ exception code				      */
    351/*  returns the context structure				      */
    352/*								      */
    353/* No error is possible.					      */
    354/* ------------------------------------------------------------------ */
    355decContext * decContextSetStatusQuiet(decContext *context, uInt status) {
    356  context->status|=status;
    357  return context;} /* decContextSetStatusQuiet */
    358
    359/* ------------------------------------------------------------------ */
    360/* decContextStatusToString -- convert status flags to a string	      */
    361/*								      */
    362/*  context is a context with valid status field		      */
    363/*								      */
    364/*  returns a constant string describing the condition.	 If multiple  */
    365/*    (or no) flags are set, a generic constant message is returned.  */
    366/* ------------------------------------------------------------------ */
    367const char *decContextStatusToString(const decContext *context) {
    368  Int status=context->status;
    369
    370  /* test the five IEEE first, as some of the others are ambiguous when */
    371  /* DECEXTFLAG=0 */
    372  if (status==DEC_Invalid_operation    ) return DEC_Condition_IO;
    373  if (status==DEC_Division_by_zero     ) return DEC_Condition_DZ;
    374  if (status==DEC_Overflow	       ) return DEC_Condition_OV;
    375  if (status==DEC_Underflow	       ) return DEC_Condition_UN;
    376  if (status==DEC_Inexact	       ) return DEC_Condition_IE;
    377
    378  if (status==DEC_Division_impossible  ) return DEC_Condition_DI;
    379  if (status==DEC_Division_undefined   ) return DEC_Condition_DU;
    380  if (status==DEC_Rounded	       ) return DEC_Condition_RO;
    381  if (status==DEC_Clamped	       ) return DEC_Condition_PA;
    382  if (status==DEC_Subnormal	       ) return DEC_Condition_SU;
    383  if (status==DEC_Conversion_syntax    ) return DEC_Condition_CS;
    384  if (status==DEC_Insufficient_storage ) return DEC_Condition_IS;
    385  if (status==DEC_Invalid_context      ) return DEC_Condition_IC;
    386  #if DECSUBSET
    387  if (status==DEC_Lost_digits	       ) return DEC_Condition_LD;
    388  #endif
    389  if (status==0			       ) return DEC_Condition_ZE;
    390  return DEC_Condition_MU;  /* Multiple errors */
    391  } /* decContextStatusToString */
    392
    393/* ------------------------------------------------------------------ */
    394/* decContextTestSavedStatus -- test bits in saved status	      */
    395/*								      */
    396/*  oldstatus is the status word to be tested			      */
    397/*  mask indicates the bits to be tested (the oldstatus bits that     */
    398/*    correspond to each 1 bit in the mask are tested)		      */
    399/*  returns 1 if any of the tested bits are 1, or 0 otherwise	      */
    400/*								      */
    401/* No error is possible.					      */
    402/* ------------------------------------------------------------------ */
    403uInt decContextTestSavedStatus(uInt oldstatus, uInt mask) {
    404  return (oldstatus&mask)!=0;
    405  } /* decContextTestSavedStatus */
    406
    407/* ------------------------------------------------------------------ */
    408/* decContextTestStatus -- test bits in current status		      */
    409/*								      */
    410/*  context is the context structure to be updated		      */
    411/*  mask indicates the bits to be tested (the status bits that	      */
    412/*    correspond to each 1 bit in the mask are tested)		      */
    413/*  returns 1 if any of the tested bits are 1, or 0 otherwise	      */
    414/*								      */
    415/* No error is possible.					      */
    416/* ------------------------------------------------------------------ */
    417uInt decContextTestStatus(decContext *context, uInt mask) {
    418  return (context->status&mask)!=0;
    419  } /* decContextTestStatus */
    420
    421/* ------------------------------------------------------------------ */
    422/* decContextZeroStatus -- clear all status bits		      */
    423/*								      */
    424/*  context is the context structure to be updated		      */
    425/*  returns context						      */
    426/*								      */
    427/* No error is possible.					      */
    428/* ------------------------------------------------------------------ */
    429decContext *decContextZeroStatus(decContext *context) {
    430  context->status=0;
    431  return context;
    432  } /* decContextZeroStatus */