/*
 * 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.
 *
 * Copyright (C) 1996, 97, 2000, 2001 by Ralf Baechle
 * Copyright (C) 2001 MIPS Technologies, Inc.
 */
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/module.h>
#include <asm/branch.h>
#include <asm/cpu.h>
#include <asm/cpu-features.h>
#include <asm/fpu.h>
#include <asm/fpu_emulator.h>
#include <asm/inst.h>
#include <asm/ptrace.h>
#include <asm/uaccess.h>

/*
 * Calculate and return exception PC in case of branch delay slot
 * for microMIPS and MIPS16e. It does not clear the ISA mode bit.
 */
int __isa_exception_epc(struct pt_regs *regs)
{
	unsigned short inst;
	long epc = regs->cp0_epc;

	/* Calculate exception PC in branch delay slot. */
	if (__get_user(inst, (u16 __user *) msk_isa16_mode(epc))) {
		/* This should never happen because delay slot was checked. */
		force_sig(SIGSEGV, current);
		return epc;
	}
	if (cpu_has_mips16) {
		if (((union mips16e_instruction)inst).ri.opcode
				== MIPS16e_jal_op)
			epc += 4;
		else
			epc += 2;
	} else if (mm_insn_16bit(inst))
		epc += 2;
	else
		epc += 4;

	return epc;
}

/* (microMIPS) Convert 16-bit register encoding to 32-bit register encoding. */
static const unsigned int reg16to32map[8] = {16, 17, 2, 3, 4, 5, 6, 7};

