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

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

DEFINITIONS

This source file includes following definitions.
  1. ieee754sp_mul

   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_mul(union ieee754sp x, union ieee754sp y)
  13 {
  14         int re;
  15         int rs;
  16         unsigned int rm;
  17         unsigned short lxm;
  18         unsigned short hxm;
  19         unsigned short lym;
  20         unsigned short hym;
  21         unsigned int lrm;
  22         unsigned int hrm;
  23         unsigned int t;
  24         unsigned int at;
  25 
  26         COMPXSP;
  27         COMPYSP;
  28 
  29         EXPLODEXSP;
  30         EXPLODEYSP;
  31 
  32         ieee754_clearcx();
  33 
  34         FLUSHXSP;
  35         FLUSHYSP;
  36 
  37         switch (CLPAIR(xc, yc)) {
  38         case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
  39         case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
  40         case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
  41         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
  42         case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
  43                 return ieee754sp_nanxcpt(y);
  44 
  45         case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
  46         case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
  47         case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
  48         case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
  49         case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
  50         case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
  51                 return ieee754sp_nanxcpt(x);
  52 
  53         case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
  54         case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
  55         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
  56         case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
  57                 return y;
  58 
  59         case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
  60         case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
  61         case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
  62         case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
  63         case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
  64                 return x;
  65 
  66 
  67         /*
  68          * Infinity handling
  69          */
  70         case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
  71         case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
  72                 ieee754_setcx(IEEE754_INVALID_OPERATION);
  73                 return ieee754sp_indef();
  74 
  75         case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
  76         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
  77         case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
  78         case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
  79         case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
  80                 return ieee754sp_inf(xs ^ ys);
  81 
  82         case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
  83         case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
  84         case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
  85         case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
  86         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
  87                 return ieee754sp_zero(xs ^ ys);
  88 
  89 
  90         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
  91                 SPDNORMX;
  92                 /* fall through */
  93 
  94         case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
  95                 SPDNORMY;
  96                 break;
  97 
  98         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
  99                 SPDNORMX;
 100                 break;
 101 
 102         case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
 103                 break;
 104         }
 105         /* rm = xm * ym, re = xe+ye basically */
 106         assert(xm & SP_HIDDEN_BIT);
 107         assert(ym & SP_HIDDEN_BIT);
 108 
 109         re = xe + ye;
 110         rs = xs ^ ys;
 111 
 112         /* shunt to top of word */
 113         xm <<= 32 - (SP_FBITS + 1);
 114         ym <<= 32 - (SP_FBITS + 1);
 115 
 116         /*
 117          * Multiply 32 bits xm, ym to give high 32 bits rm with stickness.
 118          */
 119         lxm = xm & 0xffff;
 120         hxm = xm >> 16;
 121         lym = ym & 0xffff;
 122         hym = ym >> 16;
 123 
 124         lrm = lxm * lym;        /* 16 * 16 => 32 */
 125         hrm = hxm * hym;        /* 16 * 16 => 32 */
 126 
 127         t = lxm * hym; /* 16 * 16 => 32 */
 128         at = lrm + (t << 16);
 129         hrm += at < lrm;
 130         lrm = at;
 131         hrm = hrm + (t >> 16);
 132 
 133         t = hxm * lym; /* 16 * 16 => 32 */
 134         at = lrm + (t << 16);
 135         hrm += at < lrm;
 136         lrm = at;
 137         hrm = hrm + (t >> 16);
 138 
 139         rm = hrm | (lrm != 0);
 140 
 141         /*
 142          * Sticky shift down to normal rounding precision.
 143          */
 144         if ((int) rm < 0) {
 145                 rm = (rm >> (32 - (SP_FBITS + 1 + 3))) |
 146                     ((rm << (SP_FBITS + 1 + 3)) != 0);
 147                 re++;
 148         } else {
 149                 rm = (rm >> (32 - (SP_FBITS + 1 + 3 + 1))) |
 150                      ((rm << (SP_FBITS + 1 + 3 + 1)) != 0);
 151         }
 152         assert(rm & (SP_HIDDEN_BIT << 3));
 153 
 154         return ieee754sp_format(rs, re, rm);
 155 }

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