# rtai_fpu.h

    00001 /*
    00002  *   ARTI -- RTAI-compatible Adeos-based Real-Time Interface. Based on
    00003  *   the original RTAI layer for x86.
    00004  *
    00005  *   Copyright (C) 1994 Linus Torvalds
    00006  *   Copyright (C) 2000 Gareth Hughes <gareth@valinux.com>,
    00007  *   Copyright (C) 2000 Pierre Cloutier <pcloutier@PoseidonControls.com>
    00008  *   and others.
    00009  *
    00010  *   RTAI/x86 rewrite over Adeos:
    00011  *   Copyright (C) 2002 Philippe Gerum.
    00012  *
    00013  *   This program is free software; you can redistribute it and/or modify
    00014  *   it under the terms of the GNU General Public License as published by
    00015  *   the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
    00016  *   USA; either version 2 of the License, or (at your option) any later
    00017  *   version.
    00018  *
    00019  *   This program is distributed in the hope that it will be useful,
    00020  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
    00021  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00022  *   GNU General Public License for more details.
    00023  *
    00024  *   You should have received a copy of the GNU General Public License
    00025  *   along with this program; if not, write to the Free Software
    00026  *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    00027  */
    00028
    00029 #ifndef _RTAI_ASM_I386_FPU_H
    00030 #define _RTAI_ASM_I386_FPU_H
    00031
    00032 #ifndef __cplusplus
    00033 #include <asm/processor.h>
    00034 #endif /* !__cplusplus */
    00035
    00036 typedef union i387_union FPU_ENV;
    00037
    00038 #ifdef CONFIG_RTAI_FPU_SUPPORT
    00039
    00040 #define init_fpu(tsk) \
    00041         do { init_xfpu(); tsk->used_math = 1; set_tsk_used_fpu(tsk); } while(0)
    00042
    00043 #define restore_fpu(tsk) \
    00044         do { restore_fpenv_lxrt((tsk)); set_tsk_used_fpu(tsk); } while (0)
    00045
    00046 #define load_mxcsr(val) \
    00047         do { \
    00048                 unsigned long __mxcsr = ((unsigned long)(val) & 0xffbf); \
    00049                 __asm__ __volatile__ ("ldmxcsr %0": : "m" (__mxcsr)); \
    00050         } while (0)
    00051
    00052 #define save_cr0_and_clts(x) \
    00053         do { \
    00054                 __asm__ __volatile__ ("movl %%cr0,%0; clts": "=r" (x)); \
    00055         } while (0)
    00056
    00057 #define restore_cr0(x) \
    00058         do { \
    00059                 if (x & 8) { \
    00060                        unsigned long flags; \
    00061                        rtai_hw_save_flags_and_cli(flags); \
    00062                         __asm__ __volatile__ ("movl %%cr0, %0": "=r" (x)); \
    00063                         __asm__ __volatile__ ("movl %0, %%cr0": :"r" (8 | x)); \
    00064                        rtai_hw_restore_flags(flags); \
    00065                 } \
    00066         } while (0)
    00067
    00068 #define enable_fpu() \
    00069         do { \
    00070                 __asm__ __volatile__ ("clts"); \
    00071         } while (0)
    00072
    00073 #define init_xfpu() \
    00074         do { \
    00075                 __asm__ __volatile__ ("clts; fninit"); \
    00076                 if (cpu_has_xmm) { \
    00077                         load_mxcsr(0x1f80); \
    00078                 } \
    00079         } while (0)
    00080
    00081 #define save_fpenv(x) \
    00082         do { \
    00083                 if (cpu_has_fxsr) { \
    00084                         __asm__ __volatile__ ("fxsave %0; fnclex": "=m" (x)); \
    00085                 } else { \
    00086                         __asm__ __volatile__ ("fnsave %0; fwait": "=m" (x)); \
    00087                 } \
    00088         } while (0)
    00089
    00090 #define restore_fpenv(x) \
    00091         do { \
    00092                 if (cpu_has_fxsr) { \
    00093                         __asm__ __volatile__ ("fxrstor %0": : "m" (x)); \
    00094                 } else { \
    00095                         __asm__ __volatile__ ("frstor %0": : "m" (x)); \
    00096                 } \
    00097         } while (0)
    00098
    00099 #define restore_task_fpenv(t) \
    00100         do { \
    00101                clts(); \
    00102                restore_fpenv((t)->thread.i387.fsave); \
    00103         } while (0)
    00104
    00105 #define restore_fpenv_lxrt(t) restore_task_fpenv(t)
    00106
    00107 #else /* !CONFIG_RTAI_FPU_SUPPORT */
    00108
    00109 static void init_fpu(struct task_struct *tsk) { }
    00110 #define restore_fpu(tsk)
    00111 #define save_cr0_and_clts(x)
    00112 #define restore_cr0(x)
    00113 #define enable_fpu()
    00114 #define load_mxcsr(val)
    00115 #define init_xfpu()
    00116 #define save_fpenv(x)
    00117 #define restore_fpenv(x)
    00118 #define restore_task_fpenv(t)
    00119 #define restore_fpenv_lxrt(t)
    00120
    00121 #endif /* CONFIG_RTAI_FPU_SUPPORT */
    00122
    00123 #endif /* !_RTAI_ASM_I386_FPU_H */