int __mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
		       unsigned long *contpc)
{
	union mips_instruction insn = (union mips_instruction)dec_insn.insn;
	int bc_false = 0;
	unsigned int fcr31;
	unsigned int bit;

	if (!cpu_has_mmips)
		return 0;

	switch (insn.mm_i_format.opcode) {
	case mm_pool32a_op:
		if ((insn.mm_i_format.simmediate & MM_POOL32A_MINOR_MASK) ==
		    mm_pool32axf_op) {
			switch (insn.mm_i_format.simmediate >>
				MM_POOL32A_MINOR_SHIFT) {
			case mm_jalr_op:
			case mm_jalrhb_op:
			case mm_jalrs_op:
			case mm_jalrshb_op:
				if (insn.mm_i_format.rt != 0)	/* Not mm_jr */
					regs->regs[insn.mm_i_format.rt] =
						regs->cp0_epc +
						dec_insn.pc_inc +
						dec_insn.next_pc_inc;
				*contpc = regs->regs[insn.mm_i_format.rs];
				return 1;
			}
		}
		break;
	case mm_pool32i_op:
		switch (insn.mm_i_format.rt) {
		case mm_bltzals_op:
		case mm_bltzal_op:
			regs->regs[31] = regs->cp0_epc +
				dec_insn.pc_inc +
				dec_insn.next_pc_inc;
			/* Fall through */
		case mm_bltz_op:
			if ((long)regs->regs[insn.mm_i_format.rs] < 0)
				*contpc = regs->cp0_epc +
					dec_insn.pc_inc +
					(insn.mm_i_format.simmediate << 1);
			else
				*contpc = regs->cp0_epc +
					dec_insn.pc_inc +
					dec_insn.next_pc_inc;
			return 1;
		case mm_bgezals_op:
		case mm_bgezal_op:
			regs->regs[31] = regs->cp0_epc +
					dec_insn.pc_inc +
					dec_insn.next_pc_inc;
			/* Fall through */
		case mm_bgez_op:
			if ((long)regs->regs[insn.mm_i_format.rs] >= 0)
				*contpc = regs->cp0_epc +
					dec_insn.pc_inc +
					(insn.mm_i_format.simmediate << 1);
			else
				*contpc = regs->cp0_epc +
					dec_insn.pc_inc +
					dec_insn.next_pc_inc;
			return 1;
		case mm_blez_op:
			if ((long)regs->regs[insn.mm_i_format.rs] <= 0)
				*contpc = regs->cp0_epc +
					dec_insn.pc_inc +
					(insn.mm_i_format.simmediate << 1);
			else
				*contpc = regs->cp0_epc +
					dec_insn.pc_inc +
					dec_insn.next_pc_inc;
			return 1;
		case mm_bgtz_op:
			if ((long)regs->regs[insn.mm_i_format.rs] <= 0)
				*contpc = regs->cp0_epc +
					dec_insn.pc_inc +
					(insn.mm_i_format.simmediate << 1);
			else
				*contpc = regs->cp0_epc +
					dec_insn.pc_inc +
					dec_insn.next_pc_inc;
			return 1;
		case mm_bc2f_op:
		case mm_bc1f_op:
			bc_false = 1;
			/* Fall through */
		case mm_bc2t_op:
		case mm_bc1t_op:
			preempt_disable();
			if (is_fpu_owner())
				asm volatile("cfc1\t%0,$31" : "=r" (fcr31));
			else
				fcr31 = current->thread.fpu.fcr31;
			preempt_enable();

			if (bc_false)
				fcr31 = ~fcr31;

			bit = (insn.mm_i_format.rs >> 2);
			bit += (bit != 0);
			bit += 23;
			if (fcr31 & (1 << bit))
				*contpc = regs->cp0_epc +
					dec_insn.pc_inc +
					(insn.mm_i_format.simmediate << 1);
			else
				*contpc = regs->cp0_epc +
					dec_insn.pc_inc + dec_insn.next_pc_inc;
			return 1;
		}
		break;
	case mm_pool16c_op:
		switch (insn.mm_i_format.rt) {
		case mm_jalr16_op:
		case mm_jalrs16_op:
			regs->regs[31] = regs->cp0_epc +
				dec_insn.pc_inc + dec_insn.next_pc_inc;
			/* Fall through */
		case mm_jr16_op:
			*contpc = regs->regs[insn.mm_i_format.rs];
			return 1;
		}
		break;
	case mm_beqz16_op:
		if ((long)regs->regs[reg16to32map[insn.mm_b1_format.rs]] == 0)
			*contpc = regs->cp0_epc +
				dec_insn.pc_inc +
				(insn.mm_b1_format.simmediate << 1);
		else
			*contpc = regs->cp0_epc +
				dec_insn.pc_inc + dec_insn.next_pc_inc;
		return 1;
	case mm_bnez16_op:
		if ((long)regs->regs[reg16to32map[insn.mm_b1_format.rs]] != 0)
			*contpc = regs->cp0_epc +
				dec_insn.pc_inc +
				(insn.mm_b1_format.simmediate << 1);
		else
			*contpc = regs->cp0_epc +
				dec_insn.pc_inc + dec_insn.next_pc_inc;
		return 1;
	case mm_b16_op:
		*contpc = regs->cp0_epc + dec_insn.pc_inc +
			 (insn.mm_b0_format.simmediate << 1);
		return 1;
	case mm_beq32_op:
		if (regs->regs[insn.mm_i_format.rs] ==
		    regs->regs[insn.mm_i_format.rt])
			*contpc = regs->cp0_epc +
				dec_insn.pc_inc +
				(insn.mm_i_format.simmediate << 1);
		else
			*contpc = regs->cp0_epc +
				dec_insn.pc_inc +
				dec_insn.next_pc_inc;
		return 1;
	case mm_bne32_op:
		if (regs->regs[insn.mm_i_format.rs] !=
		    regs->regs[insn.mm_i_format.rt])
			*contpc = regs->cp0_epc +
				dec_insn.pc_inc +
				(insn.mm_i_format.simmediate << 1);
		else
			*contpc = regs->cp0_epc +
				dec_insn.pc_inc + dec_insn.next_pc_inc;
		return 1;
	case mm_jalx32_op:
		regs->regs[31] = regs->cp0_epc +
			dec_insn.pc_inc + dec_insn.next_pc_inc;
		*contpc = regs->cp0_epc + dec_insn.pc_inc;
		*contpc >>= 28;
		*contpc <<= 28;
		*contpc |= (insn.j_format.target << 2);
		return 1;
	case mm_jals32_op:
	case mm_jal32_op:
		regs->regs[31] = regs->cp0_epc +
			dec_insn.pc_inc + dec_insn.next_pc_inc;
		/* Fall through */
	case mm_j32_op:
		*contpc = regs->cp0_epc + dec_insn.pc_inc;
		*contpc >>= 27;
		*contpc <<= 27;
		*contpc |= (insn.j_format.target << 1);
		set_isa16_mode(*contpc);
		return 1;
	}
	return 0;
}

/*
 * Compute return address and emulate branch in microMIPS mode after an
 * exception only. It does not handle compact branches/jumps and cannot
 * be used in interrupt context. (Compact branches/jumps do not cause
 * exceptions.)
 */
