i387.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  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. extern void restore_fpu( struct task_struct *tsk );
  23. extern void kernel_fpu_begin(void);
  24. #define kernel_fpu_end() do { stts(); preempt_enable(); } while(0)
  25. /*
  26. * These must be called with preempt disabled
  27. */
  28. static inline void __save_init_fpu( struct task_struct *tsk )
  29. {
  30. if ( cpu_has_fxsr ) {
  31. asm volatile( "fxsave %0 ; fnclex"
  32. : "=m" (tsk->thread.i387.fxsave) );
  33. } else {
  34. asm volatile( "fnsave %0 ; fwait"
  35. : "=m" (tsk->thread.i387.fsave) );
  36. }
  37. tsk->thread_info->status &= ~TS_USEDFPU;
  38. }
  39. #define __unlazy_fpu( tsk ) do { \
  40. if ((tsk)->thread_info->status & TS_USEDFPU) \
  41. save_init_fpu( tsk ); \
  42. } while (0)
  43. #define __clear_fpu( tsk ) \
  44. do { \
  45. if ((tsk)->thread_info->status & TS_USEDFPU) { \
  46. asm volatile("fnclex ; fwait"); \
  47. (tsk)->thread_info->status &= ~TS_USEDFPU; \
  48. stts(); \
  49. } \
  50. } while (0)
  51. /*
  52. * These disable preemption on their own and are safe
  53. */
  54. static inline void save_init_fpu( struct task_struct *tsk )
  55. {
  56. preempt_disable();
  57. __save_init_fpu(tsk);
  58. stts();
  59. preempt_enable();
  60. }
  61. #define unlazy_fpu( tsk ) do { \
  62. preempt_disable(); \
  63. __unlazy_fpu(tsk); \
  64. preempt_enable(); \
  65. } while (0)
  66. #define clear_fpu( tsk ) do { \
  67. preempt_disable(); \
  68. __clear_fpu( tsk ); \
  69. preempt_enable(); \
  70. } while (0)
  71. \
  72. /*
  73. * FPU state interaction...
  74. */
  75. extern unsigned short get_fpu_cwd( struct task_struct *tsk );
  76. extern unsigned short get_fpu_swd( struct task_struct *tsk );
  77. extern unsigned short get_fpu_mxcsr( struct task_struct *tsk );
  78. /*
  79. * Signal frame handlers...
  80. */
  81. extern int save_i387( struct _fpstate __user *buf );
  82. extern int restore_i387( struct _fpstate __user *buf );
  83. /*
  84. * ptrace request handers...
  85. */
  86. extern int get_fpregs( struct user_i387_struct __user *buf,
  87. struct task_struct *tsk );
  88. extern int set_fpregs( struct task_struct *tsk,
  89. struct user_i387_struct __user *buf );
  90. extern int get_fpxregs( struct user_fxsr_struct __user *buf,
  91. struct task_struct *tsk );
  92. extern int set_fpxregs( struct task_struct *tsk,
  93. struct user_fxsr_struct __user *buf );
  94. /*
  95. * FPU state for core dumps...
  96. */
  97. extern int dump_fpu( struct pt_regs *regs,
  98. struct user_i387_struct *fpu );
  99. #endif /* __ASM_I386_I387_H */