linux/arch/mips/include/asm/fpu.h
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2002 MontaVista Software Inc.
   3 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
   4 *
   5 * This program is free software; you can redistribute it and/or modify it
   6 * under the terms of the GNU General Public License as published by the
   7 * Free Software Foundation;  either version 2 of the  License, or (at your
   8 * option) any later version.
   9 */
  10#ifndef _ASM_FPU_H
  11#define _ASM_FPU_H
  12
  13#include <linux/sched.h>
  14#include <linux/thread_info.h>
  15#include <linux/bitops.h>
  16
  17#include <asm/mipsregs.h>
  18#include <asm/cpu.h>
  19#include <asm/cpu-features.h>
  20#include <asm/hazards.h>
  21#include <asm/processor.h>
  22#include <asm/current.h>
  23
  24#ifdef CONFIG_MIPS_MT_FPAFF
  25#include <asm/mips_mt.h>
  26#endif
  27
  28struct sigcontext;
  29struct sigcontext32;
  30
  31extern void fpu_emulator_init_fpu(void);
  32extern void _init_fpu(void);
  33extern void _save_fp(struct task_struct *);
  34extern void _restore_fp(struct task_struct *);
  35
  36#define __enable_fpu()                                                  \
  37do {                                                                    \
  38        set_c0_status(ST0_CU1);                                         \
  39        enable_fpu_hazard();                                            \
  40} while (0)
  41
  42#define __disable_fpu()                                                 \
  43do {                                                                    \
  44        clear_c0_status(ST0_CU1);                                       \
  45        disable_fpu_hazard();                                           \
  46} while (0)
  47
  48#define enable_fpu()                                                    \
  49do {                                                                    \
  50        if (cpu_has_fpu)                                                \
  51                __enable_fpu();                                         \
  52} while (0)
  53
  54#define disable_fpu()                                                   \
  55do {                                                                    \
  56        if (cpu_has_fpu)                                                \
  57                __disable_fpu();                                        \
  58} while (0)
  59
  60
  61#define clear_fpu_owner()       clear_thread_flag(TIF_USEDFPU)
  62
  63static inline int __is_fpu_owner(void)
  64{
  65        return test_thread_flag(TIF_USEDFPU);
  66}
  67
  68static inline int is_fpu_owner(void)
  69{
  70        return cpu_has_fpu && __is_fpu_owner();
  71}
  72
  73static inline void __own_fpu(void)
  74{
  75        __enable_fpu();
  76        KSTK_STATUS(current) |= ST0_CU1;
  77        set_thread_flag(TIF_USEDFPU);
  78}
  79
  80static inline void own_fpu_inatomic(int restore)
  81{
  82        if (cpu_has_fpu && !__is_fpu_owner()) {
  83                __own_fpu();
  84                if (restore)
  85                        _restore_fp(current);
  86        }
  87}
  88
  89static inline void own_fpu(int restore)
  90{
  91        preempt_disable();
  92        own_fpu_inatomic(restore);
  93        preempt_enable();
  94}
  95
  96static inline void lose_fpu(int save)
  97{
  98        preempt_disable();
  99        if (is_fpu_owner()) {
 100                if (save)
 101                        _save_fp(current);
 102                KSTK_STATUS(current) &= ~ST0_CU1;
 103                clear_thread_flag(TIF_USEDFPU);
 104                __disable_fpu();
 105        }
 106        preempt_enable();
 107}
 108
 109static inline void init_fpu(void)
 110{
 111        preempt_disable();
 112        if (cpu_has_fpu) {
 113                __own_fpu();
 114                _init_fpu();
 115        } else {
 116                fpu_emulator_init_fpu();
 117        }
 118        preempt_enable();
 119}
 120
 121static inline void save_fp(struct task_struct *tsk)
 122{
 123        if (cpu_has_fpu)
 124                _save_fp(tsk);
 125}
 126
 127static inline void restore_fp(struct task_struct *tsk)
 128{
 129        if (cpu_has_fpu)
 130                _restore_fp(tsk);
 131}
 132
 133static inline fpureg_t *get_fpu_regs(struct task_struct *tsk)
 134{
 135        if (tsk == current) {
 136                preempt_disable();
 137                if (is_fpu_owner())
 138                        _save_fp(current);
 139                preempt_enable();
 140        }
 141
 142        return tsk->thread.fpu.fpr;
 143}
 144
 145#endif /* _ASM_FPU_H */
 146