root/arch/mips/math-emu/dp_add.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ieee754dp_add

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /* IEEE754 floating point arithmetic
   3  * double precision: common utilities
   4  */
   5 /*
   6  * MIPS floating point support
   7  * Copyright (C) 1994-2000 Algorithmics Ltd.
   8  */
   9 
  10 #include "ieee754dp.h"
  11 
  12 union ieee754dp ieee754dp_add(union ieee754dp x, union ieee754dp y)
  13 {
  14         int s;
  15 
  16         COMPXDP;
  17         COMPYDP;
  18 
  19         EXPLODEXDP;
  20         EXPLODEYDP;
  21 
  22         ieee754_clearcx();
  23 
  24         FLUSHXDP;
  25         FLUSHYDP;
  26 
  27         switch (CLPAIR(xc, yc)) {
  28         case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
  29         case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
  30         case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
  31         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
  32         case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
  33                 return ieee754dp_nanxcpt(y);
  34 
  35         case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
  36         case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
  37         case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
  38         case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
  39         case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
  40         case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
  41                 return ieee754dp_nanxcpt(x);
  42 
  43         case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
  44         case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
  45         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
  46         case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
  47                 return y;
  48 
  49         case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
  50         case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
  51         case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
  52         case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
  53         case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
  54                 return x;
  55 
  56 
  57         /*
  58          * Infinity handling
  59          */
  60         case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
  61                 if (xs == ys)
  62                         return x;
  63                 ieee754_setcx(IEEE754_INVALID_OPERATION);
  64                 return ieee754dp_indef();
  65 
  66         case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
  67         case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
  68         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
  69                 return y;
  70 
  71         case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
  72         case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
  73         case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
  74                 return x;
  75 
  76         /*
  77          * Zero handling
  78          */
  79         case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
  80                 if (xs == ys)
  81                         return x;
  82                 else
  83                         return ieee754dp_zero(ieee754_csr.rm == FPU_CSR_RD);
  84 
  85         case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
  86         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
  87                 return x;
  88 
  89         case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
  90         case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
  91                 return y;
  92 
  93         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
  94                 DPDNORMX;
  95                 /* fall through */
  96 
  97         case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
  98                 DPDNORMY;
  99                 break;
 100 
 101         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
 102                 DPDNORMX;
 103                 break;
 104 
 105         case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
 106                 break;
 107         }
 108         assert(xm & DP_HIDDEN_BIT);
 109         assert(ym & DP_HIDDEN_BIT);
 110 
 111         /*
 112          * Provide guard,round and stick bit space.
 113          */
 114         xm <<= 3;
 115         ym <<= 3;
 116 
 117         if (xe > ye) {
 118                 /*
 119                  * Have to shift y fraction right to align.
 120                  */
 121                 s = xe - ye;
 122                 ym = XDPSRS(ym, s);
 123                 ye += s;
 124         } else if (ye > xe) {
 125                 /*
 126                  * Have to shift x fraction right to align.
 127                  */
 128                 s = ye - xe;
 129                 xm = XDPSRS(xm, s);
 130                 xe += s;
 131         }
 132         assert(xe == ye);
 133         assert(xe <= DP_EMAX);
 134 
 135         if (xs == ys) {
 136                 /*
 137                  * Generate 28 bit result of adding two 27 bit numbers
 138                  * leaving result in xm, xs and xe.
 139                  */
 140                 xm = xm + ym;
 141 
 142                 if (xm >> (DP_FBITS + 1 + 3)) { /* carry out */
 143                         xm = XDPSRS1(xm);
 144                         xe++;
 145                 }
 146         } else {
 147                 if (xm >= ym) {
 148                         xm = xm - ym;
 149                 } else {
 150                         xm = ym - xm;
 151                         xs = ys;
 152                 }
 153                 if (xm == 0)
 154                         return ieee754dp_zero(ieee754_csr.rm == FPU_CSR_RD);
 155 
 156                 /*
 157                  * Normalize to rounding precision.
 158                  */
 159                 while ((xm >> (DP_FBITS + 3)) == 0) {
 160                         xm <<= 1;
 161                         xe--;
 162                 }
 163         }
 164 
 165         return ieee754dp_format(xs, xe, xm);
 166 }

/* [<][>][^][v][top][bottom][index][help] */