Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * arch/sh/math-emu/math.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright (C) 2006 Takashi YOSHII <takasi-y@ops.dti.ne.jp>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * License.  See the file "COPYING" in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/sched/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/perf_event.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <asm/processor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include "sfp-util.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <math-emu/soft-fp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <math-emu/single.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <math-emu/double.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define	FPUL		(fregs->fpul)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define FPSCR		(fregs->fpscr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define FPSCR_RM	(FPSCR&3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define FPSCR_DN	((FPSCR>>18)&1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define FPSCR_PR	((FPSCR>>19)&1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define FPSCR_SZ	((FPSCR>>20)&1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define FPSCR_FR	((FPSCR>>21)&1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define FPSCR_MASK	0x003fffffUL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define BANK(n)	(n^(FPSCR_FR?16:0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define FR	((unsigned long*)(fregs->fp_regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #define FR0	(FR[BANK(0)])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define FRn	(FR[BANK(n)])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define FRm	(FR[BANK(m)])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #define DR	((unsigned long long*)(fregs->fp_regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #define DRn	(DR[BANK(n)/2])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #define DRm	(DR[BANK(m)/2])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #define XREG(n)	(n^16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #define XFn	(FR[BANK(XREG(n))])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #define XFm	(FR[BANK(XREG(m))])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) #define XDn	(DR[BANK(XREG(n))/2])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #define XDm	(DR[BANK(XREG(m))/2])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #define R0	(regs->regs[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #define Rn	(regs->regs[n])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) #define Rm	(regs->regs[m])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) #define WRITE(d,a)	({if(put_user(d, (typeof (d)*)a)) return -EFAULT;})
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) #define READ(d,a)	({if(get_user(d, (typeof (d)*)a)) return -EFAULT;})
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #define PACK_S(r,f)	FP_PACK_SP(&r,f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) #define UNPACK_S(f,r)	FP_UNPACK_SP(f,&r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) #define PACK_D(r,f) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	{u32 t[2]; FP_PACK_DP(t,f); ((u32*)&r)[0]=t[1]; ((u32*)&r)[1]=t[0];}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) #define UNPACK_D(f,r) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	{u32 t[2]; t[0]=((u32*)&r)[1]; t[1]=((u32*)&r)[0]; FP_UNPACK_DP(f,t);}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) // 2 args instructions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) #define BOTH_PRmn(op,x) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	FP_DECL_EX; if(FPSCR_PR) op(D,x,DRm,DRn); else op(S,x,FRm,FRn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) #define CMP_X(SZ,R,M,N) do{ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	FP_DECL_##SZ(Fm); FP_DECL_##SZ(Fn); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	UNPACK_##SZ(Fm, M); UNPACK_##SZ(Fn, N); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	FP_CMP_##SZ(R, Fn, Fm, 2); }while(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) #define EQ_X(SZ,R,M,N) do{ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	FP_DECL_##SZ(Fm); FP_DECL_##SZ(Fn); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	UNPACK_##SZ(Fm, M); UNPACK_##SZ(Fn, N); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	FP_CMP_EQ_##SZ(R, Fn, Fm); }while(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) #define CMP(OP) ({ int r; BOTH_PRmn(OP##_X,r); r; })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) fcmp_gt(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	if (CMP(CMP) > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		regs->sr |= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		regs->sr &= ~1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) fcmp_eq(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	if (CMP(CMP /*EQ*/) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		regs->sr |= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		regs->sr &= ~1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) #define ARITH_X(SZ,OP,M,N) do{ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	FP_DECL_##SZ(Fm); FP_DECL_##SZ(Fn); FP_DECL_##SZ(Fr); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	UNPACK_##SZ(Fm, M); UNPACK_##SZ(Fn, N); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	FP_##OP##_##SZ(Fr, Fn, Fm); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	PACK_##SZ(N, Fr); }while(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) fadd(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	BOTH_PRmn(ARITH_X, ADD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) fsub(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	BOTH_PRmn(ARITH_X, SUB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) fmul(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	BOTH_PRmn(ARITH_X, MUL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) fdiv(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	BOTH_PRmn(ARITH_X, DIV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) fmac(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	FP_DECL_EX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	FP_DECL_S(Fr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	FP_DECL_S(Ft);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	FP_DECL_S(F0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	FP_DECL_S(Fm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	FP_DECL_S(Fn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	UNPACK_S(F0, FR0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	UNPACK_S(Fm, FRm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	UNPACK_S(Fn, FRn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	FP_MUL_S(Ft, Fm, F0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	FP_ADD_S(Fr, Fn, Ft);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	PACK_S(FRn, Fr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) // to process fmov's extension (odd n for DR access XD).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #define FMOV_EXT(x) if(x&1) x+=16-1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) fmov_idx_reg(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	     int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	if (FPSCR_SZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		FMOV_EXT(n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		READ(FRn, Rm + R0 + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		n++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		READ(FRn, Rm + R0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		READ(FRn, Rm + R0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) fmov_mem_reg(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	     int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	if (FPSCR_SZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 		FMOV_EXT(n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 		READ(FRn, Rm + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 		n++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 		READ(FRn, Rm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 		READ(FRn, Rm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) fmov_inc_reg(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	     int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	if (FPSCR_SZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		FMOV_EXT(n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		READ(FRn, Rm + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 		n++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 		READ(FRn, Rm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 		Rm += 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		READ(FRn, Rm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 		Rm += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) fmov_reg_idx(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	     int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	if (FPSCR_SZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 		FMOV_EXT(m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 		WRITE(FRm, Rn + R0 + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		m++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		WRITE(FRm, Rn + R0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 		WRITE(FRm, Rn + R0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) fmov_reg_mem(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	     int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	if (FPSCR_SZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		FMOV_EXT(m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		WRITE(FRm, Rn + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		m++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		WRITE(FRm, Rn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		WRITE(FRm, Rn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) fmov_reg_dec(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	     int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	if (FPSCR_SZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		FMOV_EXT(m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		Rn -= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		WRITE(FRm, Rn + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		m++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		WRITE(FRm, Rn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		Rn -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 		WRITE(FRm, Rn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) fmov_reg_reg(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	     int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	if (FPSCR_SZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		FMOV_EXT(m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 		FMOV_EXT(n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		DRn = DRm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 		FRn = FRm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) fnop_mn(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) // 1 arg instructions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) #define NOTYETn(i) static int i(struct sh_fpu_soft_struct *fregs, int n) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	{ printk( #i " not yet done.\n"); return 0; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) NOTYETn(ftrv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) NOTYETn(fsqrt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) NOTYETn(fipr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) NOTYETn(fsca)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) NOTYETn(fsrra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) #define EMU_FLOAT_X(SZ,N) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	FP_DECL_##SZ(Fn); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	FP_FROM_INT_##SZ(Fn, FPUL, 32, int); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	PACK_##SZ(N, Fn); }while(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) static int ffloat(struct sh_fpu_soft_struct *fregs, int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	FP_DECL_EX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	if (FPSCR_PR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 		EMU_FLOAT_X(D, DRn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		EMU_FLOAT_X(S, FRn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) #define EMU_FTRC_X(SZ,N) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	FP_DECL_##SZ(Fn); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	UNPACK_##SZ(Fn, N); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	FP_TO_INT_##SZ(FPUL, Fn, 32, 1); }while(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) static int ftrc(struct sh_fpu_soft_struct *fregs, int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	FP_DECL_EX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	if (FPSCR_PR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		EMU_FTRC_X(D, DRn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 		EMU_FTRC_X(S, FRn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static int fcnvsd(struct sh_fpu_soft_struct *fregs, int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	FP_DECL_EX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	FP_DECL_S(Fn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	FP_DECL_D(Fr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	UNPACK_S(Fn, FPUL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	FP_CONV(D, S, 2, 1, Fr, Fn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	PACK_D(DRn, Fr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) static int fcnvds(struct sh_fpu_soft_struct *fregs, int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	FP_DECL_EX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	FP_DECL_D(Fn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	FP_DECL_S(Fr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	UNPACK_D(Fn, DRn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	FP_CONV(S, D, 1, 2, Fr, Fn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	PACK_S(FPUL, Fr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) static int fxchg(struct sh_fpu_soft_struct *fregs, int flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	FPSCR ^= flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) static int fsts(struct sh_fpu_soft_struct *fregs, int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	FRn = FPUL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) static int flds(struct sh_fpu_soft_struct *fregs, int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	FPUL = FRn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) static int fneg(struct sh_fpu_soft_struct *fregs, int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	FRn ^= (1 << (_FP_W_TYPE_SIZE - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) static int fabs(struct sh_fpu_soft_struct *fregs, int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	FRn &= ~(1 << (_FP_W_TYPE_SIZE - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) static int fld0(struct sh_fpu_soft_struct *fregs, int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	FRn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) static int fld1(struct sh_fpu_soft_struct *fregs, int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	FRn = (_FP_EXPBIAS_S << (_FP_FRACBITS_S - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) static int fnop_n(struct sh_fpu_soft_struct *fregs, int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) /// Instruction decoders.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) static int id_fxfd(struct sh_fpu_soft_struct *, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) static int id_fnxd(struct sh_fpu_soft_struct *, struct pt_regs *, int, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) static int (*fnxd[])(struct sh_fpu_soft_struct *, int) = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	fsts, flds, ffloat, ftrc, fneg, fabs, fsqrt, fsrra,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	fld0, fld1, fcnvsd, fcnvds, fnop_n, fnop_n, fipr, id_fxfd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) static int (*fnmx[])(struct sh_fpu_soft_struct *, struct pt_regs *, int, int) = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	fadd, fsub, fmul, fdiv, fcmp_eq, fcmp_gt, fmov_idx_reg, fmov_reg_idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	fmov_mem_reg, fmov_inc_reg, fmov_reg_mem, fmov_reg_dec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	fmov_reg_reg, id_fnxd, fmac, fnop_mn};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) static int id_fxfd(struct sh_fpu_soft_struct *fregs, int x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	const int flag[] = { FPSCR_SZ, FPSCR_PR, FPSCR_FR, 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	switch (x & 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 		fxchg(fregs, flag[x >> 2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 		ftrv(fregs, x - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 		fsca(fregs, x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) id_fnxd(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int x, int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	return (fnxd[x])(fregs, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) id_fnmx(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, u16 code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	int n = (code >> 8) & 0xf, m = (code >> 4) & 0xf, x = code & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	return (fnmx[x])(fregs, regs, m, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) id_sys(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, u16 code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	int n = ((code >> 8) & 0xf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	unsigned long *reg = (code & 0x0010) ? &FPUL : &FPSCR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	switch (code & 0xf0ff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	case 0x005a:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	case 0x006a:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 		Rn = *reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	case 0x405a:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	case 0x406a:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 		*reg = Rn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	case 0x4052:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	case 0x4062:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 		Rn -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 		WRITE(*reg, Rn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	case 0x4056:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	case 0x4066:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 		READ(*reg, Rn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 		Rn += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) static int fpu_emulate(u16 code, struct sh_fpu_soft_struct *fregs, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	if ((code & 0xf000) == 0xf000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 		return id_fnmx(fregs, regs, code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 		return id_sys(fregs, regs, code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)  * fpu_init - Initialize FPU registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)  * @fpu: Pointer to software emulated FPU registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) static void fpu_init(struct sh_fpu_soft_struct *fpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	fpu->fpscr = FPSCR_INIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	fpu->fpul = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	for (i = 0; i < 16; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 		fpu->fp_regs[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 		fpu->xfp_regs[i]= 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)  * do_fpu_inst - Handle reserved instructions for FPU emulation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)  * @inst: instruction code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)  * @regs: registers on stack.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) int do_fpu_inst(unsigned short inst, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	struct task_struct *tsk = current;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	struct sh_fpu_soft_struct *fpu = &(tsk->thread.xstate->softfpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	if (!(task_thread_info(tsk)->status & TS_USEDFPU)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 		/* initialize once. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 		fpu_init(fpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 		task_thread_info(tsk)->status |= TS_USEDFPU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	return fpu_emulate(inst, fpu, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }