00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef _RTAI_ASM_I386_FPU_H
00029 #define _RTAI_ASM_I386_FPU_H
00030
00031 #ifndef __cplusplus
00032 #include <asm/processor.h>
00033 #endif
00034
00035 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,25)
00036 typedef union i387_union FPU_ENV;
00037 #define TASK_FPENV(tsk) (&(tsk)->thread.i387)
00038 #else
00039 typedef union thread_xstate FPU_ENV;
00040 #define TASK_FPENV(tsk) ((tsk)->thread.xstate)
00041 #endif
00042
00043 #ifdef CONFIG_RTAI_FPU_SUPPORT
00044
00045
00046
00047 #define enable_fpu() do { \
00048 __asm__ __volatile__ ("clts"); \
00049 } while(0)
00050
00051 #define save_fpcr_and_enable_fpu(fpcr) do { \
00052 __asm__ __volatile__ ("movl %%cr0, %0; clts": "=r" (fpcr)); \
00053 } while (0)
00054
00055 #define restore_fpcr(fpcr) do { \
00056 if (fpcr & 8) { \
00057 __asm__ __volatile__ ("movl %%cr0, %0": "=r" (fpcr)); \
00058 __asm__ __volatile__ ("movl %0, %%cr0": :"r" (fpcr | 8)); \
00059 } \
00060 } while (0)
00061
00062
00063 #define init_hard_fpenv() do { \
00064 __asm__ __volatile__ ("clts; fninit"); \
00065 if (cpu_has_xmm) { \
00066 unsigned long __mxcsr = (0xffbfu & 0x1f80u); \
00067 __asm__ __volatile__ ("ldmxcsr %0": : "m" (__mxcsr)); \
00068 } \
00069 } while (0)
00070
00071
00072 #define __init_fpenv(fpenv) do { \
00073 if (cpu_has_fxsr) { \
00074 memset(&(fpenv)->fxsave, 0, sizeof(struct i387_fxsave_struct));\
00075 (fpenv)->fxsave.cwd = 0x37f; \
00076 if (cpu_has_xmm) { \
00077 (fpenv)->fxsave.mxcsr = 0x1f80; \
00078 } \
00079 } else { \
00080 memset(&(fpenv)->fsave, 0, sizeof(struct i387_fsave_struct)); \
00081 (fpenv)->fsave.cwd = 0xffff037fu; \
00082 (fpenv)->fsave.swd = 0xffff0000u; \
00083 (fpenv)->fsave.twd = 0xffffffffu; \
00084 (fpenv)->fsave.fos = 0xffff0000u; \
00085 } \
00086 } while (0)
00087
00088 #define __save_fpenv(fpenv) do { \
00089 if (cpu_has_fxsr) { \
00090 __asm__ __volatile__ ("fxsave %0; fnclex": "=m" ((fpenv)->fxsave)); \
00091 } else { \
00092 __asm__ __volatile__ ("fnsave %0; fwait": "=m" ((fpenv)->fsave)); \
00093 } \
00094 } while (0)
00095
00096 #define __restore_fpenv(fpenv) do { \
00097 if (cpu_has_fxsr) { \
00098 __asm__ __volatile__ ("fxrstor %0": : "m" ((fpenv)->fxsave)); \
00099 } else { \
00100 __asm__ __volatile__ ("frstor %0": : "m" ((fpenv)->fsave)); \
00101 } \
00102 } while (0)
00103
00104
00105
00106
00107 #define init_fpenv(fpenv) do { __init_fpenv(&(fpenv)); } while (0)
00108 #define save_fpenv(fpenv) do { __save_fpenv(&(fpenv)); } while (0)
00109 #define restore_fpenv(fpenv) do { __restore_fpenv(&(fpenv)); } while (0)
00110
00111
00112 #define init_hard_fpu(lnxtsk) do { \
00113 init_hard_fpenv(); \
00114 set_lnxtsk_uses_fpu(lnxtsk); \
00115 set_lnxtsk_using_fpu(lnxtsk); \
00116 } while (0)
00117
00118 #define init_fpu(lnxtsk) do { \
00119 __init_fpenv(TASK_FPENV(lnxtsk)); \
00120 set_lnxtsk_uses_fpu(lnxtsk); \
00121 } while (0)
00122
00123 #define restore_fpu(lnxtsk) do { \
00124 enable_fpu(); \
00125 __restore_fpenv(TASK_FPENV(lnxtsk)); \
00126 set_lnxtsk_using_fpu(lnxtsk); \
00127 } while (0)
00128
00129 #else
00130
00131 #define enable_fpu()
00132 #define save_fpcr_and_enable_fpu(fpcr)
00133 #define restore_fpcr(fpcr)
00134 #define init_hard_fpenv()
00135 #define init_fpenv(fpenv)
00136 #define save_fpenv(fpenv)
00137 #define restore_fpenv(fpenv)
00138 #define init_hard_fpu(lnxtsk)
00139 #define init_fpu(lnxtsk)
00140 #define restore_fpu(lnxtsk)
00141
00142 #endif
00143
00144
00145 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
00146
00147 #define set_lnxtsk_uses_fpu(lnxtsk) \
00148 do { (lnxtsk)->used_math = 1; } while(0)
00149 #define clear_lnxtsk_uses_fpu(lnxtsk) \
00150 do { (lnxtsk)->used_math = 0; } while(0)
00151 #define lnxtsk_uses_fpu(lnxtsk) ((lnxtsk)->used_math)
00152
00153 #define set_lnxtsk_using_fpu(lnxtsk) \
00154 do { (lnxtsk)->flags |= PF_USEDFPU; } while(0)
00155
00156 #endif
00157
00158
00159 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
00160
00161 #define set_lnxtsk_uses_fpu(lnxtsk) \
00162 do { (lnxtsk)->used_math = 1; } while(0)
00163 #define clear_lnxtsk_uses_fpu(lnxtsk) \
00164 do { (lnxtsk)->used_math = 0; } while(0)
00165 #define lnxtsk_uses_fpu(lnxtsk) ((lnxtsk)->used_math)
00166
00167 #define set_lnxtsk_using_fpu(lnxtsk) \
00168 do { task_thread_info(lnxtsk)->status |= TS_USEDFPU; } while(0)
00169
00170
00171 #endif
00172
00173
00174 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11)
00175
00176 #define set_lnxtsk_uses_fpu(lnxtsk) \
00177 do { set_stopped_child_used_math(lnxtsk); } while(0)
00178 #define clear_lnxtsk_uses_fpu(lnxtsk) \
00179 do { clear_stopped_child_used_math(lnxtsk); } while(0)
00180 #define lnxtsk_uses_fpu(lnxtsk) (tsk_used_math(lnxtsk))
00181
00182 #define set_lnxtsk_using_fpu(lnxtsk) \
00183 do { task_thread_info(lnxtsk)->status |= TS_USEDFPU; } while(0)
00184
00185
00186 #endif
00187
00188
00189 #endif