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

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

DEFINITIONS

This source file includes following definitions.
  1. ieee754sp_sub

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /* IEEE754 floating point arithmetic
   3  * single precision
   4  */
   5 /*
   6  * MIPS floating point support
   7  * Copyright (C) 1994-2000 Algorithmics Ltd.
   8  */
   9 
  10 #include "ieee754sp.h"
  11 
  12 union ieee754sp ieee754sp_sub(union ieee754sp x, union ieee754sp y)
  13 {
  14         int s;
  15 
  16         COMPXSP;
  17         COMPYSP;
  18 
  19         EXPLODEXSP;
  20         EXPLODEYSP;
  21 
  22         ieee754_clearcx();
  23 
  24         FLUSHXSP;
  25         FLUSHYSP;
  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 ieee754sp_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 ieee754sp_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 ieee754sp_indef();
  65 
  66         case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
  67         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
  68         case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
  69                 return ieee754sp_inf(ys ^ 1);
  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 ieee754sp_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                 /* quick fix up */
  92                 SPSIGN(y) ^= 1;
  93                 return y;
  94 
  95         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
  96                 SPDNORMX;
  97                 /* fall through */
  98 
  99         case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
 100                 SPDNORMY;
 101                 break;
 102 
 103         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
 104                 SPDNORMX;
 105                 break;
 106 
 107         case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
 108                 break;
 109         }
 110         /* flip sign of y and handle as add */
 111         ys ^= 1;
 112 
 113         assert(xm & SP_HIDDEN_BIT);
 114         assert(ym & SP_HIDDEN_BIT);
 115 
 116 
 117         /* provide guard,round and stick bit space */
 118         xm <<= 3;
 119         ym <<= 3;
 120 
 121         if (xe > ye) {
 122                 /*
 123                  * have to shift y fraction right to align
 124                  */
 125                 s = xe - ye;
 126                 ym = XSPSRS(ym, s);
 127                 ye += s;
 128         } else if (ye > xe) {
 129                 /*
 130                  * have to shift x fraction right to align
 131                  */
 132                 s = ye - xe;
 133                 xm = XSPSRS(xm, s);
 134                 xe += s;
 135         }
 136         assert(xe == ye);
 137         assert(xe <= SP_EMAX);
 138 
 139         if (xs == ys) {
 140                 /* generate 28 bit result of adding two 27 bit numbers
 141                  */
 142                 xm = xm + ym;
 143 
 144                 if (xm >> (SP_FBITS + 1 + 3)) { /* carry out */
 145                         SPXSRSX1();     /* shift preserving sticky */
 146                 }
 147         } else {
 148                 if (xm >= ym) {
 149                         xm = xm - ym;
 150                 } else {
 151                         xm = ym - xm;
 152                         xs = ys;
 153                 }
 154                 if (xm == 0) {
 155                         if (ieee754_csr.rm == FPU_CSR_RD)
 156                                 return ieee754sp_zero(1);       /* round negative inf. => sign = -1 */
 157                         else
 158                                 return ieee754sp_zero(0);       /* other round modes   => sign = 1 */
 159                 }
 160                 /* normalize to rounding precision
 161                  */
 162                 while ((xm >> (SP_FBITS + 3)) == 0) {
 163                         xm <<= 1;
 164                         xe--;
 165                 }
 166         }
 167 
 168         return ieee754sp_format(xs, xe, xm);
 169 }

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