1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef __ASM_ALPHA_FPU_H 3 #define __ASM_ALPHA_FPU_H 4 5 #include <asm/special_insns.h> 6 #include <uapi/asm/fpu.h> 7 8 /* The following two functions don't need trapb/excb instructions 9 around the mf_fpcr/mt_fpcr instructions because (a) the kernel 10 never generates arithmetic faults and (b) call_pal instructions 11 are implied trap barriers. */ 12 13 static inline unsigned long 14 rdfpcr(void) 15 { 16 unsigned long tmp, ret; 17 18 #if defined(CONFIG_ALPHA_EV6) || defined(CONFIG_ALPHA_EV67) 19 __asm__ __volatile__ ( 20 "ftoit $f0,%0\n\t" 21 "mf_fpcr $f0\n\t" 22 "ftoit $f0,%1\n\t" 23 "itoft %0,$f0" 24 : "=r"(tmp), "=r"(ret)); 25 #else 26 __asm__ __volatile__ ( 27 "stt $f0,%0\n\t" 28 "mf_fpcr $f0\n\t" 29 "stt $f0,%1\n\t" 30 "ldt $f0,%0" 31 : "=m"(tmp), "=m"(ret)); 32 #endif 33 34 return ret; 35 } 36 37 static inline void 38 wrfpcr(unsigned long val) 39 { 40 unsigned long tmp; 41 42 #if defined(CONFIG_ALPHA_EV6) || defined(CONFIG_ALPHA_EV67) 43 __asm__ __volatile__ ( 44 "ftoit $f0,%0\n\t" 45 "itoft %1,$f0\n\t" 46 "mt_fpcr $f0\n\t" 47 "itoft %0,$f0" 48 : "=&r"(tmp) : "r"(val)); 49 #else 50 __asm__ __volatile__ ( 51 "stt $f0,%0\n\t" 52 "ldt $f0,%1\n\t" 53 "mt_fpcr $f0\n\t" 54 "ldt $f0,%0" 55 : "=m"(tmp) : "m"(val)); 56 #endif 57 } 58 59 static inline unsigned long 60 swcr_update_status(unsigned long swcr, unsigned long fpcr) 61 { 62 /* EV6 implements most of the bits in hardware. Collect 63 the acrued exception bits from the real fpcr. */ 64 if (implver() == IMPLVER_EV6) { 65 swcr &= ~IEEE_STATUS_MASK; 66 swcr |= (fpcr >> 35) & IEEE_STATUS_MASK; 67 } 68 return swcr; 69 } 70 71 extern unsigned long alpha_read_fp_reg (unsigned long reg); 72 extern void alpha_write_fp_reg (unsigned long reg, unsigned long val); 73 extern unsigned long alpha_read_fp_reg_s (unsigned long reg); 74 extern void alpha_write_fp_reg_s (unsigned long reg, unsigned long val); 75 76 #endif /* __ASM_ALPHA_FPU_H */ 77