linux/arch/mips/include/asm/fpu_emulator.h
<<
>>
Prefs
   1/*
   2 *  This program is free software; you can distribute it and/or modify it
   3 *  under the terms of the GNU General Public License (Version 2) as
   4 *  published by the Free Software Foundation.
   5 *
   6 *  This program is distributed in the hope it will be useful, but WITHOUT
   7 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   8 *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   9 *  for more details.
  10 *
  11 *  You should have received a copy of the GNU General Public License along
  12 *  with this program; if not, write to the Free Software Foundation, Inc.,
  13 *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  14 *
  15 * Further private data for which no space exists in mips_fpu_struct.
  16 * This should be subsumed into the mips_fpu_struct structure as
  17 * defined in processor.h as soon as the absurd wired absolute assembler
  18 * offsets become dynamic at compile time.
  19 *
  20 * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
  21 * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
  22 */
  23#ifndef _ASM_FPU_EMULATOR_H
  24#define _ASM_FPU_EMULATOR_H
  25
  26#include <linux/sched.h>
  27#include <asm/dsemul.h>
  28#include <asm/thread_info.h>
  29#include <asm/inst.h>
  30#include <asm/local.h>
  31#include <asm/processor.h>
  32
  33#ifdef CONFIG_DEBUG_FS
  34
  35struct mips_fpu_emulator_stats {
  36        unsigned long emulated;
  37        unsigned long loads;
  38        unsigned long stores;
  39        unsigned long branches;
  40        unsigned long cp1ops;
  41        unsigned long cp1xops;
  42        unsigned long errors;
  43        unsigned long ieee754_inexact;
  44        unsigned long ieee754_underflow;
  45        unsigned long ieee754_overflow;
  46        unsigned long ieee754_zerodiv;
  47        unsigned long ieee754_invalidop;
  48        unsigned long ds_emul;
  49
  50        unsigned long abs_s;
  51        unsigned long abs_d;
  52        unsigned long add_s;
  53        unsigned long add_d;
  54        unsigned long bc1eqz;
  55        unsigned long bc1nez;
  56        unsigned long ceil_w_s;
  57        unsigned long ceil_w_d;
  58        unsigned long ceil_l_s;
  59        unsigned long ceil_l_d;
  60        unsigned long class_s;
  61        unsigned long class_d;
  62        unsigned long cmp_af_s;
  63        unsigned long cmp_af_d;
  64        unsigned long cmp_eq_s;
  65        unsigned long cmp_eq_d;
  66        unsigned long cmp_le_s;
  67        unsigned long cmp_le_d;
  68        unsigned long cmp_lt_s;
  69        unsigned long cmp_lt_d;
  70        unsigned long cmp_ne_s;
  71        unsigned long cmp_ne_d;
  72        unsigned long cmp_or_s;
  73        unsigned long cmp_or_d;
  74        unsigned long cmp_ueq_s;
  75        unsigned long cmp_ueq_d;
  76        unsigned long cmp_ule_s;
  77        unsigned long cmp_ule_d;
  78        unsigned long cmp_ult_s;
  79        unsigned long cmp_ult_d;
  80        unsigned long cmp_un_s;
  81        unsigned long cmp_un_d;
  82        unsigned long cmp_une_s;
  83        unsigned long cmp_une_d;
  84        unsigned long cmp_saf_s;
  85        unsigned long cmp_saf_d;
  86        unsigned long cmp_seq_s;
  87        unsigned long cmp_seq_d;
  88        unsigned long cmp_sle_s;
  89        unsigned long cmp_sle_d;
  90        unsigned long cmp_slt_s;
  91        unsigned long cmp_slt_d;
  92        unsigned long cmp_sne_s;
  93        unsigned long cmp_sne_d;
  94        unsigned long cmp_sor_s;
  95        unsigned long cmp_sor_d;
  96        unsigned long cmp_sueq_s;
  97        unsigned long cmp_sueq_d;
  98        unsigned long cmp_sule_s;
  99        unsigned long cmp_sule_d;
 100        unsigned long cmp_sult_s;
 101        unsigned long cmp_sult_d;
 102        unsigned long cmp_sun_s;
 103        unsigned long cmp_sun_d;
 104        unsigned long cmp_sune_s;
 105        unsigned long cmp_sune_d;
 106        unsigned long cvt_d_l;
 107        unsigned long cvt_d_s;
 108        unsigned long cvt_d_w;
 109        unsigned long cvt_l_s;
 110        unsigned long cvt_l_d;
 111        unsigned long cvt_s_d;
 112        unsigned long cvt_s_l;
 113        unsigned long cvt_s_w;
 114        unsigned long cvt_w_s;
 115        unsigned long cvt_w_d;
 116        unsigned long div_s;
 117        unsigned long div_d;
 118        unsigned long floor_w_s;
 119        unsigned long floor_w_d;
 120        unsigned long floor_l_s;
 121        unsigned long floor_l_d;
 122        unsigned long maddf_s;
 123        unsigned long maddf_d;
 124        unsigned long max_s;
 125        unsigned long max_d;
 126        unsigned long maxa_s;
 127        unsigned long maxa_d;
 128        unsigned long min_s;
 129        unsigned long min_d;
 130        unsigned long mina_s;
 131        unsigned long mina_d;
 132        unsigned long mov_s;
 133        unsigned long mov_d;
 134        unsigned long msubf_s;
 135        unsigned long msubf_d;
 136        unsigned long mul_s;
 137        unsigned long mul_d;
 138        unsigned long neg_s;
 139        unsigned long neg_d;
 140        unsigned long recip_s;
 141        unsigned long recip_d;
 142        unsigned long rint_s;
 143        unsigned long rint_d;
 144        unsigned long round_w_s;
 145        unsigned long round_w_d;
 146        unsigned long round_l_s;
 147        unsigned long round_l_d;
 148        unsigned long rsqrt_s;
 149        unsigned long rsqrt_d;
 150        unsigned long sel_s;
 151        unsigned long sel_d;
 152        unsigned long seleqz_s;
 153        unsigned long seleqz_d;
 154        unsigned long selnez_s;
 155        unsigned long selnez_d;
 156        unsigned long sqrt_s;
 157        unsigned long sqrt_d;
 158        unsigned long sub_s;
 159        unsigned long sub_d;
 160        unsigned long trunc_w_s;
 161        unsigned long trunc_w_d;
 162        unsigned long trunc_l_s;
 163        unsigned long trunc_l_d;
 164};
 165
 166DECLARE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
 167
 168#define MIPS_FPU_EMU_INC_STATS(M)                                       \
 169do {                                                                    \
 170        preempt_disable();                                              \
 171        __this_cpu_inc(fpuemustats.M);                                  \
 172        preempt_enable();                                               \
 173} while (0)
 174
 175#else
 176#define MIPS_FPU_EMU_INC_STATS(M) do { } while (0)
 177#endif /* CONFIG_DEBUG_FS */
 178
 179extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
 180                                    struct mips_fpu_struct *ctx, int has_fpu,
 181                                    void __user **fault_addr);
 182void force_fcr31_sig(unsigned long fcr31, void __user *fault_addr,
 183                     struct task_struct *tsk);
 184int process_fpemu_return(int sig, void __user *fault_addr,
 185                         unsigned long fcr31);
 186int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
 187                  unsigned long *contpc);
 188int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
 189                     unsigned long *contpc);
 190
 191#define SIGNALLING_NAN 0x7ff800007ff80000LL
 192
 193static inline void fpu_emulator_init_fpu(void)
 194{
 195        struct task_struct *t = current;
 196        int i;
 197
 198        for (i = 0; i < 32; i++)
 199                set_fpr64(&t->thread.fpu.fpr[i], 0, SIGNALLING_NAN);
 200}
 201
 202/*
 203 * Mask the FCSR Cause bits according to the Enable bits, observing
 204 * that Unimplemented is always enabled.
 205 */
 206static inline unsigned long mask_fcr31_x(unsigned long fcr31)
 207{
 208        return fcr31 & (FPU_CSR_UNI_X |
 209                        ((fcr31 & FPU_CSR_ALL_E) <<
 210                         (ffs(FPU_CSR_ALL_X) - ffs(FPU_CSR_ALL_E))));
 211}
 212
 213#endif /* _ASM_FPU_EMULATOR_H */
 214