fpu.h 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef __ASM_ALPHA_FPU_H
  3. #define __ASM_ALPHA_FPU_H
  4. #include <asm/special_insns.h>
  5. #include <uapi/asm/fpu.h>
  6. /* The following two functions don't need trapb/excb instructions
  7. around the mf_fpcr/mt_fpcr instructions because (a) the kernel
  8. never generates arithmetic faults and (b) call_pal instructions
  9. are implied trap barriers. */
  10. static inline unsigned long
  11. rdfpcr(void)
  12. {
  13. unsigned long tmp, ret;
  14. preempt_disable();
  15. if (current_thread_info()->status & TS_SAVED_FP) {
  16. ret = current_thread_info()->fp[31];
  17. } else {
  18. #if defined(CONFIG_ALPHA_EV6) || defined(CONFIG_ALPHA_EV67)
  19. __asm__ __volatile__ (
  20. "ftoit $f0,%0\n\t"
  21. "mf_fpcr $f0\n\t"
  22. "ftoit $f0,%1\n\t"
  23. "itoft %0,$f0"
  24. : "=r"(tmp), "=r"(ret));
  25. #else
  26. __asm__ __volatile__ (
  27. "stt $f0,%0\n\t"
  28. "mf_fpcr $f0\n\t"
  29. "stt $f0,%1\n\t"
  30. "ldt $f0,%0"
  31. : "=m"(tmp), "=m"(ret));
  32. #endif
  33. }
  34. preempt_enable();
  35. return ret;
  36. }
  37. static inline void
  38. wrfpcr(unsigned long val)
  39. {
  40. unsigned long tmp;
  41. preempt_disable();
  42. if (current_thread_info()->status & TS_SAVED_FP) {
  43. current_thread_info()->status |= TS_RESTORE_FP;
  44. current_thread_info()->fp[31] = val;
  45. } else {
  46. #if defined(CONFIG_ALPHA_EV6) || defined(CONFIG_ALPHA_EV67)
  47. __asm__ __volatile__ (
  48. "ftoit $f0,%0\n\t"
  49. "itoft %1,$f0\n\t"
  50. "mt_fpcr $f0\n\t"
  51. "itoft %0,$f0"
  52. : "=&r"(tmp) : "r"(val));
  53. #else
  54. __asm__ __volatile__ (
  55. "stt $f0,%0\n\t"
  56. "ldt $f0,%1\n\t"
  57. "mt_fpcr $f0\n\t"
  58. "ldt $f0,%0"
  59. : "=m"(tmp) : "m"(val));
  60. #endif
  61. }
  62. preempt_enable();
  63. }
  64. static inline unsigned long
  65. swcr_update_status(unsigned long swcr, unsigned long fpcr)
  66. {
  67. /* EV6 implements most of the bits in hardware. Collect
  68. the acrued exception bits from the real fpcr. */
  69. if (implver() == IMPLVER_EV6) {
  70. swcr &= ~IEEE_STATUS_MASK;
  71. swcr |= (fpcr >> 35) & IEEE_STATUS_MASK;
  72. }
  73. return swcr;
  74. }
  75. extern unsigned long alpha_read_fp_reg (unsigned long reg);
  76. extern void alpha_write_fp_reg (unsigned long reg, unsigned long val);
  77. extern unsigned long alpha_read_fp_reg_s (unsigned long reg);
  78. extern void alpha_write_fp_reg_s (unsigned long reg, unsigned long val);
  79. #endif /* __ASM_ALPHA_FPU_H */