int __microMIPS_compute_return_epc(struct pt_regs *regs)
{
	u16 __user *pc16;
	u16 halfword;
	unsigned int word;
	unsigned long contpc;
	struct mm_decoded_insn mminsn = { 0 };

	mminsn.micro_mips_mode = 1;

	/* This load never faults. */
	pc16 = (unsigned short __user *)msk_isa16_mode(regs->cp0_epc);
	__get_user(halfword, pc16);
	pc16++;
	contpc = regs->cp0_epc + 2;
	word = ((unsigned int)halfword << 16);
	mminsn.pc_inc = 2;

	if (!mm_insn_16bit(halfword)) {
		__get_user(halfword, pc16);
		pc16++;
		contpc = regs->cp0_epc + 4;
		mminsn.pc_inc = 4;
		word |= halfword;
	}
	mminsn.insn = word;

	if (get_user(halfword, pc16))
		goto sigsegv;
	mminsn.next_pc_inc = 2;
	word = ((unsigned int)halfword << 16);

	if (!mm_insn_16bit(halfword)) {
		pc16++;
		if (get_user(halfword, pc16))
			goto sigsegv;
		mminsn.next_pc_inc = 4;
		word |= halfword;
	}
	mminsn.next_insn = word;

	mm_isBranchInstr(regs, mminsn, &contpc);

	regs->cp0_epc = contpc;

	return 0;

sigsegv:
	force_sig(SIGSEGV, current);
	return -EFAULT;
}

/*
 * Compute return address and emulate branch in MIPS16e mode after an
 * exception only. It does not handle compact branches/jumps and cannot
 * be used in interrupt context. (Compact branches/jumps do not cause
 * exceptions.)
 */
int __MIPS16e_compute_return_epc(struct pt_regs *regs)
{
	u16 __user *addr;
	union mips16e_instruction inst;
	u16 inst2;
	u32 fullinst;
	long epc;

	epc = regs->cp0_epc;

	/* Read the instruction. */
	addr = (u16 __user *)msk_isa16_mode(epc);
	if (__get_user(inst.full, addr)) {
		force_sig(SIGSEGV, current);
		return -EFAULT;
	}

	switch (inst.ri.opcode) {
	case MIPS16e_extend_op:
		regs->cp0_epc += 4;
		return 0;

		/*
		 *  JAL and JALX in MIPS16e mode
		 */
	case MIPS16e_jal_op:
		addr += 1;
		if (__get_user(inst2, addr)) {
			force_sig(SIGSEGV, current);
			return -EFAULT;
		}
		fullinst = ((unsigned)inst.full << 16) | inst2;
		regs->regs[31] = epc + 6;
		epc += 4;
		epc >>= 28;
		epc <<= 28;
		/*
		 * JAL:5 X:1 TARGET[20-16]:5 TARGET[25:21]:5 TARGET[15:0]:16
		 *
		 * ......TARGET[15:0].................TARGET[20:16]...........
		 * ......TARGET[25:21]
		 */
		epc |=
		    ((fullinst & 0xffff) << 2) | ((fullinst & 0x3e00000) >> 3) |
		    ((fullinst & 0x1f0000) << 7);
		if (!inst.jal.x)
			set_isa16_mode(epc);	/* Set ISA mode bit. */
		regs->cp0_epc = epc;
		return 0;

		/*
		 *  J(AL)R(C)
		 */
	case MIPS16e_rr_op:
		if (inst.rr.func == MIPS16e_jr_func) {

			if (inst.rr.ra)
				regs->cp0_epc = regs->regs[31];
			else
				regs->cp0_epc =
				    regs->regs[reg16to32[inst.rr.rx]];

			if (inst.rr.l) {
				if (inst.rr.nd)
					regs->regs[31] = epc + 2;
				else
					regs->regs[31] = epc + 4;
			}
			return 0;
		}
		break;
	}

	/*
	 * All other cases have no branch delay slot and are 16-bits.
	 * Branches do not cause an exception.
	 */
	regs->cp0_epc += 2;

	return 0;
}

/**
 * __compute_return_epc_for_insn - Computes the return address and do emulate
 *				    branch simulation, if required.
 *
 * @regs:	Pointer to pt_regs
 * @insn:	branch instruction to decode
 * @returns:	-EFAULT on error and forces SIGBUS, and on success
 *		returns 0 or BRANCH_LIKELY_TAKEN as appropriate after
 *		evaluating the branch.
 */
