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