18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef __ASM_ALPHA_FPU_H 38c2ecf20Sopenharmony_ci#define __ASM_ALPHA_FPU_H 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#include <asm/special_insns.h> 68c2ecf20Sopenharmony_ci#include <uapi/asm/fpu.h> 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci/* The following two functions don't need trapb/excb instructions 98c2ecf20Sopenharmony_ci around the mf_fpcr/mt_fpcr instructions because (a) the kernel 108c2ecf20Sopenharmony_ci never generates arithmetic faults and (b) call_pal instructions 118c2ecf20Sopenharmony_ci are implied trap barriers. */ 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_cistatic inline unsigned long 148c2ecf20Sopenharmony_cirdfpcr(void) 158c2ecf20Sopenharmony_ci{ 168c2ecf20Sopenharmony_ci unsigned long tmp, ret; 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#if defined(CONFIG_ALPHA_EV6) || defined(CONFIG_ALPHA_EV67) 198c2ecf20Sopenharmony_ci __asm__ __volatile__ ( 208c2ecf20Sopenharmony_ci "ftoit $f0,%0\n\t" 218c2ecf20Sopenharmony_ci "mf_fpcr $f0\n\t" 228c2ecf20Sopenharmony_ci "ftoit $f0,%1\n\t" 238c2ecf20Sopenharmony_ci "itoft %0,$f0" 248c2ecf20Sopenharmony_ci : "=r"(tmp), "=r"(ret)); 258c2ecf20Sopenharmony_ci#else 268c2ecf20Sopenharmony_ci __asm__ __volatile__ ( 278c2ecf20Sopenharmony_ci "stt $f0,%0\n\t" 288c2ecf20Sopenharmony_ci "mf_fpcr $f0\n\t" 298c2ecf20Sopenharmony_ci "stt $f0,%1\n\t" 308c2ecf20Sopenharmony_ci "ldt $f0,%0" 318c2ecf20Sopenharmony_ci : "=m"(tmp), "=m"(ret)); 328c2ecf20Sopenharmony_ci#endif 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci return ret; 358c2ecf20Sopenharmony_ci} 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_cistatic inline void 388c2ecf20Sopenharmony_ciwrfpcr(unsigned long val) 398c2ecf20Sopenharmony_ci{ 408c2ecf20Sopenharmony_ci unsigned long tmp; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci#if defined(CONFIG_ALPHA_EV6) || defined(CONFIG_ALPHA_EV67) 438c2ecf20Sopenharmony_ci __asm__ __volatile__ ( 448c2ecf20Sopenharmony_ci "ftoit $f0,%0\n\t" 458c2ecf20Sopenharmony_ci "itoft %1,$f0\n\t" 468c2ecf20Sopenharmony_ci "mt_fpcr $f0\n\t" 478c2ecf20Sopenharmony_ci "itoft %0,$f0" 488c2ecf20Sopenharmony_ci : "=&r"(tmp) : "r"(val)); 498c2ecf20Sopenharmony_ci#else 508c2ecf20Sopenharmony_ci __asm__ __volatile__ ( 518c2ecf20Sopenharmony_ci "stt $f0,%0\n\t" 528c2ecf20Sopenharmony_ci "ldt $f0,%1\n\t" 538c2ecf20Sopenharmony_ci "mt_fpcr $f0\n\t" 548c2ecf20Sopenharmony_ci "ldt $f0,%0" 558c2ecf20Sopenharmony_ci : "=m"(tmp) : "m"(val)); 568c2ecf20Sopenharmony_ci#endif 578c2ecf20Sopenharmony_ci} 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_cistatic inline unsigned long 608c2ecf20Sopenharmony_ciswcr_update_status(unsigned long swcr, unsigned long fpcr) 618c2ecf20Sopenharmony_ci{ 628c2ecf20Sopenharmony_ci /* EV6 implements most of the bits in hardware. Collect 638c2ecf20Sopenharmony_ci the acrued exception bits from the real fpcr. */ 648c2ecf20Sopenharmony_ci if (implver() == IMPLVER_EV6) { 658c2ecf20Sopenharmony_ci swcr &= ~IEEE_STATUS_MASK; 668c2ecf20Sopenharmony_ci swcr |= (fpcr >> 35) & IEEE_STATUS_MASK; 678c2ecf20Sopenharmony_ci } 688c2ecf20Sopenharmony_ci return swcr; 698c2ecf20Sopenharmony_ci} 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ciextern unsigned long alpha_read_fp_reg (unsigned long reg); 728c2ecf20Sopenharmony_ciextern void alpha_write_fp_reg (unsigned long reg, unsigned long val); 738c2ecf20Sopenharmony_ciextern unsigned long alpha_read_fp_reg_s (unsigned long reg); 748c2ecf20Sopenharmony_ciextern void alpha_write_fp_reg_s (unsigned long reg, unsigned long val); 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci#endif /* __ASM_ALPHA_FPU_H */ 77