The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/powerpc/fpu/fpu_subr.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: fpu_subr.c,v 1.4 2005/12/11 12:18:42 christos Exp $ */
    2 
    3 /*
    4  * SPDX-License-Identifier: BSD-3-Clause
    5  *
    6  * Copyright (c) 1992, 1993
    7  *      The Regents of the University of California.  All rights reserved.
    8  *
    9  * This software was developed by the Computer Systems Engineering group
   10  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
   11  * contributed to Berkeley.
   12  *
   13  * All advertising materials mentioning features or use of this software
   14  * must display the following acknowledgement:
   15  *      This product includes software developed by the University of
   16  *      California, Lawrence Berkeley Laboratory.
   17  *
   18  * Redistribution and use in source and binary forms, with or without
   19  * modification, are permitted provided that the following conditions
   20  * are met:
   21  * 1. Redistributions of source code must retain the above copyright
   22  *    notice, this list of conditions and the following disclaimer.
   23  * 2. Redistributions in binary form must reproduce the above copyright
   24  *    notice, this list of conditions and the following disclaimer in the
   25  *    documentation and/or other materials provided with the distribution.
   26  * 3. Neither the name of the University nor the names of its contributors
   27  *    may be used to endorse or promote products derived from this software
   28  *    without specific prior written permission.
   29  *
   30  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   31  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   32  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   33  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   34  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   35  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   36  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   37  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   38  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   39  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   40  * SUCH DAMAGE.
   41  *
   42  *      @(#)fpu_subr.c  8.1 (Berkeley) 6/11/93
   43  */
   44 
   45 /*
   46  * FPU subroutines.
   47  */
   48 
   49 #include <sys/cdefs.h>
   50 __FBSDID("$FreeBSD$");
   51 
   52 #include <sys/types.h>
   53 #include <sys/systm.h>
   54 
   55 #include <machine/fpu.h>
   56 
   57 #include <powerpc/fpu/fpu_arith.h>
   58 #include <powerpc/fpu/fpu_emu.h>
   59 
   60 /*
   61  * Shift the given number right rsh bits.  Any bits that `fall off' will get
   62  * shoved into the sticky field; we return the resulting sticky.  Note that
   63  * shifting NaNs is legal (this will never shift all bits out); a NaN's
   64  * sticky field is ignored anyway.
   65  */
   66 int
   67 fpu_shr(struct fpn *fp, int rsh)
   68 {
   69         u_int m0, m1, m2, m3, s;
   70         int lsh;
   71 
   72 #ifdef DIAGNOSTIC
   73         if (rsh <= 0 || (fp->fp_class != FPC_NUM && !ISNAN(fp)))
   74                 panic("fpu_rightshift 1");
   75 #endif
   76 
   77         m0 = fp->fp_mant[0];
   78         m1 = fp->fp_mant[1];
   79         m2 = fp->fp_mant[2];
   80         m3 = fp->fp_mant[3];
   81 
   82         /* If shifting all the bits out, take a shortcut. */
   83         if (rsh >= FP_NMANT) {
   84 #ifdef DIAGNOSTIC
   85                 if ((m0 | m1 | m2 | m3) == 0)
   86                         panic("fpu_rightshift 2");
   87 #endif
   88                 fp->fp_mant[0] = 0;
   89                 fp->fp_mant[1] = 0;
   90                 fp->fp_mant[2] = 0;
   91                 fp->fp_mant[3] = 0;
   92 #ifdef notdef
   93                 if ((m0 | m1 | m2 | m3) == 0)
   94                         fp->fp_class = FPC_ZERO;
   95                 else
   96 #endif
   97                         fp->fp_sticky = 1;
   98                 return (1);
   99         }
  100 
  101         /* Squish out full words. */
  102         s = fp->fp_sticky;
  103         if (rsh >= 32 * 3) {
  104                 s |= m3 | m2 | m1;
  105                 m3 = m0, m2 = 0, m1 = 0, m0 = 0;
  106         } else if (rsh >= 32 * 2) {
  107                 s |= m3 | m2;
  108                 m3 = m1, m2 = m0, m1 = 0, m0 = 0;
  109         } else if (rsh >= 32) {
  110                 s |= m3;
  111                 m3 = m2, m2 = m1, m1 = m0, m0 = 0;
  112         }
  113 
  114         /* Handle any remaining partial word. */
  115         if ((rsh &= 31) != 0) {
  116                 lsh = 32 - rsh;
  117                 s |= m3 << lsh;
  118                 m3 = (m3 >> rsh) | (m2 << lsh);
  119                 m2 = (m2 >> rsh) | (m1 << lsh);
  120                 m1 = (m1 >> rsh) | (m0 << lsh);
  121                 m0 >>= rsh;
  122         }
  123         fp->fp_mant[0] = m0;
  124         fp->fp_mant[1] = m1;
  125         fp->fp_mant[2] = m2;
  126         fp->fp_mant[3] = m3;
  127         fp->fp_sticky = s;
  128         return (s);
  129 }
  130 
  131 /*
  132  * Force a number to be normal, i.e., make its fraction have all zero
  133  * bits before FP_1, then FP_1, then all 1 bits.  This is used for denorms
  134  * and (sometimes) for intermediate results.
  135  *
  136  * Internally, this may use a `supernormal' -- a number whose fp_mant
  137  * is greater than or equal to 2.0 -- so as a side effect you can hand it
  138  * a supernormal and it will fix it (provided fp->fp_mant[3] == 0).
  139  */
  140 void
  141 fpu_norm(struct fpn *fp)
  142 {
  143         u_int m0, m1, m2, m3, top, sup, nrm;
  144         int lsh, rsh, exp;
  145 
  146         exp = fp->fp_exp;
  147         m0 = fp->fp_mant[0];
  148         m1 = fp->fp_mant[1];
  149         m2 = fp->fp_mant[2];
  150         m3 = fp->fp_mant[3];
  151 
  152         /* Handle severe subnormals with 32-bit moves. */
  153         if (m0 == 0) {
  154                 if (m1)
  155                         m0 = m1, m1 = m2, m2 = m3, m3 = 0, exp -= 32;
  156                 else if (m2)
  157                         m0 = m2, m1 = m3, m2 = 0, m3 = 0, exp -= 2 * 32;
  158                 else if (m3)
  159                         m0 = m3, m1 = 0, m2 = 0, m3 = 0, exp -= 3 * 32;
  160                 else {
  161                         fp->fp_class = FPC_ZERO;
  162                         return;
  163                 }
  164         }
  165 
  166         /* Now fix any supernormal or remaining subnormal. */
  167         nrm = FP_1;
  168         sup = nrm << 1;
  169         if (m0 >= sup) {
  170                 /*
  171                  * We have a supernormal number.  We need to shift it right.
  172                  * We may assume m3==0.
  173                  */
  174                 for (rsh = 1, top = m0 >> 1; top >= sup; rsh++) /* XXX slow */
  175                         top >>= 1;
  176                 exp += rsh;
  177                 lsh = 32 - rsh;
  178                 m3 = m2 << lsh;
  179                 m2 = (m2 >> rsh) | (m1 << lsh);
  180                 m1 = (m1 >> rsh) | (m0 << lsh);
  181                 m0 = top;
  182         } else if (m0 < nrm) {
  183                 /*
  184                  * We have a regular denorm (a subnormal number), and need
  185                  * to shift it left.
  186                  */
  187                 for (lsh = 1, top = m0 << 1; top < nrm; lsh++)  /* XXX slow */
  188                         top <<= 1;
  189                 exp -= lsh;
  190                 rsh = 32 - lsh;
  191                 m0 = top | (m1 >> rsh);
  192                 m1 = (m1 << lsh) | (m2 >> rsh);
  193                 m2 = (m2 << lsh) | (m3 >> rsh);
  194                 m3 <<= lsh;
  195         }
  196 
  197         fp->fp_exp = exp;
  198         fp->fp_mant[0] = m0;
  199         fp->fp_mant[1] = m1;
  200         fp->fp_mant[2] = m2;
  201         fp->fp_mant[3] = m3;
  202 }
  203 
  204 /*
  205  * Concoct a `fresh' Quiet NaN per Appendix N.
  206  * As a side effect, we set NV (invalid) for the current exceptions.
  207  */
  208 struct fpn *
  209 fpu_newnan(struct fpemu *fe)
  210 {
  211         struct fpn *fp;
  212 
  213         fe->fe_cx |= FPSCR_VXSNAN;
  214         fp = &fe->fe_f3;
  215         fp->fp_class = FPC_QNAN;
  216         fp->fp_sign = 0;
  217         fp->fp_mant[0] = FP_1 - 1;
  218         fp->fp_mant[1] = fp->fp_mant[2] = fp->fp_mant[3] = ~0;
  219         DUMPFPN(FPE_REG, fp);
  220         return (fp);
  221 }

Cache object: f2a8893b8d57e89501ca013ed6c29a69


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.