home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6 / include / asm-alpha / fpu.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  6.1 KB  |  194 lines

  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    0xffff800000000000L
  31.  
  32. /*
  33.  * IEEE trap enables are implemented in software.  These per-thread
  34.  * bits are stored in the "ieee_state" field of "struct thread_info".
  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(CONFIG_ALPHA_EV6) || defined(CONFIG_ALPHA_EV67)
  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(CONFIG_ALPHA_EV6) || defined(CONFIG_ALPHA_EV67)
  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 */
  194.