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/include/asm-alpha/fpu.h

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 #ifndef __ASM_ALPHA_FPU_H
    2 #define __ASM_ALPHA_FPU_H
    3 
    4 /*
    5  * Alpha floating-point control register defines:
    6  */
    7 #define FPCR_DNOD       (1UL<<47)       /* denorm INV trap disable */
    8 #define FPCR_DNZ        (1UL<<48)       /* denorms to zero */
    9 #define FPCR_INVD       (1UL<<49)       /* invalid op disable (opt.) */
   10 #define FPCR_DZED       (1UL<<50)       /* division by zero disable (opt.) */
   11 #define FPCR_OVFD       (1UL<<51)       /* overflow disable (optional) */
   12 #define FPCR_INV        (1UL<<52)       /* invalid operation */
   13 #define FPCR_DZE        (1UL<<53)       /* division by zero */
   14 #define FPCR_OVF        (1UL<<54)       /* overflow */
   15 #define FPCR_UNF        (1UL<<55)       /* underflow */
   16 #define FPCR_INE        (1UL<<56)       /* inexact */
   17 #define FPCR_IOV        (1UL<<57)       /* integer overflow */
   18 #define FPCR_UNDZ       (1UL<<60)       /* underflow to zero (opt.) */
   19 #define FPCR_UNFD       (1UL<<61)       /* underflow disable (opt.) */
   20 #define FPCR_INED       (1UL<<62)       /* inexact disable (opt.) */
   21 #define FPCR_SUM        (1UL<<63)       /* summary bit */
   22 
   23 #define FPCR_DYN_SHIFT  58              /* first dynamic rounding mode bit */
   24 #define FPCR_DYN_CHOPPED (0x0UL << FPCR_DYN_SHIFT)      /* towards 0 */
   25 #define FPCR_DYN_MINUS   (0x1UL << FPCR_DYN_SHIFT)      /* towards -INF */
   26 #define FPCR_DYN_NORMAL  (0x2UL << FPCR_DYN_SHIFT)      /* towards nearest */
   27 #define FPCR_DYN_PLUS    (0x3UL << FPCR_DYN_SHIFT)      /* towards +INF */
   28 #define FPCR_DYN_MASK    (0x3UL << FPCR_DYN_SHIFT)
   29 
   30 #define FPCR_MASK       0xffff800000000000
   31 
   32 /*
   33  * IEEE trap enables are implemented in software.  These per-thread
   34  * bits are stored in the "flags" field of "struct thread_struct".
   35  * Thus, the bits are defined so as not to conflict with the
   36  * floating-point enable bit (which is architected).  On top of that,
   37  * we want to make these bits compatible with OSF/1 so
   38  * ieee_set_fp_control() etc. can be implemented easily and
   39  * compatibly.  The corresponding definitions are in
   40  * /usr/include/machine/fpu.h under OSF/1.
   41  */
   42 #define IEEE_TRAP_ENABLE_INV    (1UL<<1)        /* invalid op */
   43 #define IEEE_TRAP_ENABLE_DZE    (1UL<<2)        /* division by zero */
   44 #define IEEE_TRAP_ENABLE_OVF    (1UL<<3)        /* overflow */
   45 #define IEEE_TRAP_ENABLE_UNF    (1UL<<4)        /* underflow */
   46 #define IEEE_TRAP_ENABLE_INE    (1UL<<5)        /* inexact */
   47 #define IEEE_TRAP_ENABLE_DNO    (1UL<<6)        /* denorm */
   48 #define IEEE_TRAP_ENABLE_MASK   (IEEE_TRAP_ENABLE_INV | IEEE_TRAP_ENABLE_DZE |\
   49                                  IEEE_TRAP_ENABLE_OVF | IEEE_TRAP_ENABLE_UNF |\
   50                                  IEEE_TRAP_ENABLE_INE | IEEE_TRAP_ENABLE_DNO)
   51 
   52 /* Denorm and Underflow flushing */
   53 #define IEEE_MAP_DMZ            (1UL<<12)       /* Map denorm inputs to zero */
   54 #define IEEE_MAP_UMZ            (1UL<<13)       /* Map underflowed outputs to zero */
   55 
   56 #define IEEE_MAP_MASK           (IEEE_MAP_DMZ | IEEE_MAP_UMZ)
   57 
   58 /* status bits coming from fpcr: */
   59 #define IEEE_STATUS_INV         (1UL<<17)
   60 #define IEEE_STATUS_DZE         (1UL<<18)
   61 #define IEEE_STATUS_OVF         (1UL<<19)
   62 #define IEEE_STATUS_UNF         (1UL<<20)
   63 #define IEEE_STATUS_INE         (1UL<<21)
   64 #define IEEE_STATUS_DNO         (1UL<<22)
   65 
   66 #define IEEE_STATUS_MASK        (IEEE_STATUS_INV | IEEE_STATUS_DZE |    \
   67                                  IEEE_STATUS_OVF | IEEE_STATUS_UNF |    \
   68                                  IEEE_STATUS_INE | IEEE_STATUS_DNO)
   69 
   70 #define IEEE_SW_MASK            (IEEE_TRAP_ENABLE_MASK |                \
   71                                  IEEE_STATUS_MASK | IEEE_MAP_MASK)
   72 
   73 #define IEEE_CURRENT_RM_SHIFT   32
   74 #define IEEE_CURRENT_RM_MASK    (3UL<<IEEE_CURRENT_RM_SHIFT)
   75 
   76 #define IEEE_STATUS_TO_EXCSUM_SHIFT     16
   77 
   78 #define IEEE_INHERIT    (1UL<<63)       /* inherit on thread create? */
   79 
   80 /*
   81  * Convert the software IEEE trap enable and status bits into the
   82  * hardware fpcr format. 
   83  *
   84  * Digital Unix engineers receive my thanks for not defining the
   85  * software bits identical to the hardware bits.  The chip designers
   86  * receive my thanks for making all the not-implemented fpcr bits
   87  * RAZ forcing us to use system calls to read/write this value.
   88  */
   89 
   90 static inline unsigned long
   91 ieee_swcr_to_fpcr(unsigned long sw)
   92 {
   93         unsigned long fp;
   94         fp = (sw & IEEE_STATUS_MASK) << 35;
   95         fp |= (sw & IEEE_MAP_DMZ) << 36;
   96         fp |= (sw & IEEE_STATUS_MASK ? FPCR_SUM : 0);
   97         fp |= (~sw & (IEEE_TRAP_ENABLE_INV
   98                       | IEEE_TRAP_ENABLE_DZE
   99                       | IEEE_TRAP_ENABLE_OVF)) << 48;
  100         fp |= (~sw & (IEEE_TRAP_ENABLE_UNF | IEEE_TRAP_ENABLE_INE)) << 57;
  101         fp |= (sw & IEEE_MAP_UMZ ? FPCR_UNDZ | FPCR_UNFD : 0);
  102         fp |= (~sw & IEEE_TRAP_ENABLE_DNO) << 41;
  103         return fp;
  104 }
  105 
  106 static inline unsigned long
  107 ieee_fpcr_to_swcr(unsigned long fp)
  108 {
  109         unsigned long sw;
  110         sw = (fp >> 35) & IEEE_STATUS_MASK;
  111         sw |= (fp >> 36) & IEEE_MAP_DMZ;
  112         sw |= (~fp >> 48) & (IEEE_TRAP_ENABLE_INV
  113                              | IEEE_TRAP_ENABLE_DZE
  114                              | IEEE_TRAP_ENABLE_OVF);
  115         sw |= (~fp >> 57) & (IEEE_TRAP_ENABLE_UNF | IEEE_TRAP_ENABLE_INE);
  116         sw |= (fp >> 47) & IEEE_MAP_UMZ;
  117         sw |= (~fp >> 41) & IEEE_TRAP_ENABLE_DNO;
  118         return sw;
  119 }
  120 
  121 #ifdef __KERNEL__
  122 
  123 /* The following two functions don't need trapb/excb instructions
  124    around the mf_fpcr/mt_fpcr instructions because (a) the kernel
  125    never generates arithmetic faults and (b) call_pal instructions
  126    are implied trap barriers.  */
  127 
  128 static inline unsigned long
  129 rdfpcr(void)
  130 {
  131         unsigned long tmp, ret;
  132 
  133 #if defined(__alpha_cix__) || defined(__alpha_fix__)
  134         __asm__ __volatile__ (
  135                 "ftoit $f0,%0\n\t"
  136                 "mf_fpcr $f0\n\t"
  137                 "ftoit $f0,%1\n\t"
  138                 "itoft %0,$f0"
  139                 : "=r"(tmp), "=r"(ret));
  140 #else
  141         __asm__ __volatile__ (
  142                 "stt $f0,%0\n\t"
  143                 "mf_fpcr $f0\n\t"
  144                 "stt $f0,%1\n\t"
  145                 "ldt $f0,%0"
  146                 : "=m"(tmp), "=m"(ret));
  147 #endif
  148 
  149         return ret;
  150 }
  151 
  152 static inline void
  153 wrfpcr(unsigned long val)
  154 {
  155         unsigned long tmp;
  156 
  157 #if defined(__alpha_cix__) || defined(__alpha_fix__)
  158         __asm__ __volatile__ (
  159                 "ftoit $f0,%0\n\t"
  160                 "itoft %1,$f0\n\t"
  161                 "mt_fpcr $f0\n\t"
  162                 "itoft %0,$f0"
  163                 : "=&r"(tmp) : "r"(val));
  164 #else
  165         __asm__ __volatile__ (
  166                 "stt $f0,%0\n\t"
  167                 "ldt $f0,%1\n\t"
  168                 "mt_fpcr $f0\n\t"
  169                 "ldt $f0,%0"
  170                 : "=m"(tmp) : "m"(val));
  171 #endif
  172 }
  173 
  174 static inline unsigned long
  175 swcr_update_status(unsigned long swcr, unsigned long fpcr)
  176 {
  177         /* EV6 implements most of the bits in hardware.  Collect
  178            the acrued exception bits from the real fpcr.  */
  179         if (implver() == IMPLVER_EV6) {
  180                 swcr &= ~IEEE_STATUS_MASK;
  181                 swcr |= (fpcr >> 35) & IEEE_STATUS_MASK;
  182         }
  183         return swcr;
  184 }
  185 
  186 extern unsigned long alpha_read_fp_reg (unsigned long reg);
  187 extern void alpha_write_fp_reg (unsigned long reg, unsigned long val);
  188 extern unsigned long alpha_read_fp_reg_s (unsigned long reg);
  189 extern void alpha_write_fp_reg_s (unsigned long reg, unsigned long val);
  190 
  191 #endif /* __KERNEL__ */
  192 
  193 #endif /* __ASM_ALPHA_FPU_H */

Cache object: a85781c2c3c948029990921338400f97


[ 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.