18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Further private data for which no space exists in mips_fpu_struct. 58c2ecf20Sopenharmony_ci * This should be subsumed into the mips_fpu_struct structure as 68c2ecf20Sopenharmony_ci * defined in processor.h as soon as the absurd wired absolute assembler 78c2ecf20Sopenharmony_ci * offsets become dynamic at compile time. 88c2ecf20Sopenharmony_ci * 98c2ecf20Sopenharmony_ci * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com 108c2ecf20Sopenharmony_ci * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. 118c2ecf20Sopenharmony_ci */ 128c2ecf20Sopenharmony_ci#ifndef _ASM_FPU_EMULATOR_H 138c2ecf20Sopenharmony_ci#define _ASM_FPU_EMULATOR_H 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci#include <linux/sched.h> 168c2ecf20Sopenharmony_ci#include <asm/dsemul.h> 178c2ecf20Sopenharmony_ci#include <asm/thread_info.h> 188c2ecf20Sopenharmony_ci#include <asm/inst.h> 198c2ecf20Sopenharmony_ci#include <asm/local.h> 208c2ecf20Sopenharmony_ci#include <asm/processor.h> 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci#ifdef CONFIG_DEBUG_FS 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_cistruct mips_fpu_emulator_stats { 258c2ecf20Sopenharmony_ci unsigned long emulated; 268c2ecf20Sopenharmony_ci unsigned long loads; 278c2ecf20Sopenharmony_ci unsigned long stores; 288c2ecf20Sopenharmony_ci unsigned long branches; 298c2ecf20Sopenharmony_ci unsigned long cp1ops; 308c2ecf20Sopenharmony_ci unsigned long cp1xops; 318c2ecf20Sopenharmony_ci unsigned long errors; 328c2ecf20Sopenharmony_ci unsigned long ieee754_inexact; 338c2ecf20Sopenharmony_ci unsigned long ieee754_underflow; 348c2ecf20Sopenharmony_ci unsigned long ieee754_overflow; 358c2ecf20Sopenharmony_ci unsigned long ieee754_zerodiv; 368c2ecf20Sopenharmony_ci unsigned long ieee754_invalidop; 378c2ecf20Sopenharmony_ci unsigned long ds_emul; 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci unsigned long abs_s; 408c2ecf20Sopenharmony_ci unsigned long abs_d; 418c2ecf20Sopenharmony_ci unsigned long add_s; 428c2ecf20Sopenharmony_ci unsigned long add_d; 438c2ecf20Sopenharmony_ci unsigned long bc1eqz; 448c2ecf20Sopenharmony_ci unsigned long bc1nez; 458c2ecf20Sopenharmony_ci unsigned long ceil_w_s; 468c2ecf20Sopenharmony_ci unsigned long ceil_w_d; 478c2ecf20Sopenharmony_ci unsigned long ceil_l_s; 488c2ecf20Sopenharmony_ci unsigned long ceil_l_d; 498c2ecf20Sopenharmony_ci unsigned long class_s; 508c2ecf20Sopenharmony_ci unsigned long class_d; 518c2ecf20Sopenharmony_ci unsigned long cmp_af_s; 528c2ecf20Sopenharmony_ci unsigned long cmp_af_d; 538c2ecf20Sopenharmony_ci unsigned long cmp_eq_s; 548c2ecf20Sopenharmony_ci unsigned long cmp_eq_d; 558c2ecf20Sopenharmony_ci unsigned long cmp_le_s; 568c2ecf20Sopenharmony_ci unsigned long cmp_le_d; 578c2ecf20Sopenharmony_ci unsigned long cmp_lt_s; 588c2ecf20Sopenharmony_ci unsigned long cmp_lt_d; 598c2ecf20Sopenharmony_ci unsigned long cmp_ne_s; 608c2ecf20Sopenharmony_ci unsigned long cmp_ne_d; 618c2ecf20Sopenharmony_ci unsigned long cmp_or_s; 628c2ecf20Sopenharmony_ci unsigned long cmp_or_d; 638c2ecf20Sopenharmony_ci unsigned long cmp_ueq_s; 648c2ecf20Sopenharmony_ci unsigned long cmp_ueq_d; 658c2ecf20Sopenharmony_ci unsigned long cmp_ule_s; 668c2ecf20Sopenharmony_ci unsigned long cmp_ule_d; 678c2ecf20Sopenharmony_ci unsigned long cmp_ult_s; 688c2ecf20Sopenharmony_ci unsigned long cmp_ult_d; 698c2ecf20Sopenharmony_ci unsigned long cmp_un_s; 708c2ecf20Sopenharmony_ci unsigned long cmp_un_d; 718c2ecf20Sopenharmony_ci unsigned long cmp_une_s; 728c2ecf20Sopenharmony_ci unsigned long cmp_une_d; 738c2ecf20Sopenharmony_ci unsigned long cmp_saf_s; 748c2ecf20Sopenharmony_ci unsigned long cmp_saf_d; 758c2ecf20Sopenharmony_ci unsigned long cmp_seq_s; 768c2ecf20Sopenharmony_ci unsigned long cmp_seq_d; 778c2ecf20Sopenharmony_ci unsigned long cmp_sle_s; 788c2ecf20Sopenharmony_ci unsigned long cmp_sle_d; 798c2ecf20Sopenharmony_ci unsigned long cmp_slt_s; 808c2ecf20Sopenharmony_ci unsigned long cmp_slt_d; 818c2ecf20Sopenharmony_ci unsigned long cmp_sne_s; 828c2ecf20Sopenharmony_ci unsigned long cmp_sne_d; 838c2ecf20Sopenharmony_ci unsigned long cmp_sor_s; 848c2ecf20Sopenharmony_ci unsigned long cmp_sor_d; 858c2ecf20Sopenharmony_ci unsigned long cmp_sueq_s; 868c2ecf20Sopenharmony_ci unsigned long cmp_sueq_d; 878c2ecf20Sopenharmony_ci unsigned long cmp_sule_s; 888c2ecf20Sopenharmony_ci unsigned long cmp_sule_d; 898c2ecf20Sopenharmony_ci unsigned long cmp_sult_s; 908c2ecf20Sopenharmony_ci unsigned long cmp_sult_d; 918c2ecf20Sopenharmony_ci unsigned long cmp_sun_s; 928c2ecf20Sopenharmony_ci unsigned long cmp_sun_d; 938c2ecf20Sopenharmony_ci unsigned long cmp_sune_s; 948c2ecf20Sopenharmony_ci unsigned long cmp_sune_d; 958c2ecf20Sopenharmony_ci unsigned long cvt_d_l; 968c2ecf20Sopenharmony_ci unsigned long cvt_d_s; 978c2ecf20Sopenharmony_ci unsigned long cvt_d_w; 988c2ecf20Sopenharmony_ci unsigned long cvt_l_s; 998c2ecf20Sopenharmony_ci unsigned long cvt_l_d; 1008c2ecf20Sopenharmony_ci unsigned long cvt_s_d; 1018c2ecf20Sopenharmony_ci unsigned long cvt_s_l; 1028c2ecf20Sopenharmony_ci unsigned long cvt_s_w; 1038c2ecf20Sopenharmony_ci unsigned long cvt_w_s; 1048c2ecf20Sopenharmony_ci unsigned long cvt_w_d; 1058c2ecf20Sopenharmony_ci unsigned long div_s; 1068c2ecf20Sopenharmony_ci unsigned long div_d; 1078c2ecf20Sopenharmony_ci unsigned long floor_w_s; 1088c2ecf20Sopenharmony_ci unsigned long floor_w_d; 1098c2ecf20Sopenharmony_ci unsigned long floor_l_s; 1108c2ecf20Sopenharmony_ci unsigned long floor_l_d; 1118c2ecf20Sopenharmony_ci unsigned long maddf_s; 1128c2ecf20Sopenharmony_ci unsigned long maddf_d; 1138c2ecf20Sopenharmony_ci unsigned long max_s; 1148c2ecf20Sopenharmony_ci unsigned long max_d; 1158c2ecf20Sopenharmony_ci unsigned long maxa_s; 1168c2ecf20Sopenharmony_ci unsigned long maxa_d; 1178c2ecf20Sopenharmony_ci unsigned long min_s; 1188c2ecf20Sopenharmony_ci unsigned long min_d; 1198c2ecf20Sopenharmony_ci unsigned long mina_s; 1208c2ecf20Sopenharmony_ci unsigned long mina_d; 1218c2ecf20Sopenharmony_ci unsigned long mov_s; 1228c2ecf20Sopenharmony_ci unsigned long mov_d; 1238c2ecf20Sopenharmony_ci unsigned long msubf_s; 1248c2ecf20Sopenharmony_ci unsigned long msubf_d; 1258c2ecf20Sopenharmony_ci unsigned long mul_s; 1268c2ecf20Sopenharmony_ci unsigned long mul_d; 1278c2ecf20Sopenharmony_ci unsigned long neg_s; 1288c2ecf20Sopenharmony_ci unsigned long neg_d; 1298c2ecf20Sopenharmony_ci unsigned long recip_s; 1308c2ecf20Sopenharmony_ci unsigned long recip_d; 1318c2ecf20Sopenharmony_ci unsigned long rint_s; 1328c2ecf20Sopenharmony_ci unsigned long rint_d; 1338c2ecf20Sopenharmony_ci unsigned long round_w_s; 1348c2ecf20Sopenharmony_ci unsigned long round_w_d; 1358c2ecf20Sopenharmony_ci unsigned long round_l_s; 1368c2ecf20Sopenharmony_ci unsigned long round_l_d; 1378c2ecf20Sopenharmony_ci unsigned long rsqrt_s; 1388c2ecf20Sopenharmony_ci unsigned long rsqrt_d; 1398c2ecf20Sopenharmony_ci unsigned long sel_s; 1408c2ecf20Sopenharmony_ci unsigned long sel_d; 1418c2ecf20Sopenharmony_ci unsigned long seleqz_s; 1428c2ecf20Sopenharmony_ci unsigned long seleqz_d; 1438c2ecf20Sopenharmony_ci unsigned long selnez_s; 1448c2ecf20Sopenharmony_ci unsigned long selnez_d; 1458c2ecf20Sopenharmony_ci unsigned long sqrt_s; 1468c2ecf20Sopenharmony_ci unsigned long sqrt_d; 1478c2ecf20Sopenharmony_ci unsigned long sub_s; 1488c2ecf20Sopenharmony_ci unsigned long sub_d; 1498c2ecf20Sopenharmony_ci unsigned long trunc_w_s; 1508c2ecf20Sopenharmony_ci unsigned long trunc_w_d; 1518c2ecf20Sopenharmony_ci unsigned long trunc_l_s; 1528c2ecf20Sopenharmony_ci unsigned long trunc_l_d; 1538c2ecf20Sopenharmony_ci}; 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ciDECLARE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats); 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci#define MIPS_FPU_EMU_INC_STATS(M) \ 1588c2ecf20Sopenharmony_cido { \ 1598c2ecf20Sopenharmony_ci preempt_disable(); \ 1608c2ecf20Sopenharmony_ci __this_cpu_inc(fpuemustats.M); \ 1618c2ecf20Sopenharmony_ci preempt_enable(); \ 1628c2ecf20Sopenharmony_ci} while (0) 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_ci#else 1658c2ecf20Sopenharmony_ci#define MIPS_FPU_EMU_INC_STATS(M) do { } while (0) 1668c2ecf20Sopenharmony_ci#endif /* CONFIG_DEBUG_FS */ 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ciextern int fpu_emulator_cop1Handler(struct pt_regs *xcp, 1698c2ecf20Sopenharmony_ci struct mips_fpu_struct *ctx, int has_fpu, 1708c2ecf20Sopenharmony_ci void __user **fault_addr); 1718c2ecf20Sopenharmony_civoid force_fcr31_sig(unsigned long fcr31, void __user *fault_addr, 1728c2ecf20Sopenharmony_ci struct task_struct *tsk); 1738c2ecf20Sopenharmony_ciint process_fpemu_return(int sig, void __user *fault_addr, 1748c2ecf20Sopenharmony_ci unsigned long fcr31); 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci/* 1778c2ecf20Sopenharmony_ci * Mask the FCSR Cause bits according to the Enable bits, observing 1788c2ecf20Sopenharmony_ci * that Unimplemented is always enabled. 1798c2ecf20Sopenharmony_ci */ 1808c2ecf20Sopenharmony_cistatic inline unsigned long mask_fcr31_x(unsigned long fcr31) 1818c2ecf20Sopenharmony_ci{ 1828c2ecf20Sopenharmony_ci return fcr31 & (FPU_CSR_UNI_X | 1838c2ecf20Sopenharmony_ci ((fcr31 & FPU_CSR_ALL_E) << 1848c2ecf20Sopenharmony_ci (ffs(FPU_CSR_ALL_X) - ffs(FPU_CSR_ALL_E)))); 1858c2ecf20Sopenharmony_ci} 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ci#endif /* _ASM_FPU_EMULATOR_H */ 188