/*
 * arch/sh/math-emu/math.c
 *
 * Copyright (C) 2006 Takashi YOSHII <takasi-y@ops.dti.ne.jp>
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 */
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/perf_event.h>

#include <linux/uaccess.h>
#include <asm/processor.h>
#include <asm/io.h>

#include "sfp-util.h"
#include <math-emu/soft-fp.h>
#include <math-emu/single.h>
#include <math-emu/double.h>

#define	FPUL		(fregs->fpul)
#define FPSCR		(fregs->fpscr)
#define FPSCR_RM	(FPSCR&3)
#define FPSCR_DN	((FPSCR>>18)&1)
#define FPSCR_PR	((FPSCR>>19)&1)
#define FPSCR_SZ	((FPSCR>>20)&1)
#define FPSCR_FR	((FPSCR>>21)&1)
#define FPSCR_MASK	0x003fffffUL

#define BANK(n)	(n^(FPSCR_FR?16:0))
#define FR	((unsigned long*)(fregs->fp_regs))
#define FR0	(FR[BANK(0)])
#define FRn	(FR[BANK(n)])
#define FRm	(FR[BANK(m)])
#define DR	((unsigned long long*)(fregs->fp_regs))
#define DRn	(DR[BANK(n)/2])
#define DRm	(DR[BANK(m)/2])

#define XREG(n)	(n^16)
#define XFn	(FR[BANK(XREG(n))])
#define XFm	(FR[BANK(XREG(m))])
#define XDn	(DR[BANK(XREG(n))/2])
#define XDm	(DR[BANK(XREG(m))/2])

#define R0	(regs->regs[0])
#define Rn	(regs->regs[n])
#define Rm	(regs->regs[m])

#define WRITE(d,a)	({if(put_user(d, (typeof (d)*)a)) return -EFAULT;})
#define READ(d,a)	({if(get_user(d, (typeof (d)*)a)) return -EFAULT;})

#define PACK_S(r,f)	FP_PACK_SP(&r,f)
#define UNPACK_S(f,r)	FP_UNPACK_SP(f,&r)
#define PACK_D(r,f) \
	{u32 t[2]; FP_PACK_DP(t,f); ((u32*)&r)[0]=t[1]; ((u32*)&r)[1]=t[0];}
#define UNPACK_D(f,r) \
	{u32 t[2]; t[0]=((u32*)&r)[1]; t[1]=((u32*)&r)[0]; FP_UNPACK_DP(f,t);}

// 2 args instructions.
#define BOTH_PRmn(op,x) \
	FP_DECL_EX; if(FPSCR_PR) op(D,x,DRm,DRn); else op(S,x,FRm,FRn);

#define CMP_X(SZ,R,M,N) do{ \
	FP_DECL_##SZ(Fm); FP_DECL_##SZ(Fn); \
	UNPACK_##SZ(Fm, M); UNPACK_##SZ(Fn, N); \
	FP_CMP_##SZ(R, Fn, Fm, 2); }while(0)
#define EQ_X(SZ,R,M,N) do{ \
	FP_DECL_##SZ(Fm); FP_DECL_##SZ(Fn); \
	UNPACK_##SZ(Fm, M); UNPACK_##SZ(Fn, N); \
	FP_CMP_EQ_##SZ(R, Fn, Fm); }while(0)
#define CMP(OP) ({ int r; BOTH_PRmn(OP##_X,r); r; })

static int
fcmp_gt(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, int n)
{
	if (CMP(CMP) > 0)
		regs->sr |= 1;
	else
		regs->sr &= ~1;

	return 0;
}

static int
fcmp_eq(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, int n)
{
	if (CMP(CMP /*EQ*/) == 0)
		regs->sr |= 1;
	else
		regs->sr &= ~1;
	return 0;
}

#define ARITH_X(SZ,OP,M,N) do{ \
	FP_DECL_##SZ(Fm); FP_DECL_##SZ(Fn); FP_DECL_##SZ(Fr); \
	UNPACK_##SZ(Fm, M); UNPACK_##SZ(Fn, N); \
	FP_##OP##_##SZ(Fr, Fn, Fm); \
	PACK_##SZ(N, Fr); }while(0)

static int
fadd(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, int n)
{
	BOTH_PRmn(ARITH_X, ADD);
	return 0;
}

static int
fsub(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, int n)
{
	BOTH_PRmn(ARITH_X, SUB);
	return 0;
}

static int
fmul(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, int n)
{
	BOTH_PRmn(ARITH_X, MUL);
	return 0;
}

static int
fdiv(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, int n)
{
	BOTH_PRmn(ARITH_X, DIV);
	return 0;
}

