i387.h 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /*
  2. * include/asm-i386/i387.h
  3. *
  4. * Copyright (C) 1994 Linus Torvalds
  5. *
  6. * Pentium III FXSR, SSE support
  7. * General FPU state handling cleanups
  8. * Gareth Hughes <gareth@valinux.com>, May 2000
  9. */
  10. #ifndef __ASM_I386_I387_H
  11. #define __ASM_I386_I387_H
  12. #include <linux/sched.h>
  13. #include <linux/init.h>
  14. #include <asm/processor.h>
  15. #include <asm/sigcontext.h>
  16. #include <asm/user.h>
  17. extern void mxcsr_feature_mask_init(void);
  18. extern void init_fpu(struct task_struct *);
  19. /*
  20. * FPU lazy state save handling...
  21. */
  22. /*
  23. * The "nop" is needed to make the instructions the same
  24. * length.
  25. */
  26. #define restore_fpu(tsk) \
  27. alternative_input( \
  28. "nop ; frstor %1", \
  29. "fxrstor %1", \
  30. X86_FEATURE_FXSR, \
  31. "m" ((tsk)->thread.i387.fxsave))
  32. extern void kernel_fpu_begin(void);
  33. #define kernel_fpu_end() do { stts(); preempt_enable(); } while(0)
  34. /*
  35. * These must be called with preempt disabled
  36. */
  37. static inline void __save_init_fpu( struct task_struct *tsk )
  38. {
  39. alternative_input(
  40. "fnsave %1 ; fwait ;" GENERIC_NOP2,
  41. "fxsave %1 ; fnclex",
  42. X86_FEATURE_FXSR,
  43. "m" (tsk->thread.i387.fxsave)
  44. :"memory");
  45. task_thread_info(tsk)->status &= ~TS_USEDFPU;
  46. }
  47. #define __unlazy_fpu( tsk ) do { \
  48. if (task_thread_info(tsk)->status & TS_USEDFPU) \
  49. save_init_fpu( tsk ); \
  50. } while (0)
  51. #define __clear_fpu( tsk ) \
  52. do { \
  53. if (task_thread_info(tsk)->status & TS_USEDFPU) { \
  54. asm volatile("fnclex ; fwait"); \
  55. task_thread_info(tsk)->status &= ~TS_USEDFPU; \
  56. stts(); \
  57. } \
  58. } while (0)
  59. /*
  60. * These disable preemption on their own and are safe
  61. */
  62. static inline void save_init_fpu( struct task_struct *tsk )
  63. {
  64. preempt_disable();
  65. __save_init_fpu(tsk);
  66. stts();
  67. preempt_enable();
  68. }
  69. #define unlazy_fpu( tsk ) do { \
  70. preempt_disable(); \
  71. __unlazy_fpu(tsk); \
  72. preempt_enable(); \
  73. } while (0)
  74. #define clear_fpu( tsk ) do { \
  75. preempt_disable(); \
  76. __clear_fpu( tsk ); \
  77. preempt_enable(); \
  78. } while (0)
  79. \
  80. /*
  81. * FPU state interaction...
  82. */
  83. extern unsigned short get_fpu_cwd( struct task_struct *tsk );
  84. extern unsigned short get_fpu_swd( struct task_struct *tsk );
  85. extern unsigned short get_fpu_mxcsr( struct task_struct *tsk );
  86. /*
  87. * Signal frame handlers...
  88. */
  89. extern int save_i387( struct _fpstate __user *buf );
  90. extern int restore_i387( struct _fpstate __user *buf );
  91. /*
  92. * ptrace request handers...
  93. */
  94. extern int get_fpregs( struct user_i387_struct __user *buf,
  95. struct task_struct *tsk );
  96. extern int set_fpregs( struct task_struct *tsk,
  97. struct user_i387_struct __user *buf );
  98. extern int get_fpxregs( struct user_fxsr_struct __user *buf,
  99. struct task_struct *tsk );
  100. extern int set_fpxregs( struct task_struct *tsk,
  101. struct user_fxsr_struct __user *buf );
  102. /*
  103. * FPU state for core dumps...
  104. */
  105. extern int dump_fpu( struct pt_regs *regs,
  106. struct user_i387_struct *fpu );
  107. #endif /* __ASM_I386_I387_H */