xref: /openbmc/linux/arch/mips/kernel/branch.c (revision cbecf716ca618fd44feda6bd9a64a8179d031fc5)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds  * This file is subject to the terms and conditions of the GNU General Public
31da177e4SLinus Torvalds  * License.  See the file "COPYING" in the main directory of this archive
41da177e4SLinus Torvalds  * for more details.
51da177e4SLinus Torvalds  *
61da177e4SLinus Torvalds  * Copyright (C) 1996, 97, 2000, 2001 by Ralf Baechle
71da177e4SLinus Torvalds  * Copyright (C) 2001 MIPS Technologies, Inc.
81da177e4SLinus Torvalds  */
91da177e4SLinus Torvalds #include <linux/kernel.h>
103f07c014SIngo Molnar #include <linux/sched/signal.h>
111da177e4SLinus Torvalds #include <linux/signal.h>
12d9d54177SPaul Gortmaker #include <linux/export.h>
131da177e4SLinus Torvalds #include <asm/branch.h>
141da177e4SLinus Torvalds #include <asm/cpu.h>
151da177e4SLinus Torvalds #include <asm/cpu-features.h>
161d74f6bcSRalf Baechle #include <asm/fpu.h>
17fb6883e5SLeonid Yegoshin #include <asm/fpu_emulator.h>
181da177e4SLinus Torvalds #include <asm/inst.h>
19b0a668fbSLeonid Yegoshin #include <asm/mips-r2-to-r6-emul.h>
201da177e4SLinus Torvalds #include <asm/ptrace.h>
217c0f6ba6SLinus Torvalds #include <linux/uaccess.h>
221da177e4SLinus Torvalds 
23*6fa573a3SPujin Shi #include "probes-common.h"
24*6fa573a3SPujin Shi 
25fb6883e5SLeonid Yegoshin /*
268508488fSSteven J. Hill  * Calculate and return exception PC in case of branch delay slot
278508488fSSteven J. Hill  * for microMIPS and MIPS16e. It does not clear the ISA mode bit.
28fb6883e5SLeonid Yegoshin  */
__isa_exception_epc(struct pt_regs * regs)29fb6883e5SLeonid Yegoshin int __isa_exception_epc(struct pt_regs *regs)
30fb6883e5SLeonid Yegoshin {
31fb6883e5SLeonid Yegoshin 	unsigned short inst;
328508488fSSteven J. Hill 	long epc = regs->cp0_epc;
33fb6883e5SLeonid Yegoshin 
34fb6883e5SLeonid Yegoshin 	/* Calculate exception PC in branch delay slot. */
35fb6883e5SLeonid Yegoshin 	if (__get_user(inst, (u16 __user *) msk_isa16_mode(epc))) {
36fb6883e5SLeonid Yegoshin 		/* This should never happen because delay slot was checked. */
373cf5d076SEric W. Biederman 		force_sig(SIGSEGV);
38fb6883e5SLeonid Yegoshin 		return epc;
39fb6883e5SLeonid Yegoshin 	}
408508488fSSteven J. Hill 	if (cpu_has_mips16) {
41e6baf0e0SToma Tabacu 		union mips16e_instruction inst_mips16e;
42e6baf0e0SToma Tabacu 
43e6baf0e0SToma Tabacu 		inst_mips16e.full = inst;
44e6baf0e0SToma Tabacu 		if (inst_mips16e.ri.opcode == MIPS16e_jal_op)
458508488fSSteven J. Hill 			epc += 4;
468508488fSSteven J. Hill 		else
478508488fSSteven J. Hill 			epc += 2;
488508488fSSteven J. Hill 	} else if (mm_insn_16bit(inst))
49fb6883e5SLeonid Yegoshin 		epc += 2;
50fb6883e5SLeonid Yegoshin 	else
51fb6883e5SLeonid Yegoshin 		epc += 4;
52fb6883e5SLeonid Yegoshin 
53fb6883e5SLeonid Yegoshin 	return epc;
54fb6883e5SLeonid Yegoshin }
55fb6883e5SLeonid Yegoshin 
5676fbfc31SRalf Baechle /* (microMIPS) Convert 16-bit register encoding to 32-bit register encoding. */
5776fbfc31SRalf Baechle static const unsigned int reg16to32map[8] = {16, 17, 2, 3, 4, 5, 6, 7};
5876fbfc31SRalf Baechle 
__mm_isBranchInstr(struct pt_regs * regs,struct mm_decoded_insn dec_insn,unsigned long * contpc)5976fbfc31SRalf Baechle int __mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
6076fbfc31SRalf Baechle 		       unsigned long *contpc)
6176fbfc31SRalf Baechle {
6276fbfc31SRalf Baechle 	union mips_instruction insn = (union mips_instruction)dec_insn.insn;
63c2869aafSNathan Chancellor 	int __maybe_unused bc_false = 0;
6476fbfc31SRalf Baechle 
6576fbfc31SRalf Baechle 	if (!cpu_has_mmips)
6676fbfc31SRalf Baechle 		return 0;
6776fbfc31SRalf Baechle 
6876fbfc31SRalf Baechle 	switch (insn.mm_i_format.opcode) {
6976fbfc31SRalf Baechle 	case mm_pool32a_op:
7076fbfc31SRalf Baechle 		if ((insn.mm_i_format.simmediate & MM_POOL32A_MINOR_MASK) ==
7176fbfc31SRalf Baechle 		    mm_pool32axf_op) {
7276fbfc31SRalf Baechle 			switch (insn.mm_i_format.simmediate >>
7376fbfc31SRalf Baechle 				MM_POOL32A_MINOR_SHIFT) {
7476fbfc31SRalf Baechle 			case mm_jalr_op:
7576fbfc31SRalf Baechle 			case mm_jalrhb_op:
7676fbfc31SRalf Baechle 			case mm_jalrs_op:
7776fbfc31SRalf Baechle 			case mm_jalrshb_op:
7876fbfc31SRalf Baechle 				if (insn.mm_i_format.rt != 0)	/* Not mm_jr */
7976fbfc31SRalf Baechle 					regs->regs[insn.mm_i_format.rt] =
8076fbfc31SRalf Baechle 						regs->cp0_epc +
8176fbfc31SRalf Baechle 						dec_insn.pc_inc +
8276fbfc31SRalf Baechle 						dec_insn.next_pc_inc;
8376fbfc31SRalf Baechle 				*contpc = regs->regs[insn.mm_i_format.rs];
8476fbfc31SRalf Baechle 				return 1;
8576fbfc31SRalf Baechle 			}
8676fbfc31SRalf Baechle 		}
8776fbfc31SRalf Baechle 		break;
8876fbfc31SRalf Baechle 	case mm_pool32i_op:
8976fbfc31SRalf Baechle 		switch (insn.mm_i_format.rt) {
9076fbfc31SRalf Baechle 		case mm_bltzals_op:
9176fbfc31SRalf Baechle 		case mm_bltzal_op:
9276fbfc31SRalf Baechle 			regs->regs[31] = regs->cp0_epc +
9376fbfc31SRalf Baechle 				dec_insn.pc_inc +
9476fbfc31SRalf Baechle 				dec_insn.next_pc_inc;
95c9b02990SLiangliang Huang 			fallthrough;
9676fbfc31SRalf Baechle 		case mm_bltz_op:
9776fbfc31SRalf Baechle 			if ((long)regs->regs[insn.mm_i_format.rs] < 0)
9876fbfc31SRalf Baechle 				*contpc = regs->cp0_epc +
9976fbfc31SRalf Baechle 					dec_insn.pc_inc +
10076fbfc31SRalf Baechle 					(insn.mm_i_format.simmediate << 1);
10176fbfc31SRalf Baechle 			else
10276fbfc31SRalf Baechle 				*contpc = regs->cp0_epc +
10376fbfc31SRalf Baechle 					dec_insn.pc_inc +
10476fbfc31SRalf Baechle 					dec_insn.next_pc_inc;
10576fbfc31SRalf Baechle 			return 1;
10676fbfc31SRalf Baechle 		case mm_bgezals_op:
10776fbfc31SRalf Baechle 		case mm_bgezal_op:
10876fbfc31SRalf Baechle 			regs->regs[31] = regs->cp0_epc +
10976fbfc31SRalf Baechle 					dec_insn.pc_inc +
11076fbfc31SRalf Baechle 					dec_insn.next_pc_inc;
111c9b02990SLiangliang Huang 			fallthrough;
11276fbfc31SRalf Baechle 		case mm_bgez_op:
11376fbfc31SRalf Baechle 			if ((long)regs->regs[insn.mm_i_format.rs] >= 0)
11476fbfc31SRalf Baechle 				*contpc = regs->cp0_epc +
11576fbfc31SRalf Baechle 					dec_insn.pc_inc +
11676fbfc31SRalf Baechle 					(insn.mm_i_format.simmediate << 1);
11776fbfc31SRalf Baechle 			else
11876fbfc31SRalf Baechle 				*contpc = regs->cp0_epc +
11976fbfc31SRalf Baechle 					dec_insn.pc_inc +
12076fbfc31SRalf Baechle 					dec_insn.next_pc_inc;
12176fbfc31SRalf Baechle 			return 1;
12276fbfc31SRalf Baechle 		case mm_blez_op:
12376fbfc31SRalf Baechle 			if ((long)regs->regs[insn.mm_i_format.rs] <= 0)
12476fbfc31SRalf Baechle 				*contpc = regs->cp0_epc +
12576fbfc31SRalf Baechle 					dec_insn.pc_inc +
12676fbfc31SRalf Baechle 					(insn.mm_i_format.simmediate << 1);
12776fbfc31SRalf Baechle 			else
12876fbfc31SRalf Baechle 				*contpc = regs->cp0_epc +
12976fbfc31SRalf Baechle 					dec_insn.pc_inc +
13076fbfc31SRalf Baechle 					dec_insn.next_pc_inc;
13176fbfc31SRalf Baechle 			return 1;
13276fbfc31SRalf Baechle 		case mm_bgtz_op:
13376fbfc31SRalf Baechle 			if ((long)regs->regs[insn.mm_i_format.rs] <= 0)
13476fbfc31SRalf Baechle 				*contpc = regs->cp0_epc +
13576fbfc31SRalf Baechle 					dec_insn.pc_inc +
13676fbfc31SRalf Baechle 					(insn.mm_i_format.simmediate << 1);
13776fbfc31SRalf Baechle 			else
13876fbfc31SRalf Baechle 				*contpc = regs->cp0_epc +
13976fbfc31SRalf Baechle 					dec_insn.pc_inc +
14076fbfc31SRalf Baechle 					dec_insn.next_pc_inc;
14176fbfc31SRalf Baechle 			return 1;
1426a1cc218SPaul Burton #ifdef CONFIG_MIPS_FP_SUPPORT
14376fbfc31SRalf Baechle 		case mm_bc2f_op:
1446a1cc218SPaul Burton 		case mm_bc1f_op: {
1456a1cc218SPaul Burton 			unsigned int fcr31;
1466a1cc218SPaul Burton 			unsigned int bit;
1476a1cc218SPaul Burton 
14876fbfc31SRalf Baechle 			bc_false = 1;
149c9b02990SLiangliang Huang 			fallthrough;
15076fbfc31SRalf Baechle 		case mm_bc2t_op:
15176fbfc31SRalf Baechle 		case mm_bc1t_op:
15276fbfc31SRalf Baechle 			preempt_disable();
15376fbfc31SRalf Baechle 			if (is_fpu_owner())
154842dfc11SManuel Lauss 			        fcr31 = read_32bit_cp1_register(CP1_STATUS);
15576fbfc31SRalf Baechle 			else
15676fbfc31SRalf Baechle 				fcr31 = current->thread.fpu.fcr31;
15776fbfc31SRalf Baechle 			preempt_enable();
15876fbfc31SRalf Baechle 
15976fbfc31SRalf Baechle 			if (bc_false)
16076fbfc31SRalf Baechle 				fcr31 = ~fcr31;
16176fbfc31SRalf Baechle 
16276fbfc31SRalf Baechle 			bit = (insn.mm_i_format.rs >> 2);
16376fbfc31SRalf Baechle 			bit += (bit != 0);
16476fbfc31SRalf Baechle 			bit += 23;
16576fbfc31SRalf Baechle 			if (fcr31 & (1 << bit))
16676fbfc31SRalf Baechle 				*contpc = regs->cp0_epc +
16776fbfc31SRalf Baechle 					dec_insn.pc_inc +
16876fbfc31SRalf Baechle 					(insn.mm_i_format.simmediate << 1);
16976fbfc31SRalf Baechle 			else
17076fbfc31SRalf Baechle 				*contpc = regs->cp0_epc +
17176fbfc31SRalf Baechle 					dec_insn.pc_inc + dec_insn.next_pc_inc;
17276fbfc31SRalf Baechle 			return 1;
17376fbfc31SRalf Baechle 		}
1746a1cc218SPaul Burton #endif /* CONFIG_MIPS_FP_SUPPORT */
1756a1cc218SPaul Burton 		}
17676fbfc31SRalf Baechle 		break;
17776fbfc31SRalf Baechle 	case mm_pool16c_op:
17876fbfc31SRalf Baechle 		switch (insn.mm_i_format.rt) {
17976fbfc31SRalf Baechle 		case mm_jalr16_op:
18076fbfc31SRalf Baechle 		case mm_jalrs16_op:
18176fbfc31SRalf Baechle 			regs->regs[31] = regs->cp0_epc +
18276fbfc31SRalf Baechle 				dec_insn.pc_inc + dec_insn.next_pc_inc;
183c9b02990SLiangliang Huang 			fallthrough;
18476fbfc31SRalf Baechle 		case mm_jr16_op:
18576fbfc31SRalf Baechle 			*contpc = regs->regs[insn.mm_i_format.rs];
18676fbfc31SRalf Baechle 			return 1;
18776fbfc31SRalf Baechle 		}
18876fbfc31SRalf Baechle 		break;
18976fbfc31SRalf Baechle 	case mm_beqz16_op:
19076fbfc31SRalf Baechle 		if ((long)regs->regs[reg16to32map[insn.mm_b1_format.rs]] == 0)
19176fbfc31SRalf Baechle 			*contpc = regs->cp0_epc +
19276fbfc31SRalf Baechle 				dec_insn.pc_inc +
19376fbfc31SRalf Baechle 				(insn.mm_b1_format.simmediate << 1);
19476fbfc31SRalf Baechle 		else
19576fbfc31SRalf Baechle 			*contpc = regs->cp0_epc +
19676fbfc31SRalf Baechle 				dec_insn.pc_inc + dec_insn.next_pc_inc;
19776fbfc31SRalf Baechle 		return 1;
19876fbfc31SRalf Baechle 	case mm_bnez16_op:
19976fbfc31SRalf Baechle 		if ((long)regs->regs[reg16to32map[insn.mm_b1_format.rs]] != 0)
20076fbfc31SRalf Baechle 			*contpc = regs->cp0_epc +
20176fbfc31SRalf Baechle 				dec_insn.pc_inc +
20276fbfc31SRalf Baechle 				(insn.mm_b1_format.simmediate << 1);
20376fbfc31SRalf Baechle 		else
20476fbfc31SRalf Baechle 			*contpc = regs->cp0_epc +
20576fbfc31SRalf Baechle 				dec_insn.pc_inc + dec_insn.next_pc_inc;
20676fbfc31SRalf Baechle 		return 1;
20776fbfc31SRalf Baechle 	case mm_b16_op:
20876fbfc31SRalf Baechle 		*contpc = regs->cp0_epc + dec_insn.pc_inc +
20976fbfc31SRalf Baechle 			 (insn.mm_b0_format.simmediate << 1);
21076fbfc31SRalf Baechle 		return 1;
21176fbfc31SRalf Baechle 	case mm_beq32_op:
21276fbfc31SRalf Baechle 		if (regs->regs[insn.mm_i_format.rs] ==
21376fbfc31SRalf Baechle 		    regs->regs[insn.mm_i_format.rt])
21476fbfc31SRalf Baechle 			*contpc = regs->cp0_epc +
21576fbfc31SRalf Baechle 				dec_insn.pc_inc +
21676fbfc31SRalf Baechle 				(insn.mm_i_format.simmediate << 1);
21776fbfc31SRalf Baechle 		else
21876fbfc31SRalf Baechle 			*contpc = regs->cp0_epc +
21976fbfc31SRalf Baechle 				dec_insn.pc_inc +
22076fbfc31SRalf Baechle 				dec_insn.next_pc_inc;
22176fbfc31SRalf Baechle 		return 1;
22276fbfc31SRalf Baechle 	case mm_bne32_op:
22376fbfc31SRalf Baechle 		if (regs->regs[insn.mm_i_format.rs] !=
22476fbfc31SRalf Baechle 		    regs->regs[insn.mm_i_format.rt])
22576fbfc31SRalf Baechle 			*contpc = regs->cp0_epc +
22676fbfc31SRalf Baechle 				dec_insn.pc_inc +
22776fbfc31SRalf Baechle 				(insn.mm_i_format.simmediate << 1);
22876fbfc31SRalf Baechle 		else
22976fbfc31SRalf Baechle 			*contpc = regs->cp0_epc +
23076fbfc31SRalf Baechle 				dec_insn.pc_inc + dec_insn.next_pc_inc;
23176fbfc31SRalf Baechle 		return 1;
23276fbfc31SRalf Baechle 	case mm_jalx32_op:
23376fbfc31SRalf Baechle 		regs->regs[31] = regs->cp0_epc +
23476fbfc31SRalf Baechle 			dec_insn.pc_inc + dec_insn.next_pc_inc;
23576fbfc31SRalf Baechle 		*contpc = regs->cp0_epc + dec_insn.pc_inc;
23676fbfc31SRalf Baechle 		*contpc >>= 28;
23776fbfc31SRalf Baechle 		*contpc <<= 28;
23876fbfc31SRalf Baechle 		*contpc |= (insn.j_format.target << 2);
23976fbfc31SRalf Baechle 		return 1;
24076fbfc31SRalf Baechle 	case mm_jals32_op:
24176fbfc31SRalf Baechle 	case mm_jal32_op:
24276fbfc31SRalf Baechle 		regs->regs[31] = regs->cp0_epc +
24376fbfc31SRalf Baechle 			dec_insn.pc_inc + dec_insn.next_pc_inc;
244c9b02990SLiangliang Huang 		fallthrough;
24576fbfc31SRalf Baechle 	case mm_j32_op:
24676fbfc31SRalf Baechle 		*contpc = regs->cp0_epc + dec_insn.pc_inc;
24776fbfc31SRalf Baechle 		*contpc >>= 27;
24876fbfc31SRalf Baechle 		*contpc <<= 27;
24976fbfc31SRalf Baechle 		*contpc |= (insn.j_format.target << 1);
25076fbfc31SRalf Baechle 		set_isa16_mode(*contpc);
25176fbfc31SRalf Baechle 		return 1;
25276fbfc31SRalf Baechle 	}
25376fbfc31SRalf Baechle 	return 0;
25476fbfc31SRalf Baechle }
25576fbfc31SRalf Baechle 
256fb6883e5SLeonid Yegoshin /*
257fb6883e5SLeonid Yegoshin  * Compute return address and emulate branch in microMIPS mode after an
258fb6883e5SLeonid Yegoshin  * exception only. It does not handle compact branches/jumps and cannot
259fb6883e5SLeonid Yegoshin  * be used in interrupt context. (Compact branches/jumps do not cause
260fb6883e5SLeonid Yegoshin  * exceptions.)
261fb6883e5SLeonid Yegoshin  */
__microMIPS_compute_return_epc(struct pt_regs * regs)262fb6883e5SLeonid Yegoshin int __microMIPS_compute_return_epc(struct pt_regs *regs)
263fb6883e5SLeonid Yegoshin {
264fb6883e5SLeonid Yegoshin 	u16 __user *pc16;
265fb6883e5SLeonid Yegoshin 	u16 halfword;
266fb6883e5SLeonid Yegoshin 	unsigned int word;
267fb6883e5SLeonid Yegoshin 	unsigned long contpc;
268fb6883e5SLeonid Yegoshin 	struct mm_decoded_insn mminsn = { 0 };
269fb6883e5SLeonid Yegoshin 
270fb6883e5SLeonid Yegoshin 	mminsn.micro_mips_mode = 1;
271fb6883e5SLeonid Yegoshin 
272fb6883e5SLeonid Yegoshin 	/* This load never faults. */
273fb6883e5SLeonid Yegoshin 	pc16 = (unsigned short __user *)msk_isa16_mode(regs->cp0_epc);
274fb6883e5SLeonid Yegoshin 	__get_user(halfword, pc16);
275fb6883e5SLeonid Yegoshin 	pc16++;
276fb6883e5SLeonid Yegoshin 	contpc = regs->cp0_epc + 2;
277fb6883e5SLeonid Yegoshin 	word = ((unsigned int)halfword << 16);
278fb6883e5SLeonid Yegoshin 	mminsn.pc_inc = 2;
279fb6883e5SLeonid Yegoshin 
280fb6883e5SLeonid Yegoshin 	if (!mm_insn_16bit(halfword)) {
281fb6883e5SLeonid Yegoshin 		__get_user(halfword, pc16);
282fb6883e5SLeonid Yegoshin 		pc16++;
283fb6883e5SLeonid Yegoshin 		contpc = regs->cp0_epc + 4;
284fb6883e5SLeonid Yegoshin 		mminsn.pc_inc = 4;
285fb6883e5SLeonid Yegoshin 		word |= halfword;
286fb6883e5SLeonid Yegoshin 	}
287fb6883e5SLeonid Yegoshin 	mminsn.insn = word;
288fb6883e5SLeonid Yegoshin 
289fb6883e5SLeonid Yegoshin 	if (get_user(halfword, pc16))
290fb6883e5SLeonid Yegoshin 		goto sigsegv;
291fb6883e5SLeonid Yegoshin 	mminsn.next_pc_inc = 2;
292fb6883e5SLeonid Yegoshin 	word = ((unsigned int)halfword << 16);
293fb6883e5SLeonid Yegoshin 
294fb6883e5SLeonid Yegoshin 	if (!mm_insn_16bit(halfword)) {
295fb6883e5SLeonid Yegoshin 		pc16++;
296fb6883e5SLeonid Yegoshin 		if (get_user(halfword, pc16))
297fb6883e5SLeonid Yegoshin 			goto sigsegv;
298fb6883e5SLeonid Yegoshin 		mminsn.next_pc_inc = 4;
299fb6883e5SLeonid Yegoshin 		word |= halfword;
300fb6883e5SLeonid Yegoshin 	}
301fb6883e5SLeonid Yegoshin 	mminsn.next_insn = word;
302fb6883e5SLeonid Yegoshin 
303fb6883e5SLeonid Yegoshin 	mm_isBranchInstr(regs, mminsn, &contpc);
304fb6883e5SLeonid Yegoshin 
305fb6883e5SLeonid Yegoshin 	regs->cp0_epc = contpc;
306fb6883e5SLeonid Yegoshin 
307fb6883e5SLeonid Yegoshin 	return 0;
308fb6883e5SLeonid Yegoshin 
309fb6883e5SLeonid Yegoshin sigsegv:
3103cf5d076SEric W. Biederman 	force_sig(SIGSEGV);
311fb6883e5SLeonid Yegoshin 	return -EFAULT;
312fb6883e5SLeonid Yegoshin }
313fb6883e5SLeonid Yegoshin 
3148508488fSSteven J. Hill /*
3158508488fSSteven J. Hill  * Compute return address and emulate branch in MIPS16e mode after an
3168508488fSSteven J. Hill  * exception only. It does not handle compact branches/jumps and cannot
3178508488fSSteven J. Hill  * be used in interrupt context. (Compact branches/jumps do not cause
3188508488fSSteven J. Hill  * exceptions.)
3198508488fSSteven J. Hill  */
__MIPS16e_compute_return_epc(struct pt_regs * regs)3208508488fSSteven J. Hill int __MIPS16e_compute_return_epc(struct pt_regs *regs)
3218508488fSSteven J. Hill {
3228508488fSSteven J. Hill 	u16 __user *addr;
3238508488fSSteven J. Hill 	union mips16e_instruction inst;
3248508488fSSteven J. Hill 	u16 inst2;
3258508488fSSteven J. Hill 	u32 fullinst;
3268508488fSSteven J. Hill 	long epc;
3278508488fSSteven J. Hill 
3288508488fSSteven J. Hill 	epc = regs->cp0_epc;
3298508488fSSteven J. Hill 
3308508488fSSteven J. Hill 	/* Read the instruction. */
3318508488fSSteven J. Hill 	addr = (u16 __user *)msk_isa16_mode(epc);
3328508488fSSteven J. Hill 	if (__get_user(inst.full, addr)) {
3333cf5d076SEric W. Biederman 		force_sig(SIGSEGV);
3348508488fSSteven J. Hill 		return -EFAULT;
3358508488fSSteven J. Hill 	}
3368508488fSSteven J. Hill 
3378508488fSSteven J. Hill 	switch (inst.ri.opcode) {
3388508488fSSteven J. Hill 	case MIPS16e_extend_op:
3398508488fSSteven J. Hill 		regs->cp0_epc += 4;
3408508488fSSteven J. Hill 		return 0;
3418508488fSSteven J. Hill 
3428508488fSSteven J. Hill 		/*
3438508488fSSteven J. Hill 		 *  JAL and JALX in MIPS16e mode
3448508488fSSteven J. Hill 		 */
3458508488fSSteven J. Hill 	case MIPS16e_jal_op:
3468508488fSSteven J. Hill 		addr += 1;
3478508488fSSteven J. Hill 		if (__get_user(inst2, addr)) {
3483cf5d076SEric W. Biederman 			force_sig(SIGSEGV);
3498508488fSSteven J. Hill 			return -EFAULT;
3508508488fSSteven J. Hill 		}
3518508488fSSteven J. Hill 		fullinst = ((unsigned)inst.full << 16) | inst2;
3528508488fSSteven J. Hill 		regs->regs[31] = epc + 6;
3538508488fSSteven J. Hill 		epc += 4;
3548508488fSSteven J. Hill 		epc >>= 28;
3558508488fSSteven J. Hill 		epc <<= 28;
3568508488fSSteven J. Hill 		/*
3578508488fSSteven J. Hill 		 * JAL:5 X:1 TARGET[20-16]:5 TARGET[25:21]:5 TARGET[15:0]:16
3588508488fSSteven J. Hill 		 *
3598508488fSSteven J. Hill 		 * ......TARGET[15:0].................TARGET[20:16]...........
3608508488fSSteven J. Hill 		 * ......TARGET[25:21]
3618508488fSSteven J. Hill 		 */
3628508488fSSteven J. Hill 		epc |=
3638508488fSSteven J. Hill 		    ((fullinst & 0xffff) << 2) | ((fullinst & 0x3e00000) >> 3) |
3648508488fSSteven J. Hill 		    ((fullinst & 0x1f0000) << 7);
3658508488fSSteven J. Hill 		if (!inst.jal.x)
3668508488fSSteven J. Hill 			set_isa16_mode(epc);	/* Set ISA mode bit. */
3678508488fSSteven J. Hill 		regs->cp0_epc = epc;
3688508488fSSteven J. Hill 		return 0;
3698508488fSSteven J. Hill 
3708508488fSSteven J. Hill 		/*
3718508488fSSteven J. Hill 		 *  J(AL)R(C)
3728508488fSSteven J. Hill 		 */
3738508488fSSteven J. Hill 	case MIPS16e_rr_op:
3748508488fSSteven J. Hill 		if (inst.rr.func == MIPS16e_jr_func) {
3758508488fSSteven J. Hill 
3768508488fSSteven J. Hill 			if (inst.rr.ra)
3778508488fSSteven J. Hill 				regs->cp0_epc = regs->regs[31];
3788508488fSSteven J. Hill 			else
3798508488fSSteven J. Hill 				regs->cp0_epc =
3808508488fSSteven J. Hill 				    regs->regs[reg16to32[inst.rr.rx]];
3818508488fSSteven J. Hill 
3828508488fSSteven J. Hill 			if (inst.rr.l) {
3838508488fSSteven J. Hill 				if (inst.rr.nd)
3848508488fSSteven J. Hill 					regs->regs[31] = epc + 2;
3858508488fSSteven J. Hill 				else
3868508488fSSteven J. Hill 					regs->regs[31] = epc + 4;
3878508488fSSteven J. Hill 			}
3888508488fSSteven J. Hill 			return 0;
3898508488fSSteven J. Hill 		}
3908508488fSSteven J. Hill 		break;
3918508488fSSteven J. Hill 	}
3928508488fSSteven J. Hill 
3938508488fSSteven J. Hill 	/*
3948508488fSSteven J. Hill 	 * All other cases have no branch delay slot and are 16-bits.
3958508488fSSteven J. Hill 	 * Branches do not cause an exception.
3968508488fSSteven J. Hill 	 */
3978508488fSSteven J. Hill 	regs->cp0_epc += 2;
3988508488fSSteven J. Hill 
3998508488fSSteven J. Hill 	return 0;
4008508488fSSteven J. Hill }
4018508488fSSteven J. Hill 
402d8d4e3aeSManeesh Soni /**
403d8d4e3aeSManeesh Soni  * __compute_return_epc_for_insn - Computes the return address and do emulate
404d8d4e3aeSManeesh Soni  *				    branch simulation, if required.
405d8d4e3aeSManeesh Soni  *
406d8d4e3aeSManeesh Soni  * @regs:	Pointer to pt_regs
407d8d4e3aeSManeesh Soni  * @insn:	branch instruction to decode
408cdf93470SMathieu Malaterre  * Return:	-EFAULT on error and forces SIGILL, and on success
409d8d4e3aeSManeesh Soni  *		returns 0 or BRANCH_LIKELY_TAKEN as appropriate after
410d8d4e3aeSManeesh Soni  *		evaluating the branch.
411a8ff66f5SMarkos Chandras  *
412a8ff66f5SMarkos Chandras  * MIPS R6 Compact branches and forbidden slots:
413a8ff66f5SMarkos Chandras  *	Compact branches do not throw exceptions because they do
414a8ff66f5SMarkos Chandras  *	not have delay slots. The forbidden slot instruction ($PC+4)
415a8ff66f5SMarkos Chandras  *	is only executed if the branch was not taken. Otherwise the
416a8ff66f5SMarkos Chandras  *	forbidden slot is skipped entirely. This means that the
417a8ff66f5SMarkos Chandras  *	only possible reason to be here because of a MIPS R6 compact
418a8ff66f5SMarkos Chandras  *	branch instruction is that the forbidden slot has thrown one.
419a8ff66f5SMarkos Chandras  *	In that case the branch was not taken, so the EPC can be safely
420a8ff66f5SMarkos Chandras  *	set to EPC + 8.
4211da177e4SLinus Torvalds  */
__compute_return_epc_for_insn(struct pt_regs * regs,union mips_instruction insn)422d8d4e3aeSManeesh Soni int __compute_return_epc_for_insn(struct pt_regs *regs,
423d8d4e3aeSManeesh Soni 				   union mips_instruction insn)
4241da177e4SLinus Torvalds {
425d8d4e3aeSManeesh Soni 	long epc = regs->cp0_epc;
4266a1cc218SPaul Burton 	unsigned int dspcontrol;
427d8d4e3aeSManeesh Soni 	int ret = 0;
4281da177e4SLinus Torvalds 
4291da177e4SLinus Torvalds 	switch (insn.i_format.opcode) {
4301da177e4SLinus Torvalds 	/*
4311da177e4SLinus Torvalds 	 * jr and jalr are in r_format format.
4321da177e4SLinus Torvalds 	 */
4331da177e4SLinus Torvalds 	case spec_op:
4341da177e4SLinus Torvalds 		switch (insn.r_format.func) {
4351da177e4SLinus Torvalds 		case jalr_op:
4361da177e4SLinus Torvalds 			regs->regs[insn.r_format.rd] = epc + 8;
437c9b02990SLiangliang Huang 			fallthrough;
4381da177e4SLinus Torvalds 		case jr_op:
4395f9f41c4SMarkos Chandras 			if (NO_R6EMU && insn.r_format.func == jr_op)
4401f4edde4SMaciej W. Rozycki 				goto sigill_r2r6;
4411da177e4SLinus Torvalds 			regs->cp0_epc = regs->regs[insn.r_format.rs];
4421da177e4SLinus Torvalds 			break;
4431da177e4SLinus Torvalds 		}
4441da177e4SLinus Torvalds 		break;
4451da177e4SLinus Torvalds 
4461da177e4SLinus Torvalds 	/*
4471da177e4SLinus Torvalds 	 * This group contains:
4481da177e4SLinus Torvalds 	 * bltz_op, bgez_op, bltzl_op, bgezl_op,
4491da177e4SLinus Torvalds 	 * bltzal_op, bgezal_op, bltzall_op, bgezall_op.
4501da177e4SLinus Torvalds 	 */
4511da177e4SLinus Torvalds 	case bcond_op:
4521da177e4SLinus Torvalds 		switch (insn.i_format.rt) {
4531da177e4SLinus Torvalds 		case bltzl_op:
454319824eaSMarkos Chandras 			if (NO_R6EMU)
4551f4edde4SMaciej W. Rozycki 				goto sigill_r2r6;
456c9b02990SLiangliang Huang 			fallthrough;
457319824eaSMarkos Chandras 		case bltz_op:
458d8d4e3aeSManeesh Soni 			if ((long)regs->regs[insn.i_format.rs] < 0) {
4591da177e4SLinus Torvalds 				epc = epc + 4 + (insn.i_format.simmediate << 2);
460d8d4e3aeSManeesh Soni 				if (insn.i_format.rt == bltzl_op)
461d8d4e3aeSManeesh Soni 					ret = BRANCH_LIKELY_TAKEN;
462d8d4e3aeSManeesh Soni 			} else
4631da177e4SLinus Torvalds 				epc += 8;
4641da177e4SLinus Torvalds 			regs->cp0_epc = epc;
4651da177e4SLinus Torvalds 			break;
4661da177e4SLinus Torvalds 
4671da177e4SLinus Torvalds 		case bgezl_op:
468319824eaSMarkos Chandras 			if (NO_R6EMU)
4691f4edde4SMaciej W. Rozycki 				goto sigill_r2r6;
470c9b02990SLiangliang Huang 			fallthrough;
471319824eaSMarkos Chandras 		case bgez_op:
472d8d4e3aeSManeesh Soni 			if ((long)regs->regs[insn.i_format.rs] >= 0) {
4731da177e4SLinus Torvalds 				epc = epc + 4 + (insn.i_format.simmediate << 2);
474d8d4e3aeSManeesh Soni 				if (insn.i_format.rt == bgezl_op)
475d8d4e3aeSManeesh Soni 					ret = BRANCH_LIKELY_TAKEN;
476d8d4e3aeSManeesh Soni 			} else
4771da177e4SLinus Torvalds 				epc += 8;
4781da177e4SLinus Torvalds 			regs->cp0_epc = epc;
4791da177e4SLinus Torvalds 			break;
4801da177e4SLinus Torvalds 
4811da177e4SLinus Torvalds 		case bltzal_op:
4821da177e4SLinus Torvalds 		case bltzall_op:
483319824eaSMarkos Chandras 			if (NO_R6EMU && (insn.i_format.rs ||
484fef40be6SMaciej W. Rozycki 			    insn.i_format.rt == bltzall_op))
485fef40be6SMaciej W. Rozycki 				goto sigill_r2r6;
4861da177e4SLinus Torvalds 			regs->regs[31] = epc + 8;
487319824eaSMarkos Chandras 			/*
488319824eaSMarkos Chandras 			 * OK we are here either because we hit a NAL
489319824eaSMarkos Chandras 			 * instruction or because we are emulating an
4904939788eSRalf Baechle 			 * old bltzal{,l} one. Let's figure out what the
491319824eaSMarkos Chandras 			 * case really is.
492319824eaSMarkos Chandras 			 */
493319824eaSMarkos Chandras 			if (!insn.i_format.rs) {
494319824eaSMarkos Chandras 				/*
495319824eaSMarkos Chandras 				 * NAL or BLTZAL with rs == 0
496319824eaSMarkos Chandras 				 * Doesn't matter if we are R6 or not. The
497319824eaSMarkos Chandras 				 * result is the same
498319824eaSMarkos Chandras 				 */
499319824eaSMarkos Chandras 				regs->cp0_epc += 4 +
500319824eaSMarkos Chandras 					(insn.i_format.simmediate << 2);
501319824eaSMarkos Chandras 				break;
502319824eaSMarkos Chandras 			}
503319824eaSMarkos Chandras 			/* Now do the real thing for non-R6 BLTZAL{,L} */
504d8d4e3aeSManeesh Soni 			if ((long)regs->regs[insn.i_format.rs] < 0) {
5051da177e4SLinus Torvalds 				epc = epc + 4 + (insn.i_format.simmediate << 2);
506d8d4e3aeSManeesh Soni 				if (insn.i_format.rt == bltzall_op)
507d8d4e3aeSManeesh Soni 					ret = BRANCH_LIKELY_TAKEN;
508d8d4e3aeSManeesh Soni 			} else
5091da177e4SLinus Torvalds 				epc += 8;
5101da177e4SLinus Torvalds 			regs->cp0_epc = epc;
5111da177e4SLinus Torvalds 			break;
5121da177e4SLinus Torvalds 
5131da177e4SLinus Torvalds 		case bgezal_op:
5141da177e4SLinus Torvalds 		case bgezall_op:
515319824eaSMarkos Chandras 			if (NO_R6EMU && (insn.i_format.rs ||
516fef40be6SMaciej W. Rozycki 			    insn.i_format.rt == bgezall_op))
517fef40be6SMaciej W. Rozycki 				goto sigill_r2r6;
5181da177e4SLinus Torvalds 			regs->regs[31] = epc + 8;
519319824eaSMarkos Chandras 			/*
520319824eaSMarkos Chandras 			 * OK we are here either because we hit a BAL
521319824eaSMarkos Chandras 			 * instruction or because we are emulating an
5224939788eSRalf Baechle 			 * old bgezal{,l} one. Let's figure out what the
523319824eaSMarkos Chandras 			 * case really is.
524319824eaSMarkos Chandras 			 */
525319824eaSMarkos Chandras 			if (!insn.i_format.rs) {
526319824eaSMarkos Chandras 				/*
527319824eaSMarkos Chandras 				 * BAL or BGEZAL with rs == 0
528319824eaSMarkos Chandras 				 * Doesn't matter if we are R6 or not. The
529319824eaSMarkos Chandras 				 * result is the same
530319824eaSMarkos Chandras 				 */
531319824eaSMarkos Chandras 				regs->cp0_epc += 4 +
532319824eaSMarkos Chandras 					(insn.i_format.simmediate << 2);
533319824eaSMarkos Chandras 				break;
534319824eaSMarkos Chandras 			}
535319824eaSMarkos Chandras 			/* Now do the real thing for non-R6 BGEZAL{,L} */
536d8d4e3aeSManeesh Soni 			if ((long)regs->regs[insn.i_format.rs] >= 0) {
5371da177e4SLinus Torvalds 				epc = epc + 4 + (insn.i_format.simmediate << 2);
538d8d4e3aeSManeesh Soni 				if (insn.i_format.rt == bgezall_op)
539d8d4e3aeSManeesh Soni 					ret = BRANCH_LIKELY_TAKEN;
540d8d4e3aeSManeesh Soni 			} else
5411da177e4SLinus Torvalds 				epc += 8;
5421da177e4SLinus Torvalds 			regs->cp0_epc = epc;
5431da177e4SLinus Torvalds 			break;
544d8d4e3aeSManeesh Soni 
545e50c0a8fSRalf Baechle 		case bposge32_op:
546e50c0a8fSRalf Baechle 			if (!cpu_has_dsp)
5475f9f41c4SMarkos Chandras 				goto sigill_dsp;
548e50c0a8fSRalf Baechle 
549e50c0a8fSRalf Baechle 			dspcontrol = rddsp(0x01);
550e50c0a8fSRalf Baechle 
551e50c0a8fSRalf Baechle 			if (dspcontrol >= 32) {
552e50c0a8fSRalf Baechle 				epc = epc + 4 + (insn.i_format.simmediate << 2);
553e50c0a8fSRalf Baechle 			} else
554e50c0a8fSRalf Baechle 				epc += 8;
555e50c0a8fSRalf Baechle 			regs->cp0_epc = epc;
556e50c0a8fSRalf Baechle 			break;
5571da177e4SLinus Torvalds 		}
5581da177e4SLinus Torvalds 		break;
5591da177e4SLinus Torvalds 
5601da177e4SLinus Torvalds 	/*
5611da177e4SLinus Torvalds 	 * These are unconditional and in j_format.
5621da177e4SLinus Torvalds 	 */
563a9db101bSMaciej W. Rozycki 	case jalx_op:
5641da177e4SLinus Torvalds 	case jal_op:
5651da177e4SLinus Torvalds 		regs->regs[31] = regs->cp0_epc + 8;
566c9b02990SLiangliang Huang 		fallthrough;
5671da177e4SLinus Torvalds 	case j_op:
5681da177e4SLinus Torvalds 		epc += 4;
5691da177e4SLinus Torvalds 		epc >>= 28;
5701da177e4SLinus Torvalds 		epc <<= 28;
5711da177e4SLinus Torvalds 		epc |= (insn.j_format.target << 2);
5721da177e4SLinus Torvalds 		regs->cp0_epc = epc;
573fb6883e5SLeonid Yegoshin 		if (insn.i_format.opcode == jalx_op)
574fb6883e5SLeonid Yegoshin 			set_isa16_mode(regs->cp0_epc);
5751da177e4SLinus Torvalds 		break;
5761da177e4SLinus Torvalds 
5771da177e4SLinus Torvalds 	/*
5781da177e4SLinus Torvalds 	 * These are conditional and in i_format.
5791da177e4SLinus Torvalds 	 */
5801da177e4SLinus Torvalds 	case beql_op:
581319824eaSMarkos Chandras 		if (NO_R6EMU)
5821f4edde4SMaciej W. Rozycki 			goto sigill_r2r6;
583c9b02990SLiangliang Huang 		fallthrough;
584319824eaSMarkos Chandras 	case beq_op:
5851da177e4SLinus Torvalds 		if (regs->regs[insn.i_format.rs] ==
586d8d4e3aeSManeesh Soni 		    regs->regs[insn.i_format.rt]) {
5871da177e4SLinus Torvalds 			epc = epc + 4 + (insn.i_format.simmediate << 2);
58841ca86e8SRalf Baechle 			if (insn.i_format.opcode == beql_op)
589d8d4e3aeSManeesh Soni 				ret = BRANCH_LIKELY_TAKEN;
590d8d4e3aeSManeesh Soni 		} else
5911da177e4SLinus Torvalds 			epc += 8;
5921da177e4SLinus Torvalds 		regs->cp0_epc = epc;
5931da177e4SLinus Torvalds 		break;
5941da177e4SLinus Torvalds 
5951da177e4SLinus Torvalds 	case bnel_op:
596319824eaSMarkos Chandras 		if (NO_R6EMU)
5971f4edde4SMaciej W. Rozycki 			goto sigill_r2r6;
598c9b02990SLiangliang Huang 		fallthrough;
599319824eaSMarkos Chandras 	case bne_op:
6001da177e4SLinus Torvalds 		if (regs->regs[insn.i_format.rs] !=
601d8d4e3aeSManeesh Soni 		    regs->regs[insn.i_format.rt]) {
6021da177e4SLinus Torvalds 			epc = epc + 4 + (insn.i_format.simmediate << 2);
60341ca86e8SRalf Baechle 			if (insn.i_format.opcode == bnel_op)
604d8d4e3aeSManeesh Soni 				ret = BRANCH_LIKELY_TAKEN;
605d8d4e3aeSManeesh Soni 		} else
6061da177e4SLinus Torvalds 			epc += 8;
6071da177e4SLinus Torvalds 		regs->cp0_epc = epc;
6081da177e4SLinus Torvalds 		break;
6091da177e4SLinus Torvalds 
610319824eaSMarkos Chandras 	case blezl_op: /* not really i_format */
611e9d92d22SMarkos Chandras 		if (!insn.i_format.rt && NO_R6EMU)
6121f4edde4SMaciej W. Rozycki 			goto sigill_r2r6;
613c9b02990SLiangliang Huang 		fallthrough;
614319824eaSMarkos Chandras 	case blez_op:
615a8ff66f5SMarkos Chandras 		/*
616a8ff66f5SMarkos Chandras 		 * Compact branches for R6 for the
617a8ff66f5SMarkos Chandras 		 * blez and blezl opcodes.
618a8ff66f5SMarkos Chandras 		 * BLEZ  | rs = 0 | rt != 0  == BLEZALC
619a8ff66f5SMarkos Chandras 		 * BLEZ  | rs = rt != 0      == BGEZALC
620a8ff66f5SMarkos Chandras 		 * BLEZ  | rs != 0 | rt != 0 == BGEUC
621a8ff66f5SMarkos Chandras 		 * BLEZL | rs = 0 | rt != 0  == BLEZC
622a8ff66f5SMarkos Chandras 		 * BLEZL | rs = rt != 0      == BGEZC
623a8ff66f5SMarkos Chandras 		 * BLEZL | rs != 0 | rt != 0 == BGEC
624a8ff66f5SMarkos Chandras 		 *
625a8ff66f5SMarkos Chandras 		 * For real BLEZ{,L}, rt is always 0.
626a8ff66f5SMarkos Chandras 		 */
627a8ff66f5SMarkos Chandras 
628a8ff66f5SMarkos Chandras 		if (cpu_has_mips_r6 && insn.i_format.rt) {
629a8ff66f5SMarkos Chandras 			if ((insn.i_format.opcode == blez_op) &&
630a8ff66f5SMarkos Chandras 			    ((!insn.i_format.rs && insn.i_format.rt) ||
631a8ff66f5SMarkos Chandras 			     (insn.i_format.rs == insn.i_format.rt)))
632a8ff66f5SMarkos Chandras 				regs->regs[31] = epc + 4;
633a8ff66f5SMarkos Chandras 			regs->cp0_epc += 8;
634a8ff66f5SMarkos Chandras 			break;
635a8ff66f5SMarkos Chandras 		}
6361da177e4SLinus Torvalds 		/* rt field assumed to be zero */
637d8d4e3aeSManeesh Soni 		if ((long)regs->regs[insn.i_format.rs] <= 0) {
6381da177e4SLinus Torvalds 			epc = epc + 4 + (insn.i_format.simmediate << 2);
63941ca86e8SRalf Baechle 			if (insn.i_format.opcode == blezl_op)
640d8d4e3aeSManeesh Soni 				ret = BRANCH_LIKELY_TAKEN;
641d8d4e3aeSManeesh Soni 		} else
6421da177e4SLinus Torvalds 			epc += 8;
6431da177e4SLinus Torvalds 		regs->cp0_epc = epc;
6441da177e4SLinus Torvalds 		break;
6451da177e4SLinus Torvalds 
6461da177e4SLinus Torvalds 	case bgtzl_op:
647e9d92d22SMarkos Chandras 		if (!insn.i_format.rt && NO_R6EMU)
6481f4edde4SMaciej W. Rozycki 			goto sigill_r2r6;
649c9b02990SLiangliang Huang 		fallthrough;
650319824eaSMarkos Chandras 	case bgtz_op:
651f1b44067SMarkos Chandras 		/*
652f1b44067SMarkos Chandras 		 * Compact branches for R6 for the
653f1b44067SMarkos Chandras 		 * bgtz and bgtzl opcodes.
654f1b44067SMarkos Chandras 		 * BGTZ  | rs = 0 | rt != 0  == BGTZALC
655f1b44067SMarkos Chandras 		 * BGTZ  | rs = rt != 0      == BLTZALC
656f1b44067SMarkos Chandras 		 * BGTZ  | rs != 0 | rt != 0 == BLTUC
657f1b44067SMarkos Chandras 		 * BGTZL | rs = 0 | rt != 0  == BGTZC
658f1b44067SMarkos Chandras 		 * BGTZL | rs = rt != 0      == BLTZC
659f1b44067SMarkos Chandras 		 * BGTZL | rs != 0 | rt != 0 == BLTC
660f1b44067SMarkos Chandras 		 *
661f1b44067SMarkos Chandras 		 * *ZALC varint for BGTZ &&& rt != 0
662f1b44067SMarkos Chandras 		 * For real GTZ{,L}, rt is always 0.
663f1b44067SMarkos Chandras 		 */
664f1b44067SMarkos Chandras 		if (cpu_has_mips_r6 && insn.i_format.rt) {
665f1b44067SMarkos Chandras 			if ((insn.i_format.opcode == blez_op) &&
666f1b44067SMarkos Chandras 			    ((!insn.i_format.rs && insn.i_format.rt) ||
667f1b44067SMarkos Chandras 			    (insn.i_format.rs == insn.i_format.rt)))
668f1b44067SMarkos Chandras 				regs->regs[31] = epc + 4;
669f1b44067SMarkos Chandras 			regs->cp0_epc += 8;
670f1b44067SMarkos Chandras 			break;
671f1b44067SMarkos Chandras 		}
672f1b44067SMarkos Chandras 
6731da177e4SLinus Torvalds 		/* rt field assumed to be zero */
674d8d4e3aeSManeesh Soni 		if ((long)regs->regs[insn.i_format.rs] > 0) {
6751da177e4SLinus Torvalds 			epc = epc + 4 + (insn.i_format.simmediate << 2);
67641ca86e8SRalf Baechle 			if (insn.i_format.opcode == bgtzl_op)
677d8d4e3aeSManeesh Soni 				ret = BRANCH_LIKELY_TAKEN;
678d8d4e3aeSManeesh Soni 		} else
6791da177e4SLinus Torvalds 			epc += 8;
6801da177e4SLinus Torvalds 		regs->cp0_epc = epc;
6811da177e4SLinus Torvalds 		break;
6821da177e4SLinus Torvalds 
6836a1cc218SPaul Burton #ifdef CONFIG_MIPS_FP_SUPPORT
6841da177e4SLinus Torvalds 	/*
6851da177e4SLinus Torvalds 	 * And now the FPA/cp1 branch instructions.
6861da177e4SLinus Torvalds 	 */
6876a1cc218SPaul Burton 	case cop1_op: {
6886a1cc218SPaul Burton 		unsigned int bit, fcr31, reg;
6896a1cc218SPaul Burton 
690c8a34581SMarkos Chandras 		if (cpu_has_mips_r6 &&
691c8a34581SMarkos Chandras 		    ((insn.i_format.rs == bc1eqz_op) ||
692c8a34581SMarkos Chandras 		     (insn.i_format.rs == bc1nez_op))) {
693cc97ab23SPaul Burton 			if (!init_fp_ctx(current))
694cc97ab23SPaul Burton 				lose_fpu(1);
695c8a34581SMarkos Chandras 			reg = insn.i_format.rt;
696ac149698SPaul Burton 			bit = get_fpr32(&current->thread.fpu.fpr[reg], 0) & 0x1;
697ac149698SPaul Burton 			if (insn.i_format.rs == bc1eqz_op)
698ac149698SPaul Burton 				bit = !bit;
699c8a34581SMarkos Chandras 			own_fpu(1);
700c8a34581SMarkos Chandras 			if (bit)
701c8a34581SMarkos Chandras 				epc = epc + 4 +
702c8a34581SMarkos Chandras 					(insn.i_format.simmediate << 2);
703c8a34581SMarkos Chandras 			else
704c8a34581SMarkos Chandras 				epc += 8;
705c8a34581SMarkos Chandras 			regs->cp0_epc = epc;
706c8a34581SMarkos Chandras 
707c8a34581SMarkos Chandras 			break;
708c8a34581SMarkos Chandras 		} else {
709c8a34581SMarkos Chandras 
7101d74f6bcSRalf Baechle 			preempt_disable();
7111d74f6bcSRalf Baechle 			if (is_fpu_owner())
712842dfc11SManuel Lauss 			        fcr31 = read_32bit_cp1_register(CP1_STATUS);
7131d74f6bcSRalf Baechle 			else
714eae89076SAtsushi Nemoto 				fcr31 = current->thread.fpu.fcr31;
7151d74f6bcSRalf Baechle 			preempt_enable();
7161d74f6bcSRalf Baechle 
7171da177e4SLinus Torvalds 			bit = (insn.i_format.rt >> 2);
7181da177e4SLinus Torvalds 			bit += (bit != 0);
7191da177e4SLinus Torvalds 			bit += 23;
720ee1cca1bSRalf Baechle 			switch (insn.i_format.rt & 3) {
7211da177e4SLinus Torvalds 			case 0: /* bc1f */
7221da177e4SLinus Torvalds 			case 2: /* bc1fl */
723d8d4e3aeSManeesh Soni 				if (~fcr31 & (1 << bit)) {
724c8a34581SMarkos Chandras 					epc = epc + 4 +
725c8a34581SMarkos Chandras 						(insn.i_format.simmediate << 2);
726d8d4e3aeSManeesh Soni 					if (insn.i_format.rt == 2)
727d8d4e3aeSManeesh Soni 						ret = BRANCH_LIKELY_TAKEN;
728d8d4e3aeSManeesh Soni 				} else
7291da177e4SLinus Torvalds 					epc += 8;
7301da177e4SLinus Torvalds 				regs->cp0_epc = epc;
7311da177e4SLinus Torvalds 				break;
7321da177e4SLinus Torvalds 
7331da177e4SLinus Torvalds 			case 1: /* bc1t */
7341da177e4SLinus Torvalds 			case 3: /* bc1tl */
735d8d4e3aeSManeesh Soni 				if (fcr31 & (1 << bit)) {
736c8a34581SMarkos Chandras 					epc = epc + 4 +
737c8a34581SMarkos Chandras 						(insn.i_format.simmediate << 2);
738d8d4e3aeSManeesh Soni 					if (insn.i_format.rt == 3)
739d8d4e3aeSManeesh Soni 						ret = BRANCH_LIKELY_TAKEN;
740d8d4e3aeSManeesh Soni 				} else
7411da177e4SLinus Torvalds 					epc += 8;
7421da177e4SLinus Torvalds 				regs->cp0_epc = epc;
7431da177e4SLinus Torvalds 				break;
7441da177e4SLinus Torvalds 			}
7451da177e4SLinus Torvalds 			break;
746c8a34581SMarkos Chandras 		}
7476a1cc218SPaul Burton 	}
7486a1cc218SPaul Burton #endif /* CONFIG_MIPS_FP_SUPPORT */
7496a1cc218SPaul Burton 
750126336f0SDavid Daney #ifdef CONFIG_CPU_CAVIUM_OCTEON
751126336f0SDavid Daney 	case lwc2_op: /* This is bbit0 on Octeon */
752126336f0SDavid Daney 		if ((regs->regs[insn.i_format.rs] & (1ull<<insn.i_format.rt))
753126336f0SDavid Daney 		     == 0)
754126336f0SDavid Daney 			epc = epc + 4 + (insn.i_format.simmediate << 2);
755126336f0SDavid Daney 		else
756126336f0SDavid Daney 			epc += 8;
757126336f0SDavid Daney 		regs->cp0_epc = epc;
758126336f0SDavid Daney 		break;
759126336f0SDavid Daney 	case ldc2_op: /* This is bbit032 on Octeon */
760126336f0SDavid Daney 		if ((regs->regs[insn.i_format.rs] &
761126336f0SDavid Daney 		    (1ull<<(insn.i_format.rt+32))) == 0)
762126336f0SDavid Daney 			epc = epc + 4 + (insn.i_format.simmediate << 2);
763126336f0SDavid Daney 		else
764126336f0SDavid Daney 			epc += 8;
765126336f0SDavid Daney 		regs->cp0_epc = epc;
766126336f0SDavid Daney 		break;
767126336f0SDavid Daney 	case swc2_op: /* This is bbit1 on Octeon */
768126336f0SDavid Daney 		if (regs->regs[insn.i_format.rs] & (1ull<<insn.i_format.rt))
769126336f0SDavid Daney 			epc = epc + 4 + (insn.i_format.simmediate << 2);
770126336f0SDavid Daney 		else
771126336f0SDavid Daney 			epc += 8;
772126336f0SDavid Daney 		regs->cp0_epc = epc;
773126336f0SDavid Daney 		break;
774126336f0SDavid Daney 	case sdc2_op: /* This is bbit132 on Octeon */
775126336f0SDavid Daney 		if (regs->regs[insn.i_format.rs] &
776126336f0SDavid Daney 		    (1ull<<(insn.i_format.rt+32)))
777126336f0SDavid Daney 			epc = epc + 4 + (insn.i_format.simmediate << 2);
778126336f0SDavid Daney 		else
779126336f0SDavid Daney 			epc += 8;
780126336f0SDavid Daney 		regs->cp0_epc = epc;
781126336f0SDavid Daney 		break;
7828467ca01SMarkos Chandras #else
7838467ca01SMarkos Chandras 	case bc6_op:
7848467ca01SMarkos Chandras 		/* Only valid for MIPS R6 */
785a60b1a5bSMaciej W. Rozycki 		if (!cpu_has_mips_r6)
786a60b1a5bSMaciej W. Rozycki 			goto sigill_r6;
7878467ca01SMarkos Chandras 		regs->cp0_epc += 8;
7888467ca01SMarkos Chandras 		break;
78984fef630SMarkos Chandras 	case balc6_op:
790a60b1a5bSMaciej W. Rozycki 		if (!cpu_has_mips_r6)
791a60b1a5bSMaciej W. Rozycki 			goto sigill_r6;
79284fef630SMarkos Chandras 		/* Compact branch: BALC */
79384fef630SMarkos Chandras 		regs->regs[31] = epc + 4;
79484fef630SMarkos Chandras 		epc += 4 + (insn.i_format.simmediate << 2);
79584fef630SMarkos Chandras 		regs->cp0_epc = epc;
79684fef630SMarkos Chandras 		break;
7971c66b79bSPaul Burton 	case pop66_op:
798a60b1a5bSMaciej W. Rozycki 		if (!cpu_has_mips_r6)
799a60b1a5bSMaciej W. Rozycki 			goto sigill_r6;
80069b9a2fdSMarkos Chandras 		/* Compact branch: BEQZC || JIC */
80169b9a2fdSMarkos Chandras 		regs->cp0_epc += 8;
80269b9a2fdSMarkos Chandras 		break;
8031c66b79bSPaul Burton 	case pop76_op:
804a60b1a5bSMaciej W. Rozycki 		if (!cpu_has_mips_r6)
805a60b1a5bSMaciej W. Rozycki 			goto sigill_r6;
80628d6f93dSMarkos Chandras 		/* Compact branch: BNEZC || JIALC */
8071a73d931SPaul Burton 		if (!insn.i_format.rs) {
8081a73d931SPaul Burton 			/* JIALC: set $31/ra */
80928d6f93dSMarkos Chandras 			regs->regs[31] = epc + 4;
8101a73d931SPaul Burton 		}
81128d6f93dSMarkos Chandras 		regs->cp0_epc += 8;
81228d6f93dSMarkos Chandras 		break;
813126336f0SDavid Daney #endif
8141b492600SPaul Burton 	case pop10_op:
8151b492600SPaul Burton 	case pop30_op:
816c893ce38SMarkos Chandras 		/* Only valid for MIPS R6 */
817a60b1a5bSMaciej W. Rozycki 		if (!cpu_has_mips_r6)
818a60b1a5bSMaciej W. Rozycki 			goto sigill_r6;
81910d962d5SMarkos Chandras 		/*
82010d962d5SMarkos Chandras 		 * Compact branches:
82110d962d5SMarkos Chandras 		 * bovc, beqc, beqzalc, bnvc, bnec, bnezlac
82210d962d5SMarkos Chandras 		 */
823c893ce38SMarkos Chandras 		if (insn.i_format.rt && !insn.i_format.rs)
824c893ce38SMarkos Chandras 			regs->regs[31] = epc + 4;
825c893ce38SMarkos Chandras 		regs->cp0_epc += 8;
826c893ce38SMarkos Chandras 		break;
8271da177e4SLinus Torvalds 	}
8281da177e4SLinus Torvalds 
829d8d4e3aeSManeesh Soni 	return ret;
830d8d4e3aeSManeesh Soni 
8315f9f41c4SMarkos Chandras sigill_dsp:
832f259fe29SMaciej W. Rozycki 	pr_debug("%s: DSP branch but not DSP ASE - sending SIGILL.\n",
8337b82c105SMaciej W. Rozycki 		 current->comm);
8343cf5d076SEric W. Biederman 	force_sig(SIGILL);
835d8d4e3aeSManeesh Soni 	return -EFAULT;
8361f4edde4SMaciej W. Rozycki sigill_r2r6:
837f259fe29SMaciej W. Rozycki 	pr_debug("%s: R2 branch but r2-to-r6 emulator is not present - sending SIGILL.\n",
8385f9f41c4SMarkos Chandras 		 current->comm);
8393cf5d076SEric W. Biederman 	force_sig(SIGILL);
8405f9f41c4SMarkos Chandras 	return -EFAULT;
841a60b1a5bSMaciej W. Rozycki sigill_r6:
842f259fe29SMaciej W. Rozycki 	pr_debug("%s: R6 branch but no MIPSr6 ISA support - sending SIGILL.\n",
843a60b1a5bSMaciej W. Rozycki 		 current->comm);
8443cf5d076SEric W. Biederman 	force_sig(SIGILL);
845a60b1a5bSMaciej W. Rozycki 	return -EFAULT;
846d8d4e3aeSManeesh Soni }
847d8d4e3aeSManeesh Soni EXPORT_SYMBOL_GPL(__compute_return_epc_for_insn);
848d8d4e3aeSManeesh Soni 
__compute_return_epc(struct pt_regs * regs)849d8d4e3aeSManeesh Soni int __compute_return_epc(struct pt_regs *regs)
850d8d4e3aeSManeesh Soni {
851d8d4e3aeSManeesh Soni 	unsigned int __user *addr;
852d8d4e3aeSManeesh Soni 	long epc;
853d8d4e3aeSManeesh Soni 	union mips_instruction insn;
854d8d4e3aeSManeesh Soni 
855d8d4e3aeSManeesh Soni 	epc = regs->cp0_epc;
856d8d4e3aeSManeesh Soni 	if (epc & 3)
857d8d4e3aeSManeesh Soni 		goto unaligned;
858d8d4e3aeSManeesh Soni 
859d8d4e3aeSManeesh Soni 	/*
860d8d4e3aeSManeesh Soni 	 * Read the instruction
861d8d4e3aeSManeesh Soni 	 */
862d8d4e3aeSManeesh Soni 	addr = (unsigned int __user *) epc;
863d8d4e3aeSManeesh Soni 	if (__get_user(insn.word, addr)) {
8643cf5d076SEric W. Biederman 		force_sig(SIGSEGV);
865d8d4e3aeSManeesh Soni 		return -EFAULT;
866d8d4e3aeSManeesh Soni 	}
867d8d4e3aeSManeesh Soni 
868d8d4e3aeSManeesh Soni 	return __compute_return_epc_for_insn(regs, insn);
8691da177e4SLinus Torvalds 
8701da177e4SLinus Torvalds unaligned:
8711da177e4SLinus Torvalds 	printk("%s: unaligned epc - sending SIGBUS.\n", current->comm);
8723cf5d076SEric W. Biederman 	force_sig(SIGBUS);
8731da177e4SLinus Torvalds 	return -EFAULT;
8741da177e4SLinus Torvalds }
875d05c5130SMarcin Nowakowski 
876d05c5130SMarcin Nowakowski #if (defined CONFIG_KPROBES) || (defined CONFIG_UPROBES)
877d05c5130SMarcin Nowakowski 
__insn_is_compact_branch(union mips_instruction insn)878d05c5130SMarcin Nowakowski int __insn_is_compact_branch(union mips_instruction insn)
879d05c5130SMarcin Nowakowski {
880d05c5130SMarcin Nowakowski 	if (!cpu_has_mips_r6)
881d05c5130SMarcin Nowakowski 		return 0;
882d05c5130SMarcin Nowakowski 
883d05c5130SMarcin Nowakowski 	switch (insn.i_format.opcode) {
884d05c5130SMarcin Nowakowski 	case blezl_op:
885d05c5130SMarcin Nowakowski 	case bgtzl_op:
886d05c5130SMarcin Nowakowski 	case blez_op:
887d05c5130SMarcin Nowakowski 	case bgtz_op:
888d05c5130SMarcin Nowakowski 		/*
889d05c5130SMarcin Nowakowski 		 * blez[l] and bgtz[l] opcodes with non-zero rt
890d05c5130SMarcin Nowakowski 		 * are MIPS R6 compact branches
891d05c5130SMarcin Nowakowski 		 */
892d05c5130SMarcin Nowakowski 		if (insn.i_format.rt)
893d05c5130SMarcin Nowakowski 			return 1;
894d05c5130SMarcin Nowakowski 		break;
895d05c5130SMarcin Nowakowski 	case bc6_op:
896d05c5130SMarcin Nowakowski 	case balc6_op:
897d05c5130SMarcin Nowakowski 	case pop10_op:
898d05c5130SMarcin Nowakowski 	case pop30_op:
899d05c5130SMarcin Nowakowski 	case pop66_op:
900d05c5130SMarcin Nowakowski 	case pop76_op:
901d05c5130SMarcin Nowakowski 		return 1;
902d05c5130SMarcin Nowakowski 	}
903d05c5130SMarcin Nowakowski 
904d05c5130SMarcin Nowakowski 	return 0;
905d05c5130SMarcin Nowakowski }
906d05c5130SMarcin Nowakowski EXPORT_SYMBOL_GPL(__insn_is_compact_branch);
907d05c5130SMarcin Nowakowski 
908d05c5130SMarcin Nowakowski #endif  /* CONFIG_KPROBES || CONFIG_UPROBES */
909