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 asmlinkage int (*save_fp_context)(struct sigcontext __user *sc);
  32extern asmlinkage int (*restore_fp_context)(struct sigcontext __user *sc);
  33
  34extern asmlinkage int (*save_fp_context32)(struct sigcontext32 __user *sc);
  35extern asmlinkage int (*restore_fp_context32)(struct sigcontext32 __user *sc);
  36
  37extern void fpu_emulator_init_fpu(void);
  38extern int fpu_emulator_save_context(struct sigcontext __user *sc);
  39extern int fpu_emulator_restore_context(struct sigcontext __user *sc);
  40extern void _init_fpu(void);
  41extern void _save_fp(struct task_struct *);
  42extern void _restore_fp(struct task_struct *);
  43
  44#define __enable_fpu()                                                  \
  45do {                                                                    \
  46        set_c0_status(ST0_CU1);                                         \
  47        enable_fpu_hazard();                                            \
  48} while (0)
  49
  50#define __disable_fpu()                                                 \
  51do {                                                                    \
  52        clear_c0_status(ST0_CU1);                                       \
  53        disable_fpu_hazard();                                           \
  54} while (0)
  55
  56#define enable_fpu()                                                    \
  57do {                                                                    \
  58        if (cpu_has_fpu)                                                \
  59                __enable_fpu();                                         \
  60} while (0)
  61
  62#define disable_fpu()                                                   \
  63do {                                                                    \
  64        if (cpu_has_fpu)                                                \
  65                __disable_fpu();                                        \
  66} while (0)
  67
  68
  69#define clear_fpu_owner()       clear_thread_flag(TIF_USEDFPU)
  70
  71static inline int __is_fpu_owner(void)
  72{
  73        return test_thread_flag(TIF_USEDFPU);
  74}
  75
  76static inline int is_fpu_owner(void)
  77{
  78        return cpu_has_fpu && __is_fpu_owner();
  79}
  80
  81static inline void __own_fpu(void)
  82{
  83        __enable_fpu();
  84        KSTK_STATUS(current) |= ST0_CU1;
  85        set_thread_flag(TIF_USEDFPU);
  86}
  87
  88static inline void own_fpu_inatomic(int restore)
  89{
  90        if (cpu_has_fpu && !__is_fpu_owner()) {
  91                __own_fpu();
  92                if (restore)
  93                        _restore_fp(current);
  94        }
  95}
  96
  97static inline void own_fpu(int restore)
  98{
  99        preempt_disable();
 100        own_fpu_inatomic(restore);
 101        preempt_enable();
 102}
 103
 104static inline void lose_fpu(int save)
 105{
 106        preempt_disable();
 107        if (is_fpu_owner()) {
 108                if (save)
 109                        _save_fp(current);
 110                KSTK_STATUS(current) &= ~ST0_CU1;
 111                clear_thread_flag(TIF_USEDFPU);
 112                __disable_fpu();
 113        }
 114        preempt_enable();
 115}
 116
 117static inline void init_fpu(void)
 118{
 119        preempt_disable();
 120        if (cpu_has_fpu) {
 121                __own_fpu();
 122                _init_fpu();
 123        } else {
 124                fpu_emulator_init_fpu();
 125        }
 126        preempt_enable();
 127}
 128
 129static inline void save_fp(struct task_struct *tsk)
 130{
 131        if (cpu_has_fpu)
 132                _save_fp(tsk);
 133}
 134
 135static inline void restore_fp(struct task_struct *tsk)
 136{
 137        if (cpu_has_fpu)
 138                _restore_fp(tsk);
 139}
 140
 141static inline fpureg_t *get_fpu_regs(struct task_struct *tsk)
 142{
 143        if (tsk == current) {
 144                preempt_disable();
 145                if (is_fpu_owner())
 146                        _save_fp(current);
 147                preempt_enable();
 148        }
 149
 150        return tsk->thread.fpu.fpr;
 151}
 152
 153#endif /* _ASM_FPU_H */
 154