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) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * cp1emu.c: a MIPS coprocessor 1 (FPU) instruction emulator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * MIPS floating point support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  * Copyright (C) 1994-2000 Algorithmics Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  * Copyright (C) 2000  MIPS Technologies, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  * A complete emulator for MIPS coprocessor 1 instructions.  This is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  * required for #float(switch) or #float(trap), where it catches all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  * COP1 instructions via the "CoProcessor Unusable" exception.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15)  * More surprisingly it is also required for #float(ieee), to help out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16)  * the hardware FPU at the boundaries of the IEEE-754 representation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17)  * (denormalised values, infinities, underflow, etc).  It is made
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18)  * quite nasty because emulation of some non-COP1 instructions is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19)  * required, e.g. in branch delay slots.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21)  * Note if you know that you won't have an FPU, then you'll get much
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22)  * better performance by compiling with -msoft-float!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include <linux/debugfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include <linux/percpu-defs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #include <linux/perf_event.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #include <asm/branch.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #include <asm/inst.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #include <asm/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #include <asm/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #include <asm/cpu-info.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) #include <asm/processor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) #include <asm/fpu_emulator.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) #include <asm/fpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) #include <asm/mips-r2-to-r6-emul.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) #include "ieee754.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) /* Function which emulates a floating point instruction. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) static int fpu_emu(struct pt_regs *, struct mips_fpu_struct *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 	mips_instruction);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) static int fpux_emu(struct pt_regs *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 	struct mips_fpu_struct *, mips_instruction, void __user **);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) /* Control registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) #define FPCREG_RID	0	/* $0  = revision id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) #define FPCREG_FCCR	25	/* $25 = fccr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) #define FPCREG_FEXR	26	/* $26 = fexr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) #define FPCREG_FENR	28	/* $28 = fenr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) #define FPCREG_CSR	31	/* $31 = csr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) /* convert condition code register number to csr bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) const unsigned int fpucondbit[8] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 	FPU_CSR_COND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 	FPU_CSR_COND1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 	FPU_CSR_COND2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 	FPU_CSR_COND3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 	FPU_CSR_COND4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 	FPU_CSR_COND5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 	FPU_CSR_COND6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 	FPU_CSR_COND7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) /* (microMIPS) Convert certain microMIPS instructions to MIPS32 format. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) static const int sd_format[] = {16, 17, 0, 0, 0, 0, 0, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) static const int sdps_format[] = {16, 17, 22, 0, 0, 0, 0, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) static const int dwl_format[] = {17, 20, 21, 0, 0, 0, 0, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) static const int swl_format[] = {16, 20, 21, 0, 0, 0, 0, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78)  * This functions translates a 32-bit microMIPS instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79)  * into a 32-bit MIPS32 instruction. Returns 0 on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80)  * and SIGILL otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) static int microMIPS32_to_MIPS32(union mips_instruction *insn_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 	union mips_instruction insn = *insn_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 	union mips_instruction mips32_insn = insn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 	int func, fmt, op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 	switch (insn.mm_i_format.opcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 	case mm_ldc132_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 		mips32_insn.mm_i_format.opcode = ldc1_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 		mips32_insn.mm_i_format.rt = insn.mm_i_format.rs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 		mips32_insn.mm_i_format.rs = insn.mm_i_format.rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 	case mm_lwc132_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 		mips32_insn.mm_i_format.opcode = lwc1_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 		mips32_insn.mm_i_format.rt = insn.mm_i_format.rs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 		mips32_insn.mm_i_format.rs = insn.mm_i_format.rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 	case mm_sdc132_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 		mips32_insn.mm_i_format.opcode = sdc1_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 		mips32_insn.mm_i_format.rt = insn.mm_i_format.rs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 		mips32_insn.mm_i_format.rs = insn.mm_i_format.rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 	case mm_swc132_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 		mips32_insn.mm_i_format.opcode = swc1_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 		mips32_insn.mm_i_format.rt = insn.mm_i_format.rs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 		mips32_insn.mm_i_format.rs = insn.mm_i_format.rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 	case mm_pool32i_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 		/* NOTE: offset is << by 1 if in microMIPS mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 		if ((insn.mm_i_format.rt == mm_bc1f_op) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 		    (insn.mm_i_format.rt == mm_bc1t_op)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 			mips32_insn.fb_format.opcode = cop1_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 			mips32_insn.fb_format.bc = bc_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 			mips32_insn.fb_format.flag =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 				(insn.mm_i_format.rt == mm_bc1t_op) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 			return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	case mm_pool32f_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 		switch (insn.mm_fp0_format.func) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 		case mm_32f_01_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 		case mm_32f_11_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 		case mm_32f_02_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 		case mm_32f_12_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 		case mm_32f_41_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 		case mm_32f_51_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 		case mm_32f_42_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 		case mm_32f_52_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 			op = insn.mm_fp0_format.func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 			if (op == mm_32f_01_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 				func = madd_s_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 			else if (op == mm_32f_11_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 				func = madd_d_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 			else if (op == mm_32f_02_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 				func = nmadd_s_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 			else if (op == mm_32f_12_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 				func = nmadd_d_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 			else if (op == mm_32f_41_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 				func = msub_s_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 			else if (op == mm_32f_51_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 				func = msub_d_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 			else if (op == mm_32f_42_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 				func = nmsub_s_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 				func = nmsub_d_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 			mips32_insn.fp6_format.opcode = cop1x_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 			mips32_insn.fp6_format.fr = insn.mm_fp6_format.fr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 			mips32_insn.fp6_format.ft = insn.mm_fp6_format.ft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 			mips32_insn.fp6_format.fs = insn.mm_fp6_format.fs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 			mips32_insn.fp6_format.fd = insn.mm_fp6_format.fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 			mips32_insn.fp6_format.func = func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 		case mm_32f_10_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 			func = -1;	/* Invalid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 			op = insn.mm_fp5_format.op & 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 			if (op == mm_ldxc1_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 				func = ldxc1_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 			else if (op == mm_sdxc1_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 				func = sdxc1_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 			else if (op == mm_lwxc1_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 				func = lwxc1_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 			else if (op == mm_swxc1_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 				func = swxc1_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 			if (func != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 				mips32_insn.r_format.opcode = cop1x_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 				mips32_insn.r_format.rs =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 					insn.mm_fp5_format.base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 				mips32_insn.r_format.rt =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 					insn.mm_fp5_format.index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 				mips32_insn.r_format.rd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 				mips32_insn.r_format.re = insn.mm_fp5_format.fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 				mips32_insn.r_format.func = func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 			} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 		case mm_32f_40_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 			op = -1;	/* Invalid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 			if (insn.mm_fp2_format.op == mm_fmovt_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 				op = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 			else if (insn.mm_fp2_format.op == mm_fmovf_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 				op = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 			if (op != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 				mips32_insn.fp0_format.opcode = cop1_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 				mips32_insn.fp0_format.fmt =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 					sdps_format[insn.mm_fp2_format.fmt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 				mips32_insn.fp0_format.ft =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 					(insn.mm_fp2_format.cc<<2) + op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 				mips32_insn.fp0_format.fs =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 					insn.mm_fp2_format.fs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 				mips32_insn.fp0_format.fd =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 					insn.mm_fp2_format.fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 				mips32_insn.fp0_format.func = fmovc_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 			} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 		case mm_32f_60_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 			func = -1;	/* Invalid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 			if (insn.mm_fp0_format.op == mm_fadd_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 				func = fadd_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 			else if (insn.mm_fp0_format.op == mm_fsub_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 				func = fsub_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 			else if (insn.mm_fp0_format.op == mm_fmul_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 				func = fmul_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 			else if (insn.mm_fp0_format.op == mm_fdiv_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 				func = fdiv_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 			if (func != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 				mips32_insn.fp0_format.opcode = cop1_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 				mips32_insn.fp0_format.fmt =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 					sdps_format[insn.mm_fp0_format.fmt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 				mips32_insn.fp0_format.ft =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 					insn.mm_fp0_format.ft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 				mips32_insn.fp0_format.fs =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 					insn.mm_fp0_format.fs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 				mips32_insn.fp0_format.fd =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 					insn.mm_fp0_format.fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 				mips32_insn.fp0_format.func = func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 			} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 		case mm_32f_70_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 			func = -1;	/* Invalid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 			if (insn.mm_fp0_format.op == mm_fmovn_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 				func = fmovn_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 			else if (insn.mm_fp0_format.op == mm_fmovz_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 				func = fmovz_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 			if (func != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 				mips32_insn.fp0_format.opcode = cop1_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 				mips32_insn.fp0_format.fmt =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 					sdps_format[insn.mm_fp0_format.fmt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 				mips32_insn.fp0_format.ft =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 					insn.mm_fp0_format.ft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 				mips32_insn.fp0_format.fs =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 					insn.mm_fp0_format.fs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 				mips32_insn.fp0_format.fd =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 					insn.mm_fp0_format.fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 				mips32_insn.fp0_format.func = func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 			} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 		case mm_32f_73_op:    /* POOL32FXF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 			switch (insn.mm_fp1_format.op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 			case mm_movf0_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 			case mm_movf1_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 			case mm_movt0_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 			case mm_movt1_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 				if ((insn.mm_fp1_format.op & 0x7f) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 				    mm_movf0_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 					op = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 				else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 					op = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 				mips32_insn.r_format.opcode = spec_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 				mips32_insn.r_format.rs = insn.mm_fp4_format.fs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 				mips32_insn.r_format.rt =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 					(insn.mm_fp4_format.cc << 2) + op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 				mips32_insn.r_format.rd = insn.mm_fp4_format.rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 				mips32_insn.r_format.re = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 				mips32_insn.r_format.func = movc_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 			case mm_fcvtd0_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 			case mm_fcvtd1_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 			case mm_fcvts0_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 			case mm_fcvts1_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 				if ((insn.mm_fp1_format.op & 0x7f) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 				    mm_fcvtd0_op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 					func = fcvtd_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 					fmt = swl_format[insn.mm_fp3_format.fmt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 				} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 					func = fcvts_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 					fmt = dwl_format[insn.mm_fp3_format.fmt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 				mips32_insn.fp0_format.opcode = cop1_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 				mips32_insn.fp0_format.fmt = fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 				mips32_insn.fp0_format.ft = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 				mips32_insn.fp0_format.fs =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 					insn.mm_fp3_format.fs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 				mips32_insn.fp0_format.fd =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 					insn.mm_fp3_format.rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 				mips32_insn.fp0_format.func = func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 			case mm_fmov0_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 			case mm_fmov1_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 			case mm_fabs0_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 			case mm_fabs1_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 			case mm_fneg0_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 			case mm_fneg1_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 				if ((insn.mm_fp1_format.op & 0x7f) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 				    mm_fmov0_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 					func = fmov_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 				else if ((insn.mm_fp1_format.op & 0x7f) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 					 mm_fabs0_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 					func = fabs_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 				else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 					func = fneg_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 				mips32_insn.fp0_format.opcode = cop1_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 				mips32_insn.fp0_format.fmt =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 					sdps_format[insn.mm_fp3_format.fmt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 				mips32_insn.fp0_format.ft = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 				mips32_insn.fp0_format.fs =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 					insn.mm_fp3_format.fs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 				mips32_insn.fp0_format.fd =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 					insn.mm_fp3_format.rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 				mips32_insn.fp0_format.func = func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 			case mm_ffloorl_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 			case mm_ffloorw_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 			case mm_fceill_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 			case mm_fceilw_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 			case mm_ftruncl_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 			case mm_ftruncw_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 			case mm_froundl_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 			case mm_froundw_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 			case mm_fcvtl_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 			case mm_fcvtw_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 				if (insn.mm_fp1_format.op == mm_ffloorl_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 					func = ffloorl_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 				else if (insn.mm_fp1_format.op == mm_ffloorw_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 					func = ffloor_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 				else if (insn.mm_fp1_format.op == mm_fceill_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 					func = fceill_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 				else if (insn.mm_fp1_format.op == mm_fceilw_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 					func = fceil_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 				else if (insn.mm_fp1_format.op == mm_ftruncl_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 					func = ftruncl_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 				else if (insn.mm_fp1_format.op == mm_ftruncw_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 					func = ftrunc_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 				else if (insn.mm_fp1_format.op == mm_froundl_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 					func = froundl_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 				else if (insn.mm_fp1_format.op == mm_froundw_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 					func = fround_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 				else if (insn.mm_fp1_format.op == mm_fcvtl_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 					func = fcvtl_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 				else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 					func = fcvtw_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 				mips32_insn.fp0_format.opcode = cop1_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 				mips32_insn.fp0_format.fmt =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 					sd_format[insn.mm_fp1_format.fmt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 				mips32_insn.fp0_format.ft = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 				mips32_insn.fp0_format.fs =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 					insn.mm_fp1_format.fs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 				mips32_insn.fp0_format.fd =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 					insn.mm_fp1_format.rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 				mips32_insn.fp0_format.func = func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 			case mm_frsqrt_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 			case mm_fsqrt_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 			case mm_frecip_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 				if (insn.mm_fp1_format.op == mm_frsqrt_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 					func = frsqrt_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 				else if (insn.mm_fp1_format.op == mm_fsqrt_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 					func = fsqrt_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 				else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 					func = frecip_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 				mips32_insn.fp0_format.opcode = cop1_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 				mips32_insn.fp0_format.fmt =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 					sdps_format[insn.mm_fp1_format.fmt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 				mips32_insn.fp0_format.ft = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 				mips32_insn.fp0_format.fs =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 					insn.mm_fp1_format.fs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 				mips32_insn.fp0_format.fd =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 					insn.mm_fp1_format.rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 				mips32_insn.fp0_format.func = func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 			case mm_mfc1_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 			case mm_mtc1_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 			case mm_cfc1_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 			case mm_ctc1_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 			case mm_mfhc1_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 			case mm_mthc1_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 				if (insn.mm_fp1_format.op == mm_mfc1_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 					op = mfc_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 				else if (insn.mm_fp1_format.op == mm_mtc1_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 					op = mtc_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 				else if (insn.mm_fp1_format.op == mm_cfc1_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 					op = cfc_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 				else if (insn.mm_fp1_format.op == mm_ctc1_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 					op = ctc_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 				else if (insn.mm_fp1_format.op == mm_mfhc1_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 					op = mfhc_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 				else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 					op = mthc_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 				mips32_insn.fp1_format.opcode = cop1_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 				mips32_insn.fp1_format.op = op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 				mips32_insn.fp1_format.rt =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 					insn.mm_fp1_format.rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 				mips32_insn.fp1_format.fs =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 					insn.mm_fp1_format.fs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 				mips32_insn.fp1_format.fd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 				mips32_insn.fp1_format.func = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 			default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 		case mm_32f_74_op:	/* c.cond.fmt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 			mips32_insn.fp0_format.opcode = cop1_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 			mips32_insn.fp0_format.fmt =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 				sdps_format[insn.mm_fp4_format.fmt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 			mips32_insn.fp0_format.ft = insn.mm_fp4_format.rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 			mips32_insn.fp0_format.fs = insn.mm_fp4_format.fs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 			mips32_insn.fp0_format.fd = insn.mm_fp4_format.cc << 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 			mips32_insn.fp0_format.func =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 				insn.mm_fp4_format.cond | MM_MIPS32_COND_FC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 			return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 		return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 	*insn_ptr = mips32_insn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419)  * Redundant with logic already in kernel/branch.c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420)  * embedded in compute_return_epc.  At some point,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421)  * a single subroutine should be used across both
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422)  * modules.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 		  unsigned long *contpc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 	union mips_instruction insn = (union mips_instruction)dec_insn.insn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 	unsigned int fcr31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 	unsigned int bit = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	unsigned int bit0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 	union fpureg *fpr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 	switch (insn.i_format.opcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 	case spec_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 		switch (insn.r_format.func) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 		case jalr_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 			if (insn.r_format.rd != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 				regs->regs[insn.r_format.rd] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 					regs->cp0_epc + dec_insn.pc_inc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 					dec_insn.next_pc_inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 			fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 		case jr_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 			/* For R6, JR already emulated in jalr_op */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 			if (NO_R6EMU && insn.r_format.func == jr_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 			*contpc = regs->regs[insn.r_format.rs];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 			return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	case bcond_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 		switch (insn.i_format.rt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 		case bltzal_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 		case bltzall_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 			if (NO_R6EMU && (insn.i_format.rs ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 			    insn.i_format.rt == bltzall_op))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 			regs->regs[31] = regs->cp0_epc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 				dec_insn.pc_inc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 				dec_insn.next_pc_inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 			fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 		case bltzl_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 			if (NO_R6EMU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 			fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 		case bltz_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 			if ((long)regs->regs[insn.i_format.rs] < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 				*contpc = regs->cp0_epc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 					dec_insn.pc_inc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 					(insn.i_format.simmediate << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 				*contpc = regs->cp0_epc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 					dec_insn.pc_inc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 					dec_insn.next_pc_inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 			return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 		case bgezal_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 		case bgezall_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 			if (NO_R6EMU && (insn.i_format.rs ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 			    insn.i_format.rt == bgezall_op))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 			regs->regs[31] = regs->cp0_epc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 				dec_insn.pc_inc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 				dec_insn.next_pc_inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 			fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 		case bgezl_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 			if (NO_R6EMU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 			fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 		case bgez_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 			if ((long)regs->regs[insn.i_format.rs] >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 				*contpc = regs->cp0_epc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 					dec_insn.pc_inc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 					(insn.i_format.simmediate << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 				*contpc = regs->cp0_epc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 					dec_insn.pc_inc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 					dec_insn.next_pc_inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 			return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 	case jalx_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 		set_isa16_mode(bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 	case jal_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 		regs->regs[31] = regs->cp0_epc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 			dec_insn.pc_inc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 			dec_insn.next_pc_inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 	case j_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 		*contpc = regs->cp0_epc + dec_insn.pc_inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 		*contpc >>= 28;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 		*contpc <<= 28;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 		*contpc |= (insn.j_format.target << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 		/* Set microMIPS mode bit: XOR for jalx. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 		*contpc ^= bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 	case beql_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 		if (NO_R6EMU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 	case beq_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 		if (regs->regs[insn.i_format.rs] ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 		    regs->regs[insn.i_format.rt])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 			*contpc = regs->cp0_epc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 				dec_insn.pc_inc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 				(insn.i_format.simmediate << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 			*contpc = regs->cp0_epc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 				dec_insn.pc_inc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 				dec_insn.next_pc_inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	case bnel_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 		if (NO_R6EMU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 	case bne_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 		if (regs->regs[insn.i_format.rs] !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 		    regs->regs[insn.i_format.rt])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 			*contpc = regs->cp0_epc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 				dec_insn.pc_inc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 				(insn.i_format.simmediate << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 			*contpc = regs->cp0_epc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 				dec_insn.pc_inc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 				dec_insn.next_pc_inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 	case blezl_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 		if (!insn.i_format.rt && NO_R6EMU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	case blez_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 		 * Compact branches for R6 for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 		 * blez and blezl opcodes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 		 * BLEZ  | rs = 0 | rt != 0  == BLEZALC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 		 * BLEZ  | rs = rt != 0      == BGEZALC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 		 * BLEZ  | rs != 0 | rt != 0 == BGEUC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 		 * BLEZL | rs = 0 | rt != 0  == BLEZC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 		 * BLEZL | rs = rt != 0      == BGEZC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 		 * BLEZL | rs != 0 | rt != 0 == BGEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 		 * For real BLEZ{,L}, rt is always 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 		if (cpu_has_mips_r6 && insn.i_format.rt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 			if ((insn.i_format.opcode == blez_op) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 			    ((!insn.i_format.rs && insn.i_format.rt) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 			     (insn.i_format.rs == insn.i_format.rt)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 				regs->regs[31] = regs->cp0_epc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 					dec_insn.pc_inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 			*contpc = regs->cp0_epc + dec_insn.pc_inc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 				dec_insn.next_pc_inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 			return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 		if ((long)regs->regs[insn.i_format.rs] <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 			*contpc = regs->cp0_epc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 				dec_insn.pc_inc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 				(insn.i_format.simmediate << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 			*contpc = regs->cp0_epc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 				dec_insn.pc_inc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 				dec_insn.next_pc_inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	case bgtzl_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 		if (!insn.i_format.rt && NO_R6EMU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 	case bgtz_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 		 * Compact branches for R6 for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 		 * bgtz and bgtzl opcodes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 		 * BGTZ  | rs = 0 | rt != 0  == BGTZALC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 		 * BGTZ  | rs = rt != 0      == BLTZALC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 		 * BGTZ  | rs != 0 | rt != 0 == BLTUC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 		 * BGTZL | rs = 0 | rt != 0  == BGTZC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 		 * BGTZL | rs = rt != 0      == BLTZC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 		 * BGTZL | rs != 0 | rt != 0 == BLTC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 		 * *ZALC varint for BGTZ &&& rt != 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 		 * For real GTZ{,L}, rt is always 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 		if (cpu_has_mips_r6 && insn.i_format.rt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 			if ((insn.i_format.opcode == blez_op) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 			    ((!insn.i_format.rs && insn.i_format.rt) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 			     (insn.i_format.rs == insn.i_format.rt)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 				regs->regs[31] = regs->cp0_epc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 					dec_insn.pc_inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 			*contpc = regs->cp0_epc + dec_insn.pc_inc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 				dec_insn.next_pc_inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 			return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 		if ((long)regs->regs[insn.i_format.rs] > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 			*contpc = regs->cp0_epc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 				dec_insn.pc_inc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 				(insn.i_format.simmediate << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 			*contpc = regs->cp0_epc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 				dec_insn.pc_inc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 				dec_insn.next_pc_inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	case pop10_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 	case pop30_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 		if (!cpu_has_mips_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 		if (insn.i_format.rt && !insn.i_format.rs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 			regs->regs[31] = regs->cp0_epc + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 		*contpc = regs->cp0_epc + dec_insn.pc_inc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 			dec_insn.next_pc_inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) #ifdef CONFIG_CPU_CAVIUM_OCTEON
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 	case lwc2_op: /* This is bbit0 on Octeon */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 		if ((regs->regs[insn.i_format.rs] & (1ull<<insn.i_format.rt)) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 			*contpc = regs->cp0_epc + 4 + (insn.i_format.simmediate << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 			*contpc = regs->cp0_epc + 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 	case ldc2_op: /* This is bbit032 on Octeon */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 		if ((regs->regs[insn.i_format.rs] & (1ull<<(insn.i_format.rt + 32))) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 			*contpc = regs->cp0_epc + 4 + (insn.i_format.simmediate << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 			*contpc = regs->cp0_epc + 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 	case swc2_op: /* This is bbit1 on Octeon */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 		if (regs->regs[insn.i_format.rs] & (1ull<<insn.i_format.rt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 			*contpc = regs->cp0_epc + 4 + (insn.i_format.simmediate << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 			*contpc = regs->cp0_epc + 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 	case sdc2_op: /* This is bbit132 on Octeon */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 		if (regs->regs[insn.i_format.rs] & (1ull<<(insn.i_format.rt + 32)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 			*contpc = regs->cp0_epc + 4 + (insn.i_format.simmediate << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 			*contpc = regs->cp0_epc + 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 	case bc6_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 		 * Only valid for MIPS R6 but we can still end up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 		 * here from a broken userland so just tell emulator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 		 * this is not a branch and let it break later on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 		if  (!cpu_has_mips_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 		*contpc = regs->cp0_epc + dec_insn.pc_inc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 			dec_insn.next_pc_inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 	case balc6_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 		if (!cpu_has_mips_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 		regs->regs[31] = regs->cp0_epc + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 		*contpc = regs->cp0_epc + dec_insn.pc_inc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 			dec_insn.next_pc_inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	case pop66_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 		if (!cpu_has_mips_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 		*contpc = regs->cp0_epc + dec_insn.pc_inc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 			dec_insn.next_pc_inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	case pop76_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 		if (!cpu_has_mips_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 		if (!insn.i_format.rs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 			regs->regs[31] = regs->cp0_epc + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 		*contpc = regs->cp0_epc + dec_insn.pc_inc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 			dec_insn.next_pc_inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 	case cop0_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 	case cop1_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 		/* Need to check for R6 bc1nez and bc1eqz branches */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 		if (cpu_has_mips_r6 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 		    ((insn.i_format.rs == bc1eqz_op) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 		     (insn.i_format.rs == bc1nez_op))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 			bit = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 			fpr = &current->thread.fpu.fpr[insn.i_format.rt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 			bit0 = get_fpr32(fpr, 0) & 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 			switch (insn.i_format.rs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 			case bc1eqz_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 				bit = bit0 == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 			case bc1nez_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 				bit = bit0 != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 			if (bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 				*contpc = regs->cp0_epc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 					dec_insn.pc_inc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 					(insn.i_format.simmediate << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 				*contpc = regs->cp0_epc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 					dec_insn.pc_inc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 					dec_insn.next_pc_inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 			return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 		/* R2/R6 compatible cop1 instruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 	case cop2_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	case cop1x_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 		if (insn.i_format.rs == bc_op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 			preempt_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 			if (is_fpu_owner())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 			        fcr31 = read_32bit_cp1_register(CP1_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 				fcr31 = current->thread.fpu.fcr31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 			preempt_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 			bit = (insn.i_format.rt >> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 			bit += (bit != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 			bit += 23;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 			switch (insn.i_format.rt & 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 			case 0:	/* bc1f */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 			case 2:	/* bc1fl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 				if (~fcr31 & (1 << bit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 					*contpc = regs->cp0_epc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 						dec_insn.pc_inc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 						(insn.i_format.simmediate << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 				else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 					*contpc = regs->cp0_epc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 						dec_insn.pc_inc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 						dec_insn.next_pc_inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 				return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 			case 1:	/* bc1t */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 			case 3:	/* bc1tl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 				if (fcr31 & (1 << bit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 					*contpc = regs->cp0_epc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 						dec_insn.pc_inc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 						(insn.i_format.simmediate << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 				else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 					*contpc = regs->cp0_epc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 						dec_insn.pc_inc +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 						dec_insn.next_pc_inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 				return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773)  * In the Linux kernel, we support selection of FPR format on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774)  * basis of the Status.FR bit.	If an FPU is not present, the FR bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775)  * is hardwired to zero, which would imply a 32-bit FPU even for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776)  * 64-bit CPUs so we rather look at TIF_32BIT_FPREGS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777)  * FPU emu is slow and bulky and optimizing this function offers fairly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778)  * sizeable benefits so we try to be clever and make this function return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779)  * a constant whenever possible, that is on 64-bit kernels without O32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780)  * compatibility enabled and on 32-bit without 64-bit FPU support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) static inline int cop1_64bit(struct pt_regs *xcp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 	if (IS_ENABLED(CONFIG_64BIT) && !IS_ENABLED(CONFIG_MIPS32_O32))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	else if (IS_ENABLED(CONFIG_32BIT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 		 !IS_ENABLED(CONFIG_MIPS_O32_FP64_SUPPORT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	return !test_thread_flag(TIF_32BIT_FPREGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) static inline bool hybrid_fprs(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 	return test_thread_flag(TIF_HYBRID_FPREGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) #define SIFROMREG(si, x)						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) do {									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 	if (cop1_64bit(xcp) && !hybrid_fprs())				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 		(si) = (int)get_fpr32(&ctx->fpr[x], 0);			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 	else								\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 		(si) = (int)get_fpr32(&ctx->fpr[(x) & ~1], (x) & 1);	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) #define SITOREG(si, x)							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) do {									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 	if (cop1_64bit(xcp) && !hybrid_fprs()) {			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 		unsigned int i;						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 		set_fpr32(&ctx->fpr[x], 0, si);				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 		for (i = 1; i < ARRAY_SIZE(ctx->fpr[x].val32); i++)	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 			set_fpr32(&ctx->fpr[x], i, 0);			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 	} else {							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 		set_fpr32(&ctx->fpr[(x) & ~1], (x) & 1, si);		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 	}								\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) #define SIFROMHREG(si, x)	((si) = (int)get_fpr32(&ctx->fpr[x], 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) #define SITOHREG(si, x)							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) do {									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 	unsigned int i;							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 	set_fpr32(&ctx->fpr[x], 1, si);					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	for (i = 2; i < ARRAY_SIZE(ctx->fpr[x].val32); i++)		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 		set_fpr32(&ctx->fpr[x], i, 0);				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) #define DIFROMREG(di, x)						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 	((di) = get_fpr64(&ctx->fpr[(x) & ~(cop1_64bit(xcp) ^ 1)], 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) #define DITOREG(di, x)							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) do {									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	unsigned int fpr, i;						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 	fpr = (x) & ~(cop1_64bit(xcp) ^ 1);				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	set_fpr64(&ctx->fpr[fpr], 0, di);				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 	for (i = 1; i < ARRAY_SIZE(ctx->fpr[x].val64); i++)		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 		set_fpr64(&ctx->fpr[fpr], i, 0);			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) #define SPFROMREG(sp, x) SIFROMREG((sp).bits, x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) #define SPTOREG(sp, x)	SITOREG((sp).bits, x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) #define DPFROMREG(dp, x)	DIFROMREG((dp).bits, x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) #define DPTOREG(dp, x)	DITOREG((dp).bits, x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846)  * Emulate a CFC1 instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) static inline void cop1_cfc(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 			    mips_instruction ir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	u32 fcr31 = ctx->fcr31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	u32 value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	switch (MIPSInst_RD(ir)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	case FPCREG_CSR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 		value = fcr31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 		pr_debug("%p gpr[%d]<-csr=%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 			 (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 	case FPCREG_FENR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 		if (!cpu_has_mips_r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 		value = (fcr31 >> (FPU_CSR_FS_S - MIPS_FENR_FS_S)) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 			MIPS_FENR_FS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 		value |= fcr31 & (FPU_CSR_ALL_E | FPU_CSR_RM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 		pr_debug("%p gpr[%d]<-enr=%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 			 (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 	case FPCREG_FEXR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 		if (!cpu_has_mips_r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 		value = fcr31 & (FPU_CSR_ALL_X | FPU_CSR_ALL_S);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 		pr_debug("%p gpr[%d]<-exr=%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 			 (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 	case FPCREG_FCCR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 		if (!cpu_has_mips_r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 		value = (fcr31 >> (FPU_CSR_COND_S - MIPS_FCCR_COND0_S)) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 			MIPS_FCCR_COND0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 		value |= (fcr31 >> (FPU_CSR_COND1_S - MIPS_FCCR_COND1_S)) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 			 (MIPS_FCCR_CONDX & ~MIPS_FCCR_COND0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 		pr_debug("%p gpr[%d]<-ccr=%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 			 (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 	case FPCREG_RID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 		value = boot_cpu_data.fpu_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 	if (MIPSInst_RT(ir))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 		xcp->regs[MIPSInst_RT(ir)] = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903)  * Emulate a CTC1 instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) static inline void cop1_ctc(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 			    mips_instruction ir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 	u32 fcr31 = ctx->fcr31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	u32 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 	if (MIPSInst_RT(ir) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 		value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 		value = xcp->regs[MIPSInst_RT(ir)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 	switch (MIPSInst_RD(ir)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 	case FPCREG_CSR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 		pr_debug("%p gpr[%d]->csr=%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 			 (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 		/* Preserve read-only bits.  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 		mask = boot_cpu_data.fpu_msk31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 		fcr31 = (value & ~mask) | (fcr31 & mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	case FPCREG_FENR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 		if (!cpu_has_mips_r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 		pr_debug("%p gpr[%d]->enr=%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 			 (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 		fcr31 &= ~(FPU_CSR_FS | FPU_CSR_ALL_E | FPU_CSR_RM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 		fcr31 |= (value << (FPU_CSR_FS_S - MIPS_FENR_FS_S)) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 			 FPU_CSR_FS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 		fcr31 |= value & (FPU_CSR_ALL_E | FPU_CSR_RM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	case FPCREG_FEXR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 		if (!cpu_has_mips_r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 		pr_debug("%p gpr[%d]->exr=%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 			 (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 		fcr31 &= ~(FPU_CSR_ALL_X | FPU_CSR_ALL_S);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 		fcr31 |= value & (FPU_CSR_ALL_X | FPU_CSR_ALL_S);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	case FPCREG_FCCR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 		if (!cpu_has_mips_r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 		pr_debug("%p gpr[%d]->ccr=%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 			 (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 		fcr31 &= ~(FPU_CSR_CONDX | FPU_CSR_COND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 		fcr31 |= (value << (FPU_CSR_COND_S - MIPS_FCCR_COND0_S)) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 			 FPU_CSR_COND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 		fcr31 |= (value << (FPU_CSR_COND1_S - MIPS_FCCR_COND1_S)) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 			 FPU_CSR_CONDX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	ctx->fcr31 = fcr31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967)  * Emulate the single floating point instruction pointed at by EPC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968)  * Two instructions if the instruction is in a branch delay slot.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 		struct mm_decoded_insn dec_insn, void __user **fault_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 	unsigned long contpc = xcp->cp0_epc + dec_insn.pc_inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 	unsigned int cond, cbit, bit0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	mips_instruction ir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 	int likely, pc_inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	union fpureg *fpr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	u32 __user *wva;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	u64 __user *dva;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	u32 wval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	u64 dval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	int sig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	 * These are giving gcc a gentle hint about what to expect in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	 * dec_inst in order to do better optimization.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 	if (!cpu_has_mmips && dec_insn.micro_mips_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 		unreachable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	/* XXX NEC Vr54xx bug workaround */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 	if (delay_slot(xcp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 		if (dec_insn.micro_mips_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 			if (!mm_isBranchInstr(xcp, dec_insn, &contpc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 				clear_delay_slot(xcp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 			if (!isBranchInstr(xcp, dec_insn, &contpc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 				clear_delay_slot(xcp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 	if (delay_slot(xcp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 		 * The instruction to be emulated is in a branch delay slot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 		 * which means that we have to	emulate the branch instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 		 * BEFORE we do the cop1 instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 		 * This branch could be a COP1 branch, but in that case we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 		 * would have had a trap for that instruction, and would not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 		 * come through this route.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 		 * Linux MIPS branch emulator operates on context, updating the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 		 * cp0_epc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 		ir = dec_insn.next_insn;  /* process delay slot instr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 		pc_inc = dec_insn.next_pc_inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 		ir = dec_insn.insn;       /* process current instr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 		pc_inc = dec_insn.pc_inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 	 * Since microMIPS FPU instructios are a subset of MIPS32 FPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	 * instructions, we want to convert microMIPS FPU instructions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	 * into MIPS32 instructions so that we could reuse all of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 	 * FPU emulation code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 	 * NOTE: We cannot do this for branch instructions since they
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 	 *       are not a subset. Example: Cannot emulate a 16-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	 *       aligned target address with a MIPS32 instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	if (dec_insn.micro_mips_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 		 * If next instruction is a 16-bit instruction, then it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 		 * it cannot be a FPU instruction. This could happen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 		 * since we can be called for non-FPU instructions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 		if ((pc_inc == 2) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 			(microMIPS32_to_MIPS32((union mips_instruction *)&ir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 			 == SIGILL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 			return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) emul:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 	perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, xcp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 	MIPS_FPU_EMU_INC_STATS(emulated);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 	switch (MIPSInst_OPCODE(ir)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	case ldc1_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 		dva = (u64 __user *) (xcp->regs[MIPSInst_RS(ir)] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 				     MIPSInst_SIMM(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 		MIPS_FPU_EMU_INC_STATS(loads);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 		if (!access_ok(dva, sizeof(u64))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 			MIPS_FPU_EMU_INC_STATS(errors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 			*fault_addr = dva;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 			return SIGBUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 		if (__get_user(dval, dva)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 			MIPS_FPU_EMU_INC_STATS(errors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 			*fault_addr = dva;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 			return SIGSEGV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 		DITOREG(dval, MIPSInst_RT(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	case sdc1_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 		dva = (u64 __user *) (xcp->regs[MIPSInst_RS(ir)] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 				      MIPSInst_SIMM(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 		MIPS_FPU_EMU_INC_STATS(stores);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 		DIFROMREG(dval, MIPSInst_RT(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 		if (!access_ok(dva, sizeof(u64))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 			MIPS_FPU_EMU_INC_STATS(errors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 			*fault_addr = dva;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 			return SIGBUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 		if (__put_user(dval, dva)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 			MIPS_FPU_EMU_INC_STATS(errors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 			*fault_addr = dva;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 			return SIGSEGV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 	case lwc1_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 		wva = (u32 __user *) (xcp->regs[MIPSInst_RS(ir)] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 				      MIPSInst_SIMM(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 		MIPS_FPU_EMU_INC_STATS(loads);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 		if (!access_ok(wva, sizeof(u32))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 			MIPS_FPU_EMU_INC_STATS(errors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 			*fault_addr = wva;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 			return SIGBUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 		if (__get_user(wval, wva)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 			MIPS_FPU_EMU_INC_STATS(errors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 			*fault_addr = wva;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 			return SIGSEGV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 		SITOREG(wval, MIPSInst_RT(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 	case swc1_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 		wva = (u32 __user *) (xcp->regs[MIPSInst_RS(ir)] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 				      MIPSInst_SIMM(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 		MIPS_FPU_EMU_INC_STATS(stores);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 		SIFROMREG(wval, MIPSInst_RT(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 		if (!access_ok(wva, sizeof(u32))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 			MIPS_FPU_EMU_INC_STATS(errors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 			*fault_addr = wva;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 			return SIGBUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 		if (__put_user(wval, wva)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 			MIPS_FPU_EMU_INC_STATS(errors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 			*fault_addr = wva;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 			return SIGSEGV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	case cop1_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 		switch (MIPSInst_RS(ir)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 		case dmfc_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 			if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 			/* copregister fs -> gpr[rt] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 			if (MIPSInst_RT(ir) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 				DIFROMREG(xcp->regs[MIPSInst_RT(ir)],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 					MIPSInst_RD(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 		case dmtc_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 			if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 			/* copregister fs <- rt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 			DITOREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 		case mfhc_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 			if (!cpu_has_mips_r2_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 			/* copregister rd -> gpr[rt] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 			if (MIPSInst_RT(ir) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 				SIFROMHREG(xcp->regs[MIPSInst_RT(ir)],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 					MIPSInst_RD(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 		case mthc_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 			if (!cpu_has_mips_r2_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 			/* copregister rd <- gpr[rt] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 			SITOHREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 		case mfc_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 			/* copregister rd -> gpr[rt] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 			if (MIPSInst_RT(ir) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 				SIFROMREG(xcp->regs[MIPSInst_RT(ir)],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 					MIPSInst_RD(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 		case mtc_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 			/* copregister rd <- rt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 			SITOREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 		case cfc_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 			/* cop control register rd -> gpr[rt] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 			cop1_cfc(xcp, ctx, ir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 		case ctc_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 			/* copregister rd <- rt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 			cop1_ctc(xcp, ctx, ir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 			if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 				return SIGFPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 		case bc1eqz_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 		case bc1nez_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 			if (!cpu_has_mips_r6 || delay_slot(xcp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 			likely = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 			cond = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 			fpr = &current->thread.fpu.fpr[MIPSInst_RT(ir)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 			bit0 = get_fpr32(fpr, 0) & 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 			switch (MIPSInst_RS(ir)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 			case bc1eqz_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 				MIPS_FPU_EMU_INC_STATS(bc1eqz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 				cond = bit0 == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 			case bc1nez_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 				MIPS_FPU_EMU_INC_STATS(bc1nez);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 				cond = bit0 != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 			goto branch_common;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 		case bc_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 			if (delay_slot(xcp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 			if (cpu_has_mips_4_5_r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 				cbit = fpucondbit[MIPSInst_RT(ir) >> 2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 				cbit = FPU_CSR_COND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 			cond = ctx->fcr31 & cbit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 			likely = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 			switch (MIPSInst_RT(ir) & 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 			case bcfl_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 				if (cpu_has_mips_2_3_4_5_r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 					likely = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 				fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 			case bcf_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 				cond = !cond;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 			case bctl_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 				if (cpu_has_mips_2_3_4_5_r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 					likely = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 				fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 			case bct_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) branch_common:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 			MIPS_FPU_EMU_INC_STATS(branches);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 			set_delay_slot(xcp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 			if (cond) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 				 * Branch taken: emulate dslot instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 				unsigned long bcpc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 				 * Remember EPC at the branch to point back
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 				 * at so that any delay-slot instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 				 * signal is not silently ignored.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 				bcpc = xcp->cp0_epc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 				xcp->cp0_epc += dec_insn.pc_inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 				contpc = MIPSInst_SIMM(ir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 				ir = dec_insn.next_insn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 				if (dec_insn.micro_mips_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 					contpc = (xcp->cp0_epc + (contpc << 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 					/* If 16-bit instruction, not FPU. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 					if ((dec_insn.next_pc_inc == 2) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 						(microMIPS32_to_MIPS32((union mips_instruction *)&ir) == SIGILL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 						/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 						 * Since this instruction will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 						 * be put on the stack with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 						 * 32-bit words, get around
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 						 * this problem by putting a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 						 * NOP16 as the second one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 						 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 						if (dec_insn.next_pc_inc == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 							ir = (ir & (~0xffff)) | MM_NOP16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 						/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 						 * Single step the non-CP1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 						 * instruction in the dslot.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 						 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 						sig = mips_dsemul(xcp, ir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 								  bcpc, contpc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 						if (sig < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 							break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 						if (sig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 							xcp->cp0_epc = bcpc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 						/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 						 * SIGILL forces out of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 						 * the emulation loop.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 						 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 						return sig ? sig : SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 				} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 					contpc = (xcp->cp0_epc + (contpc << 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 				switch (MIPSInst_OPCODE(ir)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 				case lwc1_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 				case swc1_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 					goto emul;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 				case ldc1_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 				case sdc1_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 					if (cpu_has_mips_2_3_4_5_r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 						goto emul;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 					goto bc_sigill;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 				case cop1_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 					goto emul;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 				case cop1x_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 					if (cpu_has_mips_4_5_64_r2_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 						/* its one of ours */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 						goto emul;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 					goto bc_sigill;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 				case spec_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 					switch (MIPSInst_FUNC(ir)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 					case movc_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 						if (cpu_has_mips_4_5_r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 							goto emul;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 						goto bc_sigill;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 				bc_sigill:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 					xcp->cp0_epc = bcpc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 					return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 				 * Single step the non-cp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 				 * instruction in the dslot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 				sig = mips_dsemul(xcp, ir, bcpc, contpc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 				if (sig < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 				if (sig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 					xcp->cp0_epc = bcpc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 				/* SIGILL forces out of the emulation loop.  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 				return sig ? sig : SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 			} else if (likely) {	/* branch not taken */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 				 * branch likely nullifies
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 				 * dslot if not taken
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 				xcp->cp0_epc += dec_insn.pc_inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 				contpc += dec_insn.pc_inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 				 * else continue & execute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 				 * dslot as normal insn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 			if (!(MIPSInst_RS(ir) & 0x10))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 			/* a real fpu computation instruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 			sig = fpu_emu(xcp, ctx, ir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 			if (sig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 				return sig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 	case cop1x_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 		if (!cpu_has_mips_4_5_64_r2_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 			return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 		sig = fpux_emu(xcp, ctx, ir, fault_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 		if (sig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 			return sig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 	case spec_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 		if (!cpu_has_mips_4_5_r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 			return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 		if (MIPSInst_FUNC(ir) != movc_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 			return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 		cond = fpucondbit[MIPSInst_RT(ir) >> 2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 		if (((ctx->fcr31 & cond) != 0) == ((MIPSInst_RT(ir) & 1) != 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 			xcp->regs[MIPSInst_RD(ir)] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 				xcp->regs[MIPSInst_RS(ir)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 		return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 	/* we did it !! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 	xcp->cp0_epc = contpc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 	clear_delay_slot(xcp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391)  * Conversion table from MIPS compare ops 48-63
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392)  * cond = ieee754dp_cmp(x,y,IEEE754_UN,sig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) static const unsigned char cmptab[8] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 	0,			/* cmp_0 (sig) cmp_sf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 	IEEE754_CUN,		/* cmp_un (sig) cmp_ngle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 	IEEE754_CEQ,		/* cmp_eq (sig) cmp_seq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 	IEEE754_CEQ | IEEE754_CUN,	/* cmp_ueq (sig) cmp_ngl  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 	IEEE754_CLT,		/* cmp_olt (sig) cmp_lt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 	IEEE754_CLT | IEEE754_CUN,	/* cmp_ult (sig) cmp_nge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 	IEEE754_CLT | IEEE754_CEQ,	/* cmp_ole (sig) cmp_le */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 	IEEE754_CLT | IEEE754_CEQ | IEEE754_CUN,	/* cmp_ule (sig) cmp_ngt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) static const unsigned char negative_cmptab[8] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 	0, /* Reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 	IEEE754_CLT | IEEE754_CGT | IEEE754_CEQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 	IEEE754_CLT | IEEE754_CGT | IEEE754_CUN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 	IEEE754_CLT | IEEE754_CGT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 	/* Reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415)  * Additional MIPS4 instructions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) #define DEF3OP(name, p, f1, f2, f3)					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) static union ieee754##p fpemu_##p##_##name(union ieee754##p r,		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 	union ieee754##p s, union ieee754##p t)				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) {									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 	struct _ieee754_csr ieee754_csr_save;				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 	s = f1(s, t);							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 	ieee754_csr_save = ieee754_csr;					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 	s = f2(s, r);							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 	ieee754_csr_save.cx |= ieee754_csr.cx;				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 	ieee754_csr_save.sx |= ieee754_csr.sx;				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 	s = f3(s);							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 	ieee754_csr.cx |= ieee754_csr_save.cx;				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 	ieee754_csr.sx |= ieee754_csr_save.sx;				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 	return s;							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) static union ieee754dp fpemu_dp_recip(union ieee754dp d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 	return ieee754dp_div(ieee754dp_one(0), d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) static union ieee754dp fpemu_dp_rsqrt(union ieee754dp d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 	return ieee754dp_div(ieee754dp_one(0), ieee754dp_sqrt(d));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) static union ieee754sp fpemu_sp_recip(union ieee754sp s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 	return ieee754sp_div(ieee754sp_one(0), s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) static union ieee754sp fpemu_sp_rsqrt(union ieee754sp s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 	return ieee754sp_div(ieee754sp_one(0), ieee754sp_sqrt(s));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) DEF3OP(madd, sp, ieee754sp_mul, ieee754sp_add, );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) DEF3OP(msub, sp, ieee754sp_mul, ieee754sp_sub, );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) DEF3OP(nmadd, sp, ieee754sp_mul, ieee754sp_add, ieee754sp_neg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) DEF3OP(nmsub, sp, ieee754sp_mul, ieee754sp_sub, ieee754sp_neg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) DEF3OP(madd, dp, ieee754dp_mul, ieee754dp_add, );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) DEF3OP(msub, dp, ieee754dp_mul, ieee754dp_sub, );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) DEF3OP(nmadd, dp, ieee754dp_mul, ieee754dp_add, ieee754dp_neg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) DEF3OP(nmsub, dp, ieee754dp_mul, ieee754dp_sub, ieee754dp_neg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 	mips_instruction ir, void __user **fault_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 	unsigned int rcsr = 0;	/* resulting csr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 	MIPS_FPU_EMU_INC_STATS(cp1xops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 	switch (MIPSInst_FMA_FFMT(ir)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 	case s_fmt:{		/* 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 		union ieee754sp(*handler) (union ieee754sp, union ieee754sp, union ieee754sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 		union ieee754sp fd, fr, fs, ft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 		u32 __user *va;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 		u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 		switch (MIPSInst_FUNC(ir)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 		case lwxc1_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 			va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 				xcp->regs[MIPSInst_FT(ir)]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 			MIPS_FPU_EMU_INC_STATS(loads);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 			if (!access_ok(va, sizeof(u32))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 				MIPS_FPU_EMU_INC_STATS(errors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 				*fault_addr = va;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 				return SIGBUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 			if (__get_user(val, va)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 				MIPS_FPU_EMU_INC_STATS(errors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 				*fault_addr = va;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 				return SIGSEGV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 			SITOREG(val, MIPSInst_FD(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 		case swxc1_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 			va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 				xcp->regs[MIPSInst_FT(ir)]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 			MIPS_FPU_EMU_INC_STATS(stores);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 			SIFROMREG(val, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 			if (!access_ok(va, sizeof(u32))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 				MIPS_FPU_EMU_INC_STATS(errors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 				*fault_addr = va;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 				return SIGBUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 			if (put_user(val, va)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 				MIPS_FPU_EMU_INC_STATS(errors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 				*fault_addr = va;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 				return SIGSEGV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 		case madd_s_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 			if (cpu_has_mac2008_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 				handler = ieee754sp_madd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 				handler = fpemu_sp_madd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 			goto scoptop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 		case msub_s_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 			if (cpu_has_mac2008_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 				handler = ieee754sp_msub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 				handler = fpemu_sp_msub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 			goto scoptop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 		case nmadd_s_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 			if (cpu_has_mac2008_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 				handler = ieee754sp_nmadd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 				handler = fpemu_sp_nmadd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 			goto scoptop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 		case nmsub_s_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 			if (cpu_has_mac2008_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 				handler = ieee754sp_nmsub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 				handler = fpemu_sp_nmsub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 			goto scoptop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 		      scoptop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 			SPFROMREG(fr, MIPSInst_FR(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 			SPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 			SPFROMREG(ft, MIPSInst_FT(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 			fd = (*handler) (fr, fs, ft);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 			SPTOREG(fd, MIPSInst_FD(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 		      copcsr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 			if (ieee754_cxtest(IEEE754_INEXACT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) 				MIPS_FPU_EMU_INC_STATS(ieee754_inexact);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 				rcsr |= FPU_CSR_INE_X | FPU_CSR_INE_S;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 			if (ieee754_cxtest(IEEE754_UNDERFLOW)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 				MIPS_FPU_EMU_INC_STATS(ieee754_underflow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 				rcsr |= FPU_CSR_UDF_X | FPU_CSR_UDF_S;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 			if (ieee754_cxtest(IEEE754_OVERFLOW)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 				MIPS_FPU_EMU_INC_STATS(ieee754_overflow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 				rcsr |= FPU_CSR_OVF_X | FPU_CSR_OVF_S;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 			if (ieee754_cxtest(IEEE754_INVALID_OPERATION)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 				MIPS_FPU_EMU_INC_STATS(ieee754_invalidop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 				rcsr |= FPU_CSR_INV_X | FPU_CSR_INV_S;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 			ctx->fcr31 = (ctx->fcr31 & ~FPU_CSR_ALL_X) | rcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 			if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 				/*printk ("SIGFPE: FPU csr = %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 				   ctx->fcr31); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 				return SIGFPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 			return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 	case d_fmt:{		/* 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 		union ieee754dp(*handler) (union ieee754dp, union ieee754dp, union ieee754dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 		union ieee754dp fd, fr, fs, ft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 		u64 __user *va;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 		u64 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 		switch (MIPSInst_FUNC(ir)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 		case ldxc1_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 			va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 				xcp->regs[MIPSInst_FT(ir)]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 			MIPS_FPU_EMU_INC_STATS(loads);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 			if (!access_ok(va, sizeof(u64))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 				MIPS_FPU_EMU_INC_STATS(errors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 				*fault_addr = va;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 				return SIGBUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 			if (__get_user(val, va)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 				MIPS_FPU_EMU_INC_STATS(errors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 				*fault_addr = va;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 				return SIGSEGV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 			DITOREG(val, MIPSInst_FD(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 		case sdxc1_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 			va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 				xcp->regs[MIPSInst_FT(ir)]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 			MIPS_FPU_EMU_INC_STATS(stores);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 			DIFROMREG(val, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 			if (!access_ok(va, sizeof(u64))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 				MIPS_FPU_EMU_INC_STATS(errors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 				*fault_addr = va;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 				return SIGBUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 			if (__put_user(val, va)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 				MIPS_FPU_EMU_INC_STATS(errors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) 				*fault_addr = va;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) 				return SIGSEGV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) 		case madd_d_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 			if (cpu_has_mac2008_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) 				handler = ieee754dp_madd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) 				handler = fpemu_dp_madd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) 			goto dcoptop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) 		case msub_d_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 			if (cpu_has_mac2008_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 				handler = ieee754dp_msub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 				handler = fpemu_dp_msub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 			goto dcoptop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 		case nmadd_d_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 			if (cpu_has_mac2008_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 				handler = ieee754dp_nmadd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 				handler = fpemu_dp_nmadd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 			goto dcoptop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 		case nmsub_d_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 			if (cpu_has_mac2008_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 				handler = ieee754dp_nmsub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 			handler = fpemu_dp_nmsub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 			goto dcoptop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 		      dcoptop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) 			DPFROMREG(fr, MIPSInst_FR(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 			DPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) 			DPFROMREG(ft, MIPSInst_FT(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 			fd = (*handler) (fr, fs, ft);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) 			DPTOREG(fd, MIPSInst_FD(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 			goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 			return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 	case 0x3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) 		if (MIPSInst_FUNC(ir) != pfetch_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) 			return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 		/* ignore prefx operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 		return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680)  * Emulate a single COP1 arithmetic instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) 	mips_instruction ir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 	int rfmt;		/* resulting format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 	unsigned int rcsr = 0;	/* resulting csr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 	unsigned int oldrm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 	unsigned int cbit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) 	unsigned int cond;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 	union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) 		union ieee754dp d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 		union ieee754sp s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) 		int w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) 		s64 l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) 	} rv;			/* resulting value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) 	u64 bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) 	MIPS_FPU_EMU_INC_STATS(cp1ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) 	switch (rfmt = (MIPSInst_FFMT(ir) & 0xf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 	case s_fmt: {		/* 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) 		union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 			union ieee754sp(*b) (union ieee754sp, union ieee754sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 			union ieee754sp(*u) (union ieee754sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) 		} handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 		union ieee754sp fd, fs, ft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) 		switch (MIPSInst_FUNC(ir)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) 			/* binary ops */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 		case fadd_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) 			MIPS_FPU_EMU_INC_STATS(add_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) 			handler.b = ieee754sp_add;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 			goto scopbop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 		case fsub_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) 			MIPS_FPU_EMU_INC_STATS(sub_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 			handler.b = ieee754sp_sub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 			goto scopbop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 		case fmul_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) 			MIPS_FPU_EMU_INC_STATS(mul_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) 			handler.b = ieee754sp_mul;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) 			goto scopbop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) 		case fdiv_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) 			MIPS_FPU_EMU_INC_STATS(div_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 			handler.b = ieee754sp_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 			goto scopbop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 			/* unary  ops */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 		case fsqrt_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 			if (!cpu_has_mips_2_3_4_5_r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 			MIPS_FPU_EMU_INC_STATS(sqrt_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 			handler.u = ieee754sp_sqrt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 			goto scopuop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) 		 * Note that on some MIPS IV implementations such as the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 		 * R5000 and R8000 the FSQRT and FRECIP instructions do not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) 		 * achieve full IEEE-754 accuracy - however this emulator does.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 		case frsqrt_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 			if (!cpu_has_mips_4_5_64_r2_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) 			MIPS_FPU_EMU_INC_STATS(rsqrt_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) 			handler.u = fpemu_sp_rsqrt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 			goto scopuop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 		case frecip_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) 			if (!cpu_has_mips_4_5_64_r2_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 			MIPS_FPU_EMU_INC_STATS(recip_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 			handler.u = fpemu_sp_recip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 			goto scopuop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) 		case fmovc_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) 			if (!cpu_has_mips_4_5_r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 			cond = fpucondbit[MIPSInst_FT(ir) >> 2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) 			if (((ctx->fcr31 & cond) != 0) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) 				((MIPSInst_FT(ir) & 1) != 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 			SPFROMREG(rv.s, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) 		case fmovz_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 			if (!cpu_has_mips_4_5_r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 			if (xcp->regs[MIPSInst_FT(ir)] != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) 			SPFROMREG(rv.s, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) 		case fmovn_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) 			if (!cpu_has_mips_4_5_r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) 			if (xcp->regs[MIPSInst_FT(ir)] == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) 			SPFROMREG(rv.s, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) 		case fseleqz_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) 			if (!cpu_has_mips_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) 			MIPS_FPU_EMU_INC_STATS(seleqz_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) 			SPFROMREG(rv.s, MIPSInst_FT(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) 			if (rv.w & 0x1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) 				rv.w = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) 				SPFROMREG(rv.s, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) 		case fselnez_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) 			if (!cpu_has_mips_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) 			MIPS_FPU_EMU_INC_STATS(selnez_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) 			SPFROMREG(rv.s, MIPSInst_FT(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) 			if (rv.w & 0x1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) 				SPFROMREG(rv.s, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) 				rv.w = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) 		case fmaddf_op: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) 			union ieee754sp ft, fs, fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) 			if (!cpu_has_mips_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) 			MIPS_FPU_EMU_INC_STATS(maddf_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) 			SPFROMREG(ft, MIPSInst_FT(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) 			SPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) 			SPFROMREG(fd, MIPSInst_FD(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) 			rv.s = ieee754sp_maddf(fd, fs, ft);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) 			goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) 		case fmsubf_op: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) 			union ieee754sp ft, fs, fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) 			if (!cpu_has_mips_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) 			MIPS_FPU_EMU_INC_STATS(msubf_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) 			SPFROMREG(ft, MIPSInst_FT(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) 			SPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) 			SPFROMREG(fd, MIPSInst_FD(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) 			rv.s = ieee754sp_msubf(fd, fs, ft);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) 			goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) 		case frint_op: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) 			union ieee754sp fs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) 			if (!cpu_has_mips_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) 			MIPS_FPU_EMU_INC_STATS(rint_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) 			SPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) 			rv.s = ieee754sp_rint(fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) 			goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) 		case fclass_op: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) 			union ieee754sp fs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) 			if (!cpu_has_mips_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) 			MIPS_FPU_EMU_INC_STATS(class_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) 			SPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) 			rv.w = ieee754sp_2008class(fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) 			rfmt = w_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) 			goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) 		case fmin_op: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) 			union ieee754sp fs, ft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) 			if (!cpu_has_mips_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) 			MIPS_FPU_EMU_INC_STATS(min_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) 			SPFROMREG(ft, MIPSInst_FT(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) 			SPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) 			rv.s = ieee754sp_fmin(fs, ft);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) 			goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) 		case fmina_op: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) 			union ieee754sp fs, ft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) 			if (!cpu_has_mips_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) 			MIPS_FPU_EMU_INC_STATS(mina_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) 			SPFROMREG(ft, MIPSInst_FT(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) 			SPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) 			rv.s = ieee754sp_fmina(fs, ft);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) 			goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) 		case fmax_op: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) 			union ieee754sp fs, ft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) 			if (!cpu_has_mips_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) 			MIPS_FPU_EMU_INC_STATS(max_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) 			SPFROMREG(ft, MIPSInst_FT(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) 			SPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) 			rv.s = ieee754sp_fmax(fs, ft);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) 			goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) 		case fmaxa_op: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) 			union ieee754sp fs, ft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) 			if (!cpu_has_mips_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) 			MIPS_FPU_EMU_INC_STATS(maxa_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) 			SPFROMREG(ft, MIPSInst_FT(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) 			SPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) 			rv.s = ieee754sp_fmaxa(fs, ft);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) 			goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) 		case fabs_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) 			MIPS_FPU_EMU_INC_STATS(abs_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) 			handler.u = ieee754sp_abs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) 			goto scopuop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) 		case fneg_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) 			MIPS_FPU_EMU_INC_STATS(neg_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) 			handler.u = ieee754sp_neg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) 			goto scopuop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) 		case fmov_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) 			/* an easy one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) 			MIPS_FPU_EMU_INC_STATS(mov_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) 			SPFROMREG(rv.s, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) 			goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) 			/* binary op on handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) scopbop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) 			SPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) 			SPFROMREG(ft, MIPSInst_FT(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) 			rv.s = (*handler.b) (fs, ft);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) 			goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) scopuop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) 			SPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) 			rv.s = (*handler.u) (fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) 			goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) copcsr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) 			if (ieee754_cxtest(IEEE754_INEXACT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) 				MIPS_FPU_EMU_INC_STATS(ieee754_inexact);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) 				rcsr |= FPU_CSR_INE_X | FPU_CSR_INE_S;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) 			if (ieee754_cxtest(IEEE754_UNDERFLOW)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) 				MIPS_FPU_EMU_INC_STATS(ieee754_underflow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) 				rcsr |= FPU_CSR_UDF_X | FPU_CSR_UDF_S;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) 			if (ieee754_cxtest(IEEE754_OVERFLOW)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) 				MIPS_FPU_EMU_INC_STATS(ieee754_overflow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) 				rcsr |= FPU_CSR_OVF_X | FPU_CSR_OVF_S;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) 			if (ieee754_cxtest(IEEE754_ZERO_DIVIDE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) 				MIPS_FPU_EMU_INC_STATS(ieee754_zerodiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) 				rcsr |= FPU_CSR_DIV_X | FPU_CSR_DIV_S;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) 			if (ieee754_cxtest(IEEE754_INVALID_OPERATION)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) 				MIPS_FPU_EMU_INC_STATS(ieee754_invalidop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) 				rcsr |= FPU_CSR_INV_X | FPU_CSR_INV_S;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) 			/* unary conv ops */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) 		case fcvts_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) 			return SIGILL;	/* not defined */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) 		case fcvtd_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) 			MIPS_FPU_EMU_INC_STATS(cvt_d_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) 			SPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) 			rv.d = ieee754dp_fsp(fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) 			rfmt = d_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) 			goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) 		case fcvtw_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) 			MIPS_FPU_EMU_INC_STATS(cvt_w_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) 			SPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) 			rv.w = ieee754sp_tint(fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) 			rfmt = w_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) 			goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) 		case fround_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) 		case ftrunc_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) 		case fceil_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) 		case ffloor_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) 			if (!cpu_has_mips_2_3_4_5_r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) 			if (MIPSInst_FUNC(ir) == fceil_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) 				MIPS_FPU_EMU_INC_STATS(ceil_w_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) 			if (MIPSInst_FUNC(ir) == ffloor_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) 				MIPS_FPU_EMU_INC_STATS(floor_w_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) 			if (MIPSInst_FUNC(ir) == fround_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) 				MIPS_FPU_EMU_INC_STATS(round_w_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) 			if (MIPSInst_FUNC(ir) == ftrunc_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) 				MIPS_FPU_EMU_INC_STATS(trunc_w_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) 			oldrm = ieee754_csr.rm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) 			SPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) 			ieee754_csr.rm = MIPSInst_FUNC(ir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) 			rv.w = ieee754sp_tint(fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) 			ieee754_csr.rm = oldrm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) 			rfmt = w_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) 			goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) 		case fsel_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) 			if (!cpu_has_mips_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) 			MIPS_FPU_EMU_INC_STATS(sel_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) 			SPFROMREG(fd, MIPSInst_FD(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) 			if (fd.bits & 0x1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) 				SPFROMREG(rv.s, MIPSInst_FT(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) 				SPFROMREG(rv.s, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) 		case fcvtl_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) 			if (!cpu_has_mips_3_4_5_64_r2_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) 			MIPS_FPU_EMU_INC_STATS(cvt_l_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) 			SPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) 			rv.l = ieee754sp_tlong(fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) 			rfmt = l_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) 			goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) 		case froundl_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) 		case ftruncl_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) 		case fceill_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) 		case ffloorl_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) 			if (!cpu_has_mips_3_4_5_64_r2_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) 			if (MIPSInst_FUNC(ir) == fceill_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) 				MIPS_FPU_EMU_INC_STATS(ceil_l_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) 			if (MIPSInst_FUNC(ir) == ffloorl_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) 				MIPS_FPU_EMU_INC_STATS(floor_l_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) 			if (MIPSInst_FUNC(ir) == froundl_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) 				MIPS_FPU_EMU_INC_STATS(round_l_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) 			if (MIPSInst_FUNC(ir) == ftruncl_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) 				MIPS_FPU_EMU_INC_STATS(trunc_l_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) 			oldrm = ieee754_csr.rm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) 			SPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) 			ieee754_csr.rm = MIPSInst_FUNC(ir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) 			rv.l = ieee754sp_tlong(fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) 			ieee754_csr.rm = oldrm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) 			rfmt = l_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) 			goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) 			if (!NO_R6EMU && MIPSInst_FUNC(ir) >= fcmp_op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) 				unsigned int cmpop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) 				union ieee754sp fs, ft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) 				cmpop = MIPSInst_FUNC(ir) - fcmp_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) 				SPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) 				SPFROMREG(ft, MIPSInst_FT(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) 				rv.w = ieee754sp_cmp(fs, ft,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) 					cmptab[cmpop & 0x7], cmpop & 0x8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) 				rfmt = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) 				if ((cmpop & 0x8) && ieee754_cxtest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) 					(IEEE754_INVALID_OPERATION))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) 					rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) 				else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) 					goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) 			} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) 	case d_fmt: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) 		union ieee754dp fd, fs, ft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) 		union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) 			union ieee754dp(*b) (union ieee754dp, union ieee754dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) 			union ieee754dp(*u) (union ieee754dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) 		} handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) 		switch (MIPSInst_FUNC(ir)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) 			/* binary ops */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) 		case fadd_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) 			MIPS_FPU_EMU_INC_STATS(add_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) 			handler.b = ieee754dp_add;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) 			goto dcopbop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) 		case fsub_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) 			MIPS_FPU_EMU_INC_STATS(sub_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) 			handler.b = ieee754dp_sub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) 			goto dcopbop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) 		case fmul_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) 			MIPS_FPU_EMU_INC_STATS(mul_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) 			handler.b = ieee754dp_mul;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) 			goto dcopbop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) 		case fdiv_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) 			MIPS_FPU_EMU_INC_STATS(div_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) 			handler.b = ieee754dp_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) 			goto dcopbop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) 			/* unary  ops */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) 		case fsqrt_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) 			if (!cpu_has_mips_2_3_4_5_r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) 			MIPS_FPU_EMU_INC_STATS(sqrt_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) 			handler.u = ieee754dp_sqrt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) 			goto dcopuop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) 		 * Note that on some MIPS IV implementations such as the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) 		 * R5000 and R8000 the FSQRT and FRECIP instructions do not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) 		 * achieve full IEEE-754 accuracy - however this emulator does.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) 		case frsqrt_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) 			if (!cpu_has_mips_4_5_64_r2_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) 			MIPS_FPU_EMU_INC_STATS(rsqrt_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) 			handler.u = fpemu_dp_rsqrt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) 			goto dcopuop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) 		case frecip_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) 			if (!cpu_has_mips_4_5_64_r2_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) 			MIPS_FPU_EMU_INC_STATS(recip_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) 			handler.u = fpemu_dp_recip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) 			goto dcopuop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) 		case fmovc_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) 			if (!cpu_has_mips_4_5_r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) 			cond = fpucondbit[MIPSInst_FT(ir) >> 2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) 			if (((ctx->fcr31 & cond) != 0) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) 				((MIPSInst_FT(ir) & 1) != 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) 			DPFROMREG(rv.d, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) 		case fmovz_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) 			if (!cpu_has_mips_4_5_r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) 			if (xcp->regs[MIPSInst_FT(ir)] != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) 			DPFROMREG(rv.d, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) 		case fmovn_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) 			if (!cpu_has_mips_4_5_r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) 			if (xcp->regs[MIPSInst_FT(ir)] == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) 			DPFROMREG(rv.d, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) 		case fseleqz_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) 			if (!cpu_has_mips_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) 			MIPS_FPU_EMU_INC_STATS(seleqz_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) 			DPFROMREG(rv.d, MIPSInst_FT(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) 			if (rv.l & 0x1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) 				rv.l = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) 				DPFROMREG(rv.d, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) 		case fselnez_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) 			if (!cpu_has_mips_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) 			MIPS_FPU_EMU_INC_STATS(selnez_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) 			DPFROMREG(rv.d, MIPSInst_FT(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) 			if (rv.l & 0x1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) 				DPFROMREG(rv.d, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) 				rv.l = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) 		case fmaddf_op: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) 			union ieee754dp ft, fs, fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) 			if (!cpu_has_mips_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) 			MIPS_FPU_EMU_INC_STATS(maddf_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) 			DPFROMREG(ft, MIPSInst_FT(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) 			DPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) 			DPFROMREG(fd, MIPSInst_FD(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) 			rv.d = ieee754dp_maddf(fd, fs, ft);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) 			goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) 		case fmsubf_op: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) 			union ieee754dp ft, fs, fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) 			if (!cpu_has_mips_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) 			MIPS_FPU_EMU_INC_STATS(msubf_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) 			DPFROMREG(ft, MIPSInst_FT(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) 			DPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) 			DPFROMREG(fd, MIPSInst_FD(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) 			rv.d = ieee754dp_msubf(fd, fs, ft);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) 			goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) 		case frint_op: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) 			union ieee754dp fs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) 			if (!cpu_has_mips_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) 			MIPS_FPU_EMU_INC_STATS(rint_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) 			DPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) 			rv.d = ieee754dp_rint(fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) 			goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) 		case fclass_op: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) 			union ieee754dp fs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) 			if (!cpu_has_mips_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) 			MIPS_FPU_EMU_INC_STATS(class_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) 			DPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) 			rv.l = ieee754dp_2008class(fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) 			rfmt = l_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) 			goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) 		case fmin_op: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) 			union ieee754dp fs, ft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) 			if (!cpu_has_mips_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) 			MIPS_FPU_EMU_INC_STATS(min_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) 			DPFROMREG(ft, MIPSInst_FT(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) 			DPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) 			rv.d = ieee754dp_fmin(fs, ft);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) 			goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) 		case fmina_op: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) 			union ieee754dp fs, ft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) 			if (!cpu_has_mips_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) 			MIPS_FPU_EMU_INC_STATS(mina_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) 			DPFROMREG(ft, MIPSInst_FT(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) 			DPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) 			rv.d = ieee754dp_fmina(fs, ft);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) 			goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) 		case fmax_op: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) 			union ieee754dp fs, ft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) 			if (!cpu_has_mips_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) 			MIPS_FPU_EMU_INC_STATS(max_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) 			DPFROMREG(ft, MIPSInst_FT(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) 			DPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) 			rv.d = ieee754dp_fmax(fs, ft);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) 			goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) 		case fmaxa_op: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) 			union ieee754dp fs, ft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) 			if (!cpu_has_mips_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) 			MIPS_FPU_EMU_INC_STATS(maxa_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) 			DPFROMREG(ft, MIPSInst_FT(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) 			DPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) 			rv.d = ieee754dp_fmaxa(fs, ft);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) 			goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) 		case fabs_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) 			MIPS_FPU_EMU_INC_STATS(abs_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) 			handler.u = ieee754dp_abs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) 			goto dcopuop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) 		case fneg_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) 			MIPS_FPU_EMU_INC_STATS(neg_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) 			handler.u = ieee754dp_neg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) 			goto dcopuop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) 		case fmov_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) 			/* an easy one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) 			MIPS_FPU_EMU_INC_STATS(mov_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) 			DPFROMREG(rv.d, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) 			goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) 			/* binary op on handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) dcopbop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) 			DPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) 			DPFROMREG(ft, MIPSInst_FT(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) 			rv.d = (*handler.b) (fs, ft);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) 			goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) dcopuop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) 			DPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) 			rv.d = (*handler.u) (fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) 			goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) 		 * unary conv ops
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) 		case fcvts_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) 			MIPS_FPU_EMU_INC_STATS(cvt_s_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) 			DPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) 			rv.s = ieee754sp_fdp(fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) 			rfmt = s_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) 			goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) 		case fcvtd_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) 			return SIGILL;	/* not defined */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) 		case fcvtw_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) 			MIPS_FPU_EMU_INC_STATS(cvt_w_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) 			DPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) 			rv.w = ieee754dp_tint(fs);	/* wrong */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) 			rfmt = w_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) 			goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) 		case fround_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) 		case ftrunc_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) 		case fceil_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) 		case ffloor_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) 			if (!cpu_has_mips_2_3_4_5_r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) 			if (MIPSInst_FUNC(ir) == fceil_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) 				MIPS_FPU_EMU_INC_STATS(ceil_w_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) 			if (MIPSInst_FUNC(ir) == ffloor_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) 				MIPS_FPU_EMU_INC_STATS(floor_w_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) 			if (MIPSInst_FUNC(ir) == fround_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) 				MIPS_FPU_EMU_INC_STATS(round_w_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) 			if (MIPSInst_FUNC(ir) == ftrunc_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) 				MIPS_FPU_EMU_INC_STATS(trunc_w_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) 			oldrm = ieee754_csr.rm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) 			DPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) 			ieee754_csr.rm = MIPSInst_FUNC(ir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) 			rv.w = ieee754dp_tint(fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) 			ieee754_csr.rm = oldrm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) 			rfmt = w_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) 			goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) 		case fsel_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) 			if (!cpu_has_mips_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) 			MIPS_FPU_EMU_INC_STATS(sel_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) 			DPFROMREG(fd, MIPSInst_FD(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) 			if (fd.bits & 0x1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) 				DPFROMREG(rv.d, MIPSInst_FT(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) 				DPFROMREG(rv.d, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) 		case fcvtl_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) 			if (!cpu_has_mips_3_4_5_64_r2_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) 			MIPS_FPU_EMU_INC_STATS(cvt_l_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) 			DPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) 			rv.l = ieee754dp_tlong(fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) 			rfmt = l_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) 			goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) 		case froundl_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) 		case ftruncl_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) 		case fceill_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) 		case ffloorl_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) 			if (!cpu_has_mips_3_4_5_64_r2_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) 			if (MIPSInst_FUNC(ir) == fceill_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) 				MIPS_FPU_EMU_INC_STATS(ceil_l_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) 			if (MIPSInst_FUNC(ir) == ffloorl_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) 				MIPS_FPU_EMU_INC_STATS(floor_l_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) 			if (MIPSInst_FUNC(ir) == froundl_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) 				MIPS_FPU_EMU_INC_STATS(round_l_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) 			if (MIPSInst_FUNC(ir) == ftruncl_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) 				MIPS_FPU_EMU_INC_STATS(trunc_l_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) 			oldrm = ieee754_csr.rm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) 			DPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) 			ieee754_csr.rm = MIPSInst_FUNC(ir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) 			rv.l = ieee754dp_tlong(fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) 			ieee754_csr.rm = oldrm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) 			rfmt = l_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) 			goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) 			if (!NO_R6EMU && MIPSInst_FUNC(ir) >= fcmp_op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) 				unsigned int cmpop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) 				union ieee754dp fs, ft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) 				cmpop = MIPSInst_FUNC(ir) - fcmp_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) 				DPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) 				DPFROMREG(ft, MIPSInst_FT(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) 				rv.w = ieee754dp_cmp(fs, ft,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) 					cmptab[cmpop & 0x7], cmpop & 0x8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) 				rfmt = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) 				if ((cmpop & 0x8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) 					&&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) 					ieee754_cxtest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) 					(IEEE754_INVALID_OPERATION))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) 					rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) 				else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) 					goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) 			else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) 	case w_fmt: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) 		union ieee754dp fs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) 		switch (MIPSInst_FUNC(ir)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) 		case fcvts_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) 			/* convert word to single precision real */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) 			MIPS_FPU_EMU_INC_STATS(cvt_s_w);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) 			SPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) 			rv.s = ieee754sp_fint(fs.bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) 			rfmt = s_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) 			goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) 		case fcvtd_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) 			/* convert word to double precision real */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) 			MIPS_FPU_EMU_INC_STATS(cvt_d_w);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) 			SPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) 			rv.d = ieee754dp_fint(fs.bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) 			rfmt = d_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) 			goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) 		default: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) 			/* Emulating the new CMP.condn.fmt R6 instruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) #define CMPOP_MASK	0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) #define SIGN_BIT	(0x1 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) #define PREDICATE_BIT	(0x1 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) 			int cmpop = MIPSInst_FUNC(ir) & CMPOP_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) 			int sig = MIPSInst_FUNC(ir) & SIGN_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) 			union ieee754sp fs, ft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) 			/* This is an R6 only instruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) 			if (!cpu_has_mips_r6 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) 			    (MIPSInst_FUNC(ir) & 0x20))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) 			if (!sig) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) 				if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) 					switch (cmpop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) 					case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) 					MIPS_FPU_EMU_INC_STATS(cmp_af_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) 					case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) 					MIPS_FPU_EMU_INC_STATS(cmp_un_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) 					case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) 					MIPS_FPU_EMU_INC_STATS(cmp_eq_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) 					case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) 					MIPS_FPU_EMU_INC_STATS(cmp_ueq_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) 					case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) 					MIPS_FPU_EMU_INC_STATS(cmp_lt_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) 					case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) 					MIPS_FPU_EMU_INC_STATS(cmp_ult_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) 					case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) 					MIPS_FPU_EMU_INC_STATS(cmp_le_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) 					case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) 					MIPS_FPU_EMU_INC_STATS(cmp_ule_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) 				} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) 					switch (cmpop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) 					case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) 					MIPS_FPU_EMU_INC_STATS(cmp_or_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) 					case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) 					MIPS_FPU_EMU_INC_STATS(cmp_une_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) 					case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) 					MIPS_FPU_EMU_INC_STATS(cmp_ne_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) 				if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) 					switch (cmpop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) 					case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) 					MIPS_FPU_EMU_INC_STATS(cmp_saf_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) 					case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) 					MIPS_FPU_EMU_INC_STATS(cmp_sun_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) 					case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) 					MIPS_FPU_EMU_INC_STATS(cmp_seq_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) 					case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) 					MIPS_FPU_EMU_INC_STATS(cmp_sueq_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) 					case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) 					MIPS_FPU_EMU_INC_STATS(cmp_slt_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) 					case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) 					MIPS_FPU_EMU_INC_STATS(cmp_sult_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) 					case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) 					MIPS_FPU_EMU_INC_STATS(cmp_sle_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) 					case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) 					MIPS_FPU_EMU_INC_STATS(cmp_sule_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) 				} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) 					switch (cmpop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) 					case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) 					MIPS_FPU_EMU_INC_STATS(cmp_sor_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) 					case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) 					MIPS_FPU_EMU_INC_STATS(cmp_sune_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) 					case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) 					MIPS_FPU_EMU_INC_STATS(cmp_sne_s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) 			/* fmt is w_fmt for single precision so fix it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) 			rfmt = s_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) 			/* default to false */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) 			rv.w = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) 			/* CMP.condn.S */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) 			SPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) 			SPFROMREG(ft, MIPSInst_FT(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) 			/* positive predicates */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) 			if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) 				if (ieee754sp_cmp(fs, ft, cmptab[cmpop],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) 						  sig))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) 				    rv.w = -1; /* true, all 1s */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) 				if ((sig) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) 				    ieee754_cxtest(IEEE754_INVALID_OPERATION))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) 					rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) 				else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) 					goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) 				/* negative predicates */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) 				switch (cmpop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) 				case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) 				case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) 				case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) 					if (ieee754sp_cmp(fs, ft,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) 							  negative_cmptab[cmpop],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) 							  sig))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) 						rv.w = -1; /* true, all 1s */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) 					if (sig &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) 					    ieee754_cxtest(IEEE754_INVALID_OPERATION))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) 						rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) 					else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) 						goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) 				default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) 					/* Reserved R6 ops */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) 					return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) 	case l_fmt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) 		if (!cpu_has_mips_3_4_5_64_r2_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) 			return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) 		DIFROMREG(bits, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) 		switch (MIPSInst_FUNC(ir)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) 		case fcvts_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) 			/* convert long to single precision real */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) 			MIPS_FPU_EMU_INC_STATS(cvt_s_l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) 			rv.s = ieee754sp_flong(bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) 			rfmt = s_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) 			goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) 		case fcvtd_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) 			/* convert long to double precision real */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) 			MIPS_FPU_EMU_INC_STATS(cvt_d_l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) 			rv.d = ieee754dp_flong(bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) 			rfmt = d_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) 			goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) 		default: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) 			/* Emulating the new CMP.condn.fmt R6 instruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) 			int cmpop = MIPSInst_FUNC(ir) & CMPOP_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) 			int sig = MIPSInst_FUNC(ir) & SIGN_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) 			union ieee754dp fs, ft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) 			if (!cpu_has_mips_r6 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) 			    (MIPSInst_FUNC(ir) & 0x20))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) 				return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) 			if (!sig) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) 				if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) 					switch (cmpop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) 					case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) 					MIPS_FPU_EMU_INC_STATS(cmp_af_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) 					case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) 					MIPS_FPU_EMU_INC_STATS(cmp_un_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) 					case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) 					MIPS_FPU_EMU_INC_STATS(cmp_eq_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) 					case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) 					MIPS_FPU_EMU_INC_STATS(cmp_ueq_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) 					case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) 					MIPS_FPU_EMU_INC_STATS(cmp_lt_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) 					case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) 					MIPS_FPU_EMU_INC_STATS(cmp_ult_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) 					case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) 					MIPS_FPU_EMU_INC_STATS(cmp_le_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) 					case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) 					MIPS_FPU_EMU_INC_STATS(cmp_ule_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) 				} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) 					switch (cmpop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) 					case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) 					MIPS_FPU_EMU_INC_STATS(cmp_or_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) 					case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) 					MIPS_FPU_EMU_INC_STATS(cmp_une_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) 					case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) 					MIPS_FPU_EMU_INC_STATS(cmp_ne_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) 				if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) 					switch (cmpop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) 					case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) 					MIPS_FPU_EMU_INC_STATS(cmp_saf_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) 					case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) 					MIPS_FPU_EMU_INC_STATS(cmp_sun_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) 					case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) 					MIPS_FPU_EMU_INC_STATS(cmp_seq_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) 					case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) 					MIPS_FPU_EMU_INC_STATS(cmp_sueq_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) 					case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) 					MIPS_FPU_EMU_INC_STATS(cmp_slt_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) 					case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) 					MIPS_FPU_EMU_INC_STATS(cmp_sult_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) 					case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) 					MIPS_FPU_EMU_INC_STATS(cmp_sle_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) 					case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) 					MIPS_FPU_EMU_INC_STATS(cmp_sule_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) 				} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) 					switch (cmpop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) 					case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) 					MIPS_FPU_EMU_INC_STATS(cmp_sor_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) 					case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) 					MIPS_FPU_EMU_INC_STATS(cmp_sune_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) 					case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) 					MIPS_FPU_EMU_INC_STATS(cmp_sne_d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) 			/* fmt is l_fmt for double precision so fix it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) 			rfmt = d_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) 			/* default to false */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) 			rv.l = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) 			/* CMP.condn.D */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) 			DPFROMREG(fs, MIPSInst_FS(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) 			DPFROMREG(ft, MIPSInst_FT(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) 			/* positive predicates */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) 			if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) 				if (ieee754dp_cmp(fs, ft,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) 						  cmptab[cmpop], sig))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) 				    rv.l = -1LL; /* true, all 1s */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) 				if (sig &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) 				    ieee754_cxtest(IEEE754_INVALID_OPERATION))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) 					rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) 				else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) 					goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) 				/* negative predicates */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) 				switch (cmpop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) 				case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) 				case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) 				case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) 					if (ieee754dp_cmp(fs, ft,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) 							  negative_cmptab[cmpop],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) 							  sig))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) 						rv.l = -1LL; /* true, all 1s */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) 					if (sig &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) 					    ieee754_cxtest(IEEE754_INVALID_OPERATION))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) 						rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) 					else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) 						goto copcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) 				default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) 					/* Reserved R6 ops */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) 					return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) 		return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) 	 * Update the fpu CSR register for this operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) 	 * If an exception is required, generate a tidy SIGFPE exception,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) 	 * without updating the result register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) 	 * Note: cause exception bits do not accumulate, they are rewritten
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) 	 * for each op; only the flag/sticky bits accumulate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) 	ctx->fcr31 = (ctx->fcr31 & ~FPU_CSR_ALL_X) | rcsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) 	if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) 		/*printk ("SIGFPE: FPU csr = %08x\n",ctx->fcr31); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) 		return SIGFPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) 	 * Now we can safely write the result back to the register file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) 	switch (rfmt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) 	case -1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) 		if (cpu_has_mips_4_5_r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) 			cbit = fpucondbit[MIPSInst_FD(ir) >> 2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) 			cbit = FPU_CSR_COND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) 		if (rv.w)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) 			ctx->fcr31 |= cbit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) 			ctx->fcr31 &= ~cbit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) 	case d_fmt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) 		DPTOREG(rv.d, MIPSInst_FD(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) 	case s_fmt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) 		SPTOREG(rv.s, MIPSInst_FD(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) 	case w_fmt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) 		SITOREG(rv.w, MIPSInst_FD(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) 	case l_fmt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) 		if (!cpu_has_mips_3_4_5_64_r2_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) 			return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) 		DITOREG(rv.l, MIPSInst_FD(ir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) 		return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809)  * Emulate FPU instructions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811)  * If we use FPU hardware, then we have been typically called to handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812)  * an unimplemented operation, such as where an operand is a NaN or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813)  * denormalized.  In that case exit the emulation loop after a single
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814)  * iteration so as to let hardware execute any subsequent instructions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816)  * If we have no FPU hardware or it has been disabled, then continue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817)  * emulating floating-point instructions until one of these conditions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818)  * has occurred:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820)  * - a non-FPU instruction has been encountered,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822)  * - an attempt to emulate has ended with a signal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824)  * - the ISA mode has been switched.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826)  * We need to terminate the emulation loop if we got switched to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827)  * MIPS16 mode, whether supported or not, so that we do not attempt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828)  * to emulate a MIPS16 instruction as a regular MIPS FPU instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829)  * Similarly if we got switched to the microMIPS mode and only the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830)  * regular MIPS mode is supported, so that we do not attempt to emulate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831)  * a microMIPS instruction as a regular MIPS FPU instruction.  Or if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832)  * we got switched to the regular MIPS mode and only the microMIPS mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833)  * is supported, so that we do not attempt to emulate a regular MIPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834)  * instruction that should cause an Address Error exception instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835)  * For simplicity we always terminate upon an ISA mode switch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) 	int has_fpu, void __user **fault_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) 	unsigned long oldepc, prevepc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) 	struct mm_decoded_insn dec_insn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) 	u16 instr[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) 	u16 *instr_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) 	int sig = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) 	 * Initialize context if it hasn't been used already, otherwise ensure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) 	 * it has been saved to struct thread_struct.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) 	if (!init_fp_ctx(current))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) 		lose_fpu(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) 	oldepc = xcp->cp0_epc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) 		prevepc = xcp->cp0_epc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) 		if (get_isa16_mode(prevepc) && cpu_has_mmips) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) 			 * Get next 2 microMIPS instructions and convert them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) 			 * into 32-bit instructions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) 			if ((get_user(instr[0], (u16 __user *)msk_isa16_mode(xcp->cp0_epc))) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) 			    (get_user(instr[1], (u16 __user *)msk_isa16_mode(xcp->cp0_epc + 2))) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) 			    (get_user(instr[2], (u16 __user *)msk_isa16_mode(xcp->cp0_epc + 4))) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) 			    (get_user(instr[3], (u16 __user *)msk_isa16_mode(xcp->cp0_epc + 6)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) 				MIPS_FPU_EMU_INC_STATS(errors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) 				return SIGBUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) 			instr_ptr = instr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) 			/* Get first instruction. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) 			if (mm_insn_16bit(*instr_ptr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) 				/* Duplicate the half-word. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) 				dec_insn.insn = (*instr_ptr << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) 					(*instr_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) 				/* 16-bit instruction. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) 				dec_insn.pc_inc = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) 				instr_ptr += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) 				dec_insn.insn = (*instr_ptr << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) 					*(instr_ptr+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) 				/* 32-bit instruction. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) 				dec_insn.pc_inc = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) 				instr_ptr += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) 			/* Get second instruction. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) 			if (mm_insn_16bit(*instr_ptr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) 				/* Duplicate the half-word. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) 				dec_insn.next_insn = (*instr_ptr << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) 					(*instr_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) 				/* 16-bit instruction. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) 				dec_insn.next_pc_inc = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) 				dec_insn.next_insn = (*instr_ptr << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) 					*(instr_ptr+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) 				/* 32-bit instruction. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) 				dec_insn.next_pc_inc = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) 			dec_insn.micro_mips_mode = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) 			if ((get_user(dec_insn.insn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) 			    (mips_instruction __user *) xcp->cp0_epc)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) 			    (get_user(dec_insn.next_insn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) 			    (mips_instruction __user *)(xcp->cp0_epc+4)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) 				MIPS_FPU_EMU_INC_STATS(errors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) 				return SIGBUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) 			dec_insn.pc_inc = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) 			dec_insn.next_pc_inc = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) 			dec_insn.micro_mips_mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) 		if ((dec_insn.insn == 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) 		   ((dec_insn.pc_inc == 2) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) 		   ((dec_insn.insn & 0xffff) == MM_NOP16)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) 			xcp->cp0_epc += dec_insn.pc_inc;	/* Skip NOPs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) 			 * The 'ieee754_csr' is an alias of ctx->fcr31.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) 			 * No need to copy ctx->fcr31 to ieee754_csr.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) 			sig = cop1Emulate(xcp, ctx, dec_insn, fault_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) 		if (has_fpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) 		if (sig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) 		 * We have to check for the ISA bit explicitly here,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) 		 * because `get_isa16_mode' may return 0 if support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) 		 * for code compression has been globally disabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) 		 * or otherwise we may produce the wrong signal or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) 		 * even proceed successfully where we must not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) 		if ((xcp->cp0_epc ^ prevepc) & 0x1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) 		cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) 	} while (xcp->cp0_epc > prevepc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) 	/* SIGILL indicates a non-fpu instruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) 	if (sig == SIGILL && xcp->cp0_epc != oldepc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) 		/* but if EPC has advanced, then ignore it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) 		sig = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) 	return sig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) }