i387.h
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:4k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * include/asm-x86_64/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.  * x86-64 work by Andi Kleen 2002
  10.  */
  11. #ifndef __ASM_X86_64_I387_H
  12. #define __ASM_X86_64_I387_H
  13. #include <linux/sched.h>
  14. #include <asm/processor.h>
  15. #include <asm/sigcontext.h>
  16. #include <asm/user.h>
  17. extern void init_fpu(void);
  18. int save_i387( struct _fpstate *buf);
  19. /*
  20.  * FPU lazy state save handling...
  21.  */
  22. #define kernel_fpu_end() stts()
  23. #define unlazy_fpu( tsk ) do { 
  24. if ( tsk->flags & PF_USEDFPU ) 
  25. save_init_fpu( tsk ); 
  26. } while (0)
  27. #define clear_fpu( tsk ) do { 
  28. if ( tsk->flags & PF_USEDFPU ) { 
  29. asm volatile("fwait"); 
  30. tsk->flags &= ~PF_USEDFPU; 
  31. stts(); 
  32. } while (0)
  33. #define load_mxcsr( val ) do { 
  34. unsigned long __mxcsr = ((unsigned long)(val) & 0xffbf); 
  35. asm volatile( "ldmxcsr %0" : : "m" (__mxcsr) ); 
  36. } while (0)
  37. /*
  38.  * ptrace request handers...
  39.  */
  40. extern int get_fpregs( struct user_i387_struct *buf,
  41.        struct task_struct *tsk );
  42. extern int set_fpregs( struct task_struct *tsk,
  43.        struct user_i387_struct *buf );
  44. /*
  45.  * FPU state for core dumps...
  46.  */
  47. extern int dump_fpu( struct pt_regs *regs,
  48.      struct user_i387_struct *fpu );
  49. /* 
  50.  * i387 state interaction
  51.  */
  52. #define get_fpu_mxcsr(t) ((t)->thread.i387.fxsave.mxcsr)
  53. #define get_fpu_cwd(t) ((t)->thread.i387.fxsave.cwd)
  54. #define get_fpu_fxsr_twd(t) ((t)->thread.i387.fxsave.twd)
  55. #define get_fpu_swd(t) ((t)->thread.i387.fxsave.swd)
  56. #define set_fpu_cwd(t,val) ((t)->thread.i387.fxsave.cwd = (val))
  57. #define set_fpu_swd(t,val) ((t)->thread.i387.fxsave.swd = (val))
  58. #define set_fpu_fxsr_twd(t,val) ((t)->thread.i387.fxsave.twd = (val))
  59. #define set_fpu_mxcsr(t,val) ((t)->thread.i387.fxsave.mxcsr = (val)&0xffbf)
  60. static inline int restore_fpu_checking(struct i387_fxsave_struct *fx) 
  61. int err;
  62. asm volatile("1:  rex64 ; fxrstor (%[fx])nt"
  63.      "2:n"
  64.      ".section .fixup,"ax"n"
  65.      "3:  movl $-1,%[err]n"
  66.      "    jmp  2bn"
  67.      ".previousn"
  68.      ".section __ex_table,"a"n"
  69.      "   .align 8n"
  70.      "   .quad  1b,3bn"
  71.      ".previous"
  72.      : [err] "=r" (err)
  73.      : [fx] "r" (fx), "0" (0)); 
  74. return err;
  75. static inline int save_i387_checking(struct i387_fxsave_struct *fx) 
  76. int err;
  77. asm volatile("1:  rex64 ; fxsave (%[fx])nt"
  78.      "2:n"
  79.      ".section .fixup,"ax"n"
  80.      "3:  movl $-1,%[err]n"
  81.      "    jmp  2bn"
  82.      ".previousn"
  83.      ".section __ex_table,"a"n"
  84.      "   .align 8n"
  85.      "   .quad  1b,3bn"
  86.      ".previous"
  87.      : [err] "=r" (err)
  88.      : [fx] "r" (fx), "0" (0)); 
  89. return err;
  90. static inline void kernel_fpu_begin(void)
  91. {
  92. struct task_struct *tsk = current;
  93. if (tsk->flags & PF_USEDFPU) {
  94. asm volatile("fxsave %0 ; fnclex"
  95.       : "=m" (tsk->thread.i387.fxsave));
  96. tsk->flags &= ~PF_USEDFPU;
  97. return;
  98. }
  99. clts();
  100. }
  101. static inline void save_init_fpu( struct task_struct *tsk )
  102. {
  103. asm volatile( "fxsave %0 ; fnclex"
  104.       : "=m" (tsk->thread.i387.fxsave));
  105. tsk->flags &= ~PF_USEDFPU;
  106. stts();
  107. }
  108. /* 
  109.  * This restores directly out of user space. Exceptions are handled.
  110.  */ 
  111. static inline int restore_i387(struct _fpstate *buf)
  112. {
  113. return restore_fpu_checking((struct i387_fxsave_struct *)buf);
  114. }
  115. static inline void empty_fpu(struct task_struct *child)
  116. {
  117. if (!child->used_math) {
  118. /* Simulate an empty FPU. */
  119. memset(&child->thread.i387.fxsave,0,sizeof(struct i387_fxsave_struct));
  120. child->thread.i387.fxsave.cwd = 0x037f; 
  121. child->thread.i387.fxsave.swd = 0;
  122. child->thread.i387.fxsave.twd = 0; 
  123. child->thread.i387.fxsave.mxcsr = 0x1f80;
  124. }
  125. child->used_math = 1; 
  126. }
  127. #endif /* __ASM_X86_64_I387_H */