static int
fmac(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, int n)
{
	FP_DECL_EX;
	FP_DECL_S(Fr);
	FP_DECL_S(Ft);
	FP_DECL_S(F0);
	FP_DECL_S(Fm);
	FP_DECL_S(Fn);
	UNPACK_S(F0, FR0);
	UNPACK_S(Fm, FRm);
	UNPACK_S(Fn, FRn);
	FP_MUL_S(Ft, Fm, F0);
	FP_ADD_S(Fr, Fn, Ft);
	PACK_S(FRn, Fr);
	return 0;
}

// to process fmov's extension (odd n for DR access XD).
#define FMOV_EXT(x) if(x&1) x+=16-1

static int
fmov_idx_reg(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m,
	     int n)
{
	if (FPSCR_SZ) {
		FMOV_EXT(n);
		READ(FRn, Rm + R0 + 4);
		n++;
		READ(FRn, Rm + R0);
	} else {
		READ(FRn, Rm + R0);
	}

	return 0;
}

static int
fmov_mem_reg(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m,
	     int n)
{
	if (FPSCR_SZ) {
		FMOV_EXT(n);
		READ(FRn, Rm + 4);
		n++;
		READ(FRn, Rm);
	} else {
		READ(FRn, Rm);
	}

	return 0;
}

static int
fmov_inc_reg(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m,
	     int n)
{
	if (FPSCR_SZ) {
		FMOV_EXT(n);
		READ(FRn, Rm + 4);
		n++;
		READ(FRn, Rm);
		Rm += 8;
	} else {
		READ(FRn, Rm);
		Rm += 4;
	}

	return 0;
}

static int
fmov_reg_idx(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m,
	     int n)
{
	if (FPSCR_SZ) {
		FMOV_EXT(m);
		WRITE(FRm, Rn + R0 + 4);
		m++;
		WRITE(FRm, Rn + R0);
	} else {
		WRITE(FRm, Rn + R0);
	}

	return 0;
}

static int
fmov_reg_mem(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m,
	     int n)
{
	if (FPSCR_SZ) {
		FMOV_EXT(m);
		WRITE(FRm, Rn + 4);
		m++;
		WRITE(FRm, Rn);
	} else {
		WRITE(FRm, Rn);
	}

	return 0;
}

static int
fmov_reg_dec(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m,
	     int n)
{
	if (FPSCR_SZ) {
		FMOV_EXT(m);
		Rn -= 8;
		WRITE(FRm, Rn + 4);
		m++;
		WRITE(FRm, Rn);
	} else {
		Rn -= 4;
		WRITE(FRm, Rn);
	}

	return 0;
}

static int
fmov_reg_reg(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m,
	     int n)
{
	if (FPSCR_SZ) {
		FMOV_EXT(m);
		FMOV_EXT(n);
		DRn = DRm;
	} else {
		FRn = FRm;
	}

	return 0;
}

static int
fnop_mn(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, int n)
{
	return -EINVAL;
}