int __compute_return_epc_for_insn(struct pt_regs *regs,
				   union mips_instruction insn)
{
	unsigned int bit, fcr31, dspcontrol;
	long epc = regs->cp0_epc;
	int ret = 0;

	switch (insn.i_format.opcode) {
	/*
	 * jr and jalr are in r_format format.
	 */
	case spec_op:
		switch (insn.r_format.func) {
		case jalr_op:
			regs->regs[insn.r_format.rd] = epc + 8;
			/* Fall through */
		case jr_op:
			regs->cp0_epc = regs->regs[insn.r_format.rs];
			break;
		}
		break;

	/*
	 * This group contains:
	 * bltz_op, bgez_op, bltzl_op, bgezl_op,
	 * bltzal_op, bgezal_op, bltzall_op, bgezall_op.
	 */
	case bcond_op:
		switch (insn.i_format.rt) {
		case bltz_op:
		case bltzl_op:
			if ((long)regs->regs[insn.i_format.rs] < 0) {
				epc = epc + 4 + (insn.i_format.simmediate << 2);
				if (insn.i_format.rt == bltzl_op)
					ret = BRANCH_LIKELY_TAKEN;
			} else
				epc += 8;
			regs->cp0_epc = epc;
			break;

		case bgez_op:
		case bgezl_op:
			if ((long)regs->regs[insn.i_format.rs] >= 0) {
				epc = epc + 4 + (insn.i_format.simmediate << 2);
				if (insn.i_format.rt == bgezl_op)
					ret = BRANCH_LIKELY_TAKEN;
			} else
				epc += 8;
			regs->cp0_epc = epc;
			break;

		case bltzal_op:
		case bltzall_op:
			regs->regs[31] = epc + 8;
			if ((long)regs->regs[insn.i_format.rs] < 0) {
				epc = epc + 4 + (insn.i_format.simmediate << 2);
				if (insn.i_format.rt == bltzall_op)
					ret = BRANCH_LIKELY_TAKEN;
			} else
				epc += 8;
			regs->cp0_epc = epc;
			break;

		case bgezal_op:
		case bgezall_op:
			regs->regs[31] = epc + 8;
			if ((long)regs->regs[insn.i_format.rs] >= 0) {
				epc = epc + 4 + (insn.i_format.simmediate << 2);
				if (insn.i_format.rt == bgezall_op)
					ret = BRANCH_LIKELY_TAKEN;
			} else
				epc += 8;
			regs->cp0_epc = epc;
			break;

		case bposge32_op:
			if (!cpu_has_dsp)
				goto sigill;

			dspcontrol = rddsp(0x01);

			if (dspcontrol >= 32) {
				epc = epc + 4 + (insn.i_format.simmediate << 2);
			} else
				epc += 8;
			regs->cp0_epc = epc;
			break;
		}
		break;

	/*
	 * These are unconditional and in j_format.
	 */
	case jal_op:
		regs->regs[31] = regs->cp0_epc + 8;
	case j_op:
		epc += 4;
		epc >>= 28;
		epc <<= 28;
		epc |= (insn.j_format.target << 2);
		regs->cp0_epc = epc;
		if (insn.i_format.opcode == jalx_op)
			set_isa16_mode(regs->cp0_epc);
		break;

	/*
	 * These are conditional and in i_format.
	 */
	case beq_op:
	case beql_op:
		if (regs->regs[insn.i_format.rs] ==
		    regs->regs[insn.i_format.rt]) {
			epc = epc + 4 + (insn.i_format.simmediate << 2);
			if (insn.i_format.opcode == beql_op)
				ret = BRANCH_LIKELY_TAKEN;
		} else
			epc += 8;
		regs->cp0_epc = epc;
		break;

	case bne_op:
	case bnel_op:
		if (regs->regs[insn.i_format.rs] !=
		    regs->regs[insn.i_format.rt]) {
			epc = epc + 4 + (insn.i_format.simmediate << 2);
			if (insn.i_format.opcode == bnel_op)
				ret = BRANCH_LIKELY_TAKEN;
		} else
			epc += 8;
		regs->cp0_epc = epc;
		break;

	case blez_op: /* not really i_format */
	case blezl_op:
		/* rt field assumed to be zero */
		if ((long)regs->regs[insn.i_format.rs] <= 0) {
			epc = epc + 4 + (insn.i_format.simmediate << 2);
			if (insn.i_format.opcode == blezl_op)
				ret = BRANCH_LIKELY_TAKEN;
		} else
			epc += 8;
		regs->cp0_epc = epc;
		break;

	case bgtz_op:
	case bgtzl_op:
		/* rt field assumed to be zero */
		if ((long)regs->regs[insn.i_format.rs] > 0) {
			epc = epc + 4 + (insn.i_format.simmediate << 2);
			if (insn.i_format.opcode == bgtzl_op)
				ret = BRANCH_LIKELY_TAKEN;
		} else
			epc += 8;
		regs->cp0_epc = epc;
		break;

	/*
	 * And now the FPA/cp1 branch instructions.
	 */
	case cop1_op:
		preempt_disable();
		if (is_fpu_owner())
			asm volatile(
				".set push\n"
				"\t.set mips1\n"
				"\tcfc1\t%0,$31\n"
				"\t.set pop" : "=r" (fcr31));
		else
			fcr31 = current->thread.fpu.fcr31;
		preempt_enable();

		bit = (insn.i_format.rt >> 2);
		bit += (bit != 0);
		bit += 23;
		switch (insn.i_format.rt & 3) {
		case 0: /* bc1f */
		case 2: /* bc1fl */
			if (~fcr31 & (1 << bit)) {
				epc = epc + 4 + (insn.i_format.simmediate << 2);
				if (insn.i_format.rt == 2)
					ret = BRANCH_LIKELY_TAKEN;
			} else
				epc += 8;
			regs->cp0_epc = epc;
			break;

		case 1: /* bc1t */
		case 3: /* bc1tl */
			if (fcr31 & (1 << bit)) {
				epc = epc + 4 + (insn.i_format.simmediate << 2);
				if (insn.i_format.rt == 3)
					ret = BRANCH_LIKELY_TAKEN;
			} else
				epc += 8;
			regs->cp0_epc = epc;
			break;
		}
		break;
#ifdef CONFIG_CPU_CAVIUM_OCTEON
	case lwc2_op: /* This is bbit0 on Octeon */
		if ((regs->regs[insn.i_format.rs] & (1ull<<insn.i_format.rt))
		     == 0)
			epc = epc + 4 + (insn.i_format.simmediate << 2);
		else
			epc += 8;
		regs->cp0_epc = epc;
		break;
	case ldc2_op: /* This is bbit032 on Octeon */
		if ((regs->regs[insn.i_format.rs] &
		    (1ull<<(insn.i_format.rt+32))) == 0)
			epc = epc + 4 + (insn.i_format.simmediate << 2);
		else
			epc += 8;
		regs->cp0_epc = epc;
		break;
	case swc2_op: /* This is bbit1 on Octeon */
		if (regs->regs[insn.i_format.rs] & (1ull<<insn.i_format.rt))
			epc = epc + 4 + (insn.i_format.simmediate << 2);
		else
			epc += 8;
		regs->cp0_epc = epc;
		break;
	case sdc2_op: /* This is bbit132 on Octeon */
		if (regs->regs[insn.i_format.rs] &
		    (1ull<<(insn.i_format.rt+32)))
			epc = epc + 4 + (insn.i_format.simmediate << 2);
		else
			epc += 8;
		regs->cp0_epc = epc;
		break;
#endif
	}

	return ret;

sigill:
	printk("%s: DSP branch but not DSP ASE - sending SIGBUS.\n", current->comm);
	force_sig(SIGBUS, current);
	return -EFAULT;
}
EXPORT_SYMBOL_GPL(__compute_return_epc_for_insn);

int __compute_return_epc(struct pt_regs *regs)
{
	unsigned int __user *addr;
	long epc;
	union mips_instruction insn;

	epc = regs->cp0_epc;
	if (epc & 3)
		goto unaligned;

	/*
	 * Read the instruction
	 */
	addr = (unsigned int __user *) epc;
	if (__get_user(insn.word, addr)) {
		force_sig(SIGSEGV, current);
		return -EFAULT;
	}

	return __compute_return_epc_for_insn(regs, insn);

unaligned:
	printk("%s: unaligned epc - sending SIGBUS.\n", current->comm);
	force_sig(SIGBUS, current);
	return -EFAULT;
}