// 1 arg instructions.
#define NOTYETn(i) static int i(struct sh_fpu_soft_struct *fregs, int n) \
	{ printk( #i " not yet done.\n"); return 0; }

NOTYETn(ftrv)
NOTYETn(fsqrt)
NOTYETn(fipr)
NOTYETn(fsca)
NOTYETn(fsrra)

#define EMU_FLOAT_X(SZ,N) do { \
	FP_DECL_##SZ(Fn); \
	FP_FROM_INT_##SZ(Fn, FPUL, 32, int); \
	PACK_##SZ(N, Fn); }while(0)
static int ffloat(struct sh_fpu_soft_struct *fregs, int n)
{
	FP_DECL_EX;

	if (FPSCR_PR)
		EMU_FLOAT_X(D, DRn);
	else
		EMU_FLOAT_X(S, FRn);

	return 0;
}

#define EMU_FTRC_X(SZ,N) do { \
	FP_DECL_##SZ(Fn); \
	UNPACK_##SZ(Fn, N); \
	FP_TO_INT_##SZ(FPUL, Fn, 32, 1); }while(0)
static int ftrc(struct sh_fpu_soft_struct *fregs, int n)
{
	FP_DECL_EX;

	if (FPSCR_PR)
		EMU_FTRC_X(D, DRn);
	else
		EMU_FTRC_X(S, FRn);

	return 0;
}

static int fcnvsd(struct sh_fpu_soft_struct *fregs, int n)
{
	FP_DECL_EX;
	FP_DECL_S(Fn);
	FP_DECL_D(Fr);
	UNPACK_S(Fn, FPUL);
	FP_CONV(D, S, 2, 1, Fr, Fn);
	PACK_D(DRn, Fr);
	return 0;
}

static int fcnvds(struct sh_fpu_soft_struct *fregs, int n)
{
	FP_DECL_EX;
	FP_DECL_D(Fn);
	FP_DECL_S(Fr);
	UNPACK_D(Fn, DRn);
	FP_CONV(S, D, 1, 2, Fr, Fn);
	PACK_S(FPUL, Fr);
	return 0;
}

static int fxchg(struct sh_fpu_soft_struct *fregs, int flag)
{
	FPSCR ^= flag;
	return 0;
}

static int fsts(struct sh_fpu_soft_struct *fregs, int n)
{
	FRn = FPUL;
	return 0;
}

static int flds(struct sh_fpu_soft_struct *fregs, int n)
{
	FPUL = FRn;
	return 0;
}

static int fneg(struct sh_fpu_soft_struct *fregs, int n)
{
	FRn ^= (1 << (_FP_W_TYPE_SIZE - 1));
	return 0;
}

static int fabs(struct sh_fpu_soft_struct *fregs, int n)
{
	FRn &= ~(1 << (_FP_W_TYPE_SIZE - 1));
	return 0;
}

static int fld0(struct sh_fpu_soft_struct *fregs, int n)
{
	FRn = 0;
	return 0;
}

static int fld1(struct sh_fpu_soft_struct *fregs, int n)
{
	FRn = (_FP_EXPBIAS_S << (_FP_FRACBITS_S - 1));
	return 0;
}

static int fnop_n(struct sh_fpu_soft_struct *fregs, int n)
{
	return -EINVAL;
}

/// Instruction decoders.

static int id_fxfd(struct sh_fpu_soft_struct *, int);
static int id_fnxd(struct sh_fpu_soft_struct *, struct pt_regs *, int, int);

static int (*fnxd[])(struct sh_fpu_soft_struct *, int) = {
	fsts, flds, ffloat, ftrc, fneg, fabs, fsqrt, fsrra,
	fld0, fld1, fcnvsd, fcnvds, fnop_n, fnop_n, fipr, id_fxfd
};

static int (*fnmx[])(struct sh_fpu_soft_struct *, struct pt_regs *, int, int) = {
	fadd, fsub, fmul, fdiv, fcmp_eq, fcmp_gt, fmov_idx_reg, fmov_reg_idx,
	fmov_mem_reg, fmov_inc_reg, fmov_reg_mem, fmov_reg_dec,
	fmov_reg_reg, id_fnxd, fmac, fnop_mn};

static int id_fxfd(struct sh_fpu_soft_struct *fregs, int x)
{
	const int flag[] = { FPSCR_SZ, FPSCR_PR, FPSCR_FR, 0 };
	switch (x & 3) {
	case 3:
		fxchg(fregs, flag[x >> 2]);
		break;
	case 1:
		ftrv(fregs, x - 1);
		break;
	default:
		fsca(fregs, x);
	}
	return 0;
}

static int
id_fnxd(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int x, int n)
{
	return (fnxd[x])(fregs, n);
}

static int
id_fnmx(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, u16 code)
{
	int n = (code >> 8) & 0xf, m = (code >> 4) & 0xf, x = code & 0xf;
	return (fnmx[x])(fregs, regs, m, n);
}

static int
id_sys(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, u16 code)
{
	int n = ((code >> 8) & 0xf);
	unsigned long *reg = (code & 0x0010) ? &FPUL : &FPSCR;

	switch (code & 0xf0ff) {
	case 0x005a:
	case 0x006a:
		Rn = *reg;
		break;
	case 0x405a:
	case 0x406a:
		*reg = Rn;
		break;
	case 0x4052:
	case 0x4062:
		Rn -= 4;
		WRITE(*reg, Rn);
		break;
	case 0x4056:
	case 0x4066:
		READ(*reg, Rn);
		Rn += 4;
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static int fpu_emulate(u16 code, struct sh_fpu_soft_struct *fregs, struct pt_regs *regs)
{
	if ((code & 0xf000) == 0xf000)
		return id_fnmx(fregs, regs, code);
	else
		return id_sys(fregs, regs, code);
}

/**
 *	denormal_to_double - Given denormalized float number,
 *	                     store double float
 *
 *	@fpu: Pointer to sh_fpu_soft structure
 *	@n: Index to FP register
 */
static void denormal_to_double(struct sh_fpu_soft_struct *fpu, int n)
{
	unsigned long du, dl;
	unsigned long x = fpu->fpul;
	int exp = 1023 - 126;

	if (x != 0 && (x & 0x7f800000) == 0) {
		du = (x & 0x80000000);
		while ((x & 0x00800000) == 0) {
			x <<= 1;
			exp--;
		}
		x &= 0x007fffff;
		du |= (exp << 20) | (x >> 3);
		dl = x << 29;

		fpu->fp_regs[n] = du;
		fpu->fp_regs[n+1] = dl;
	}
}

/**
 *	ieee_fpe_handler - Handle denormalized number exception
 *
 *	@regs: Pointer to register structure
 *
 *	Returns 1 when it's handled (should not cause exception).
 */
static int ieee_fpe_handler(struct pt_regs *regs)
{
	unsigned short insn = *(unsigned short *)regs->pc;
	unsigned short finsn;
	unsigned long nextpc;
	siginfo_t info;
	int nib[4] = {
		(insn >> 12) & 0xf,
		(insn >> 8) & 0xf,
		(insn >> 4) & 0xf,
		insn & 0xf};

	if (nib[0] == 0xb ||
	    (nib[0] == 0x4 && nib[2] == 0x0 && nib[3] == 0xb)) /* bsr & jsr */
		regs->pr = regs->pc + 4;

	if (nib[0] == 0xa || nib[0] == 0xb) { /* bra & bsr */
		nextpc = regs->pc + 4 + ((short) ((insn & 0xfff) << 4) >> 3);
		finsn = *(unsigned short *) (regs->pc + 2);
	} else if (nib[0] == 0x8 && nib[1] == 0xd) { /* bt/s */
		if (regs->sr & 1)
			nextpc = regs->pc + 4 + ((char) (insn & 0xff) << 1);
		else
			nextpc = regs->pc + 4;
		finsn = *(unsigned short *) (regs->pc + 2);
	} else if (nib[0] == 0x8 && nib[1] == 0xf) { /* bf/s */
		if (regs->sr & 1)
			nextpc = regs->pc + 4;
		else
			nextpc = regs->pc + 4 + ((char) (insn & 0xff) << 1);
		finsn = *(unsigned short *) (regs->pc + 2);
	} else if (nib[0] == 0x4 && nib[3] == 0xb &&
		 (nib[2] == 0x0 || nib[2] == 0x2)) { /* jmp & jsr */
		nextpc = regs->regs[nib[1]];
		finsn = *(unsigned short *) (regs->pc + 2);
	} else if (nib[0] == 0x0 && nib[3] == 0x3 &&
		 (nib[2] == 0x0 || nib[2] == 0x2)) { /* braf & bsrf */
		nextpc = regs->pc + 4 + regs->regs[nib[1]];
		finsn = *(unsigned short *) (regs->pc + 2);
	} else if (insn == 0x000b) { /* rts */
		nextpc = regs->pr;
		finsn = *(unsigned short *) (regs->pc + 2);
	} else {
		nextpc = regs->pc + 2;
		finsn = insn;
	}

	if ((finsn & 0xf1ff) == 0xf0ad) { /* fcnvsd */
		struct task_struct *tsk = current;

		if ((tsk->thread.xstate->softfpu.fpscr & (1 << 17))) {
			/* FPU error */
			denormal_to_double (&tsk->thread.xstate->softfpu,
					    (finsn >> 8) & 0xf);
			tsk->thread.xstate->softfpu.fpscr &=
				~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK);
			task_thread_info(tsk)->status |= TS_USEDFPU;
		} else {
			info.si_signo = SIGFPE;
			info.si_errno = 0;
			info.si_code = FPE_FLTINV;
			info.si_addr = (void __user *)regs->pc;
			force_sig_info(SIGFPE, &info, tsk);
		}

		regs->pc = nextpc;
		return 1;
	}

	return 0;
}

/**
 * fpu_init - Initialize FPU registers
 * @fpu: Pointer to software emulated FPU registers.
 */
static void fpu_init(struct sh_fpu_soft_struct *fpu)
{
	int i;

	fpu->fpscr = FPSCR_INIT;
	fpu->fpul = 0;

	for (i = 0; i < 16; i++) {
		fpu->fp_regs[i] = 0;
		fpu->xfp_regs[i]= 0;
	}
}

/**
 * do_fpu_inst - Handle reserved instructions for FPU emulation
 * @inst: instruction code.
 * @regs: registers on stack.
 */
int do_fpu_inst(unsigned short inst, struct pt_regs *regs)
{
	struct task_struct *tsk = current;
	struct sh_fpu_soft_struct *fpu = &(tsk->thread.xstate->softfpu);

	perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, 0);

	if (!(task_thread_info(tsk)->status & TS_USEDFPU)) {
		/* initialize once. */
		fpu_init(fpu);
		task_thread_info(tsk)->status |= TS_USEDFPU;
	}

	return fpu_emulate(inst, fpu, regs);
}
