0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 #include <linux/sched.h>
0025 #include <linux/debugfs.h>
0026 #include <linux/percpu-defs.h>
0027 #include <linux/perf_event.h>
0028
0029 #include <asm/branch.h>
0030 #include <asm/inst.h>
0031 #include <asm/ptrace.h>
0032 #include <asm/signal.h>
0033 #include <linux/uaccess.h>
0034
0035 #include <asm/cpu-info.h>
0036 #include <asm/processor.h>
0037 #include <asm/fpu_emulator.h>
0038 #include <asm/fpu.h>
0039 #include <asm/mips-r2-to-r6-emul.h>
0040
0041 #include "ieee754.h"
0042
0043
0044
0045 static int fpu_emu(struct pt_regs *, struct mips_fpu_struct *,
0046 mips_instruction);
0047
0048 static int fpux_emu(struct pt_regs *,
0049 struct mips_fpu_struct *, mips_instruction, void __user **);
0050
0051
0052
0053 #define FPCREG_RID 0
0054 #define FPCREG_FCCR 25
0055 #define FPCREG_FEXR 26
0056 #define FPCREG_FENR 28
0057 #define FPCREG_CSR 31
0058
0059
0060 const unsigned int fpucondbit[8] = {
0061 FPU_CSR_COND,
0062 FPU_CSR_COND1,
0063 FPU_CSR_COND2,
0064 FPU_CSR_COND3,
0065 FPU_CSR_COND4,
0066 FPU_CSR_COND5,
0067 FPU_CSR_COND6,
0068 FPU_CSR_COND7
0069 };
0070
0071
0072 static const int sd_format[] = {16, 17, 0, 0, 0, 0, 0, 0};
0073 static const int sdps_format[] = {16, 17, 22, 0, 0, 0, 0, 0};
0074 static const int dwl_format[] = {17, 20, 21, 0, 0, 0, 0, 0};
0075 static const int swl_format[] = {16, 20, 21, 0, 0, 0, 0, 0};
0076
0077
0078
0079
0080
0081
0082 static int microMIPS32_to_MIPS32(union mips_instruction *insn_ptr)
0083 {
0084 union mips_instruction insn = *insn_ptr;
0085 union mips_instruction mips32_insn = insn;
0086 int func, fmt, op;
0087
0088 switch (insn.mm_i_format.opcode) {
0089 case mm_ldc132_op:
0090 mips32_insn.mm_i_format.opcode = ldc1_op;
0091 mips32_insn.mm_i_format.rt = insn.mm_i_format.rs;
0092 mips32_insn.mm_i_format.rs = insn.mm_i_format.rt;
0093 break;
0094 case mm_lwc132_op:
0095 mips32_insn.mm_i_format.opcode = lwc1_op;
0096 mips32_insn.mm_i_format.rt = insn.mm_i_format.rs;
0097 mips32_insn.mm_i_format.rs = insn.mm_i_format.rt;
0098 break;
0099 case mm_sdc132_op:
0100 mips32_insn.mm_i_format.opcode = sdc1_op;
0101 mips32_insn.mm_i_format.rt = insn.mm_i_format.rs;
0102 mips32_insn.mm_i_format.rs = insn.mm_i_format.rt;
0103 break;
0104 case mm_swc132_op:
0105 mips32_insn.mm_i_format.opcode = swc1_op;
0106 mips32_insn.mm_i_format.rt = insn.mm_i_format.rs;
0107 mips32_insn.mm_i_format.rs = insn.mm_i_format.rt;
0108 break;
0109 case mm_pool32i_op:
0110
0111 if ((insn.mm_i_format.rt == mm_bc1f_op) ||
0112 (insn.mm_i_format.rt == mm_bc1t_op)) {
0113 mips32_insn.fb_format.opcode = cop1_op;
0114 mips32_insn.fb_format.bc = bc_op;
0115 mips32_insn.fb_format.flag =
0116 (insn.mm_i_format.rt == mm_bc1t_op) ? 1 : 0;
0117 } else
0118 return SIGILL;
0119 break;
0120 case mm_pool32f_op:
0121 switch (insn.mm_fp0_format.func) {
0122 case mm_32f_01_op:
0123 case mm_32f_11_op:
0124 case mm_32f_02_op:
0125 case mm_32f_12_op:
0126 case mm_32f_41_op:
0127 case mm_32f_51_op:
0128 case mm_32f_42_op:
0129 case mm_32f_52_op:
0130 op = insn.mm_fp0_format.func;
0131 if (op == mm_32f_01_op)
0132 func = madd_s_op;
0133 else if (op == mm_32f_11_op)
0134 func = madd_d_op;
0135 else if (op == mm_32f_02_op)
0136 func = nmadd_s_op;
0137 else if (op == mm_32f_12_op)
0138 func = nmadd_d_op;
0139 else if (op == mm_32f_41_op)
0140 func = msub_s_op;
0141 else if (op == mm_32f_51_op)
0142 func = msub_d_op;
0143 else if (op == mm_32f_42_op)
0144 func = nmsub_s_op;
0145 else
0146 func = nmsub_d_op;
0147 mips32_insn.fp6_format.opcode = cop1x_op;
0148 mips32_insn.fp6_format.fr = insn.mm_fp6_format.fr;
0149 mips32_insn.fp6_format.ft = insn.mm_fp6_format.ft;
0150 mips32_insn.fp6_format.fs = insn.mm_fp6_format.fs;
0151 mips32_insn.fp6_format.fd = insn.mm_fp6_format.fd;
0152 mips32_insn.fp6_format.func = func;
0153 break;
0154 case mm_32f_10_op:
0155 func = -1;
0156 op = insn.mm_fp5_format.op & 0x7;
0157 if (op == mm_ldxc1_op)
0158 func = ldxc1_op;
0159 else if (op == mm_sdxc1_op)
0160 func = sdxc1_op;
0161 else if (op == mm_lwxc1_op)
0162 func = lwxc1_op;
0163 else if (op == mm_swxc1_op)
0164 func = swxc1_op;
0165
0166 if (func != -1) {
0167 mips32_insn.r_format.opcode = cop1x_op;
0168 mips32_insn.r_format.rs =
0169 insn.mm_fp5_format.base;
0170 mips32_insn.r_format.rt =
0171 insn.mm_fp5_format.index;
0172 mips32_insn.r_format.rd = 0;
0173 mips32_insn.r_format.re = insn.mm_fp5_format.fd;
0174 mips32_insn.r_format.func = func;
0175 } else
0176 return SIGILL;
0177 break;
0178 case mm_32f_40_op:
0179 op = -1;
0180 if (insn.mm_fp2_format.op == mm_fmovt_op)
0181 op = 1;
0182 else if (insn.mm_fp2_format.op == mm_fmovf_op)
0183 op = 0;
0184 if (op != -1) {
0185 mips32_insn.fp0_format.opcode = cop1_op;
0186 mips32_insn.fp0_format.fmt =
0187 sdps_format[insn.mm_fp2_format.fmt];
0188 mips32_insn.fp0_format.ft =
0189 (insn.mm_fp2_format.cc<<2) + op;
0190 mips32_insn.fp0_format.fs =
0191 insn.mm_fp2_format.fs;
0192 mips32_insn.fp0_format.fd =
0193 insn.mm_fp2_format.fd;
0194 mips32_insn.fp0_format.func = fmovc_op;
0195 } else
0196 return SIGILL;
0197 break;
0198 case mm_32f_60_op:
0199 func = -1;
0200 if (insn.mm_fp0_format.op == mm_fadd_op)
0201 func = fadd_op;
0202 else if (insn.mm_fp0_format.op == mm_fsub_op)
0203 func = fsub_op;
0204 else if (insn.mm_fp0_format.op == mm_fmul_op)
0205 func = fmul_op;
0206 else if (insn.mm_fp0_format.op == mm_fdiv_op)
0207 func = fdiv_op;
0208 if (func != -1) {
0209 mips32_insn.fp0_format.opcode = cop1_op;
0210 mips32_insn.fp0_format.fmt =
0211 sdps_format[insn.mm_fp0_format.fmt];
0212 mips32_insn.fp0_format.ft =
0213 insn.mm_fp0_format.ft;
0214 mips32_insn.fp0_format.fs =
0215 insn.mm_fp0_format.fs;
0216 mips32_insn.fp0_format.fd =
0217 insn.mm_fp0_format.fd;
0218 mips32_insn.fp0_format.func = func;
0219 } else
0220 return SIGILL;
0221 break;
0222 case mm_32f_70_op:
0223 func = -1;
0224 if (insn.mm_fp0_format.op == mm_fmovn_op)
0225 func = fmovn_op;
0226 else if (insn.mm_fp0_format.op == mm_fmovz_op)
0227 func = fmovz_op;
0228 if (func != -1) {
0229 mips32_insn.fp0_format.opcode = cop1_op;
0230 mips32_insn.fp0_format.fmt =
0231 sdps_format[insn.mm_fp0_format.fmt];
0232 mips32_insn.fp0_format.ft =
0233 insn.mm_fp0_format.ft;
0234 mips32_insn.fp0_format.fs =
0235 insn.mm_fp0_format.fs;
0236 mips32_insn.fp0_format.fd =
0237 insn.mm_fp0_format.fd;
0238 mips32_insn.fp0_format.func = func;
0239 } else
0240 return SIGILL;
0241 break;
0242 case mm_32f_73_op:
0243 switch (insn.mm_fp1_format.op) {
0244 case mm_movf0_op:
0245 case mm_movf1_op:
0246 case mm_movt0_op:
0247 case mm_movt1_op:
0248 if ((insn.mm_fp1_format.op & 0x7f) ==
0249 mm_movf0_op)
0250 op = 0;
0251 else
0252 op = 1;
0253 mips32_insn.r_format.opcode = spec_op;
0254 mips32_insn.r_format.rs = insn.mm_fp4_format.fs;
0255 mips32_insn.r_format.rt =
0256 (insn.mm_fp4_format.cc << 2) + op;
0257 mips32_insn.r_format.rd = insn.mm_fp4_format.rt;
0258 mips32_insn.r_format.re = 0;
0259 mips32_insn.r_format.func = movc_op;
0260 break;
0261 case mm_fcvtd0_op:
0262 case mm_fcvtd1_op:
0263 case mm_fcvts0_op:
0264 case mm_fcvts1_op:
0265 if ((insn.mm_fp1_format.op & 0x7f) ==
0266 mm_fcvtd0_op) {
0267 func = fcvtd_op;
0268 fmt = swl_format[insn.mm_fp3_format.fmt];
0269 } else {
0270 func = fcvts_op;
0271 fmt = dwl_format[insn.mm_fp3_format.fmt];
0272 }
0273 mips32_insn.fp0_format.opcode = cop1_op;
0274 mips32_insn.fp0_format.fmt = fmt;
0275 mips32_insn.fp0_format.ft = 0;
0276 mips32_insn.fp0_format.fs =
0277 insn.mm_fp3_format.fs;
0278 mips32_insn.fp0_format.fd =
0279 insn.mm_fp3_format.rt;
0280 mips32_insn.fp0_format.func = func;
0281 break;
0282 case mm_fmov0_op:
0283 case mm_fmov1_op:
0284 case mm_fabs0_op:
0285 case mm_fabs1_op:
0286 case mm_fneg0_op:
0287 case mm_fneg1_op:
0288 if ((insn.mm_fp1_format.op & 0x7f) ==
0289 mm_fmov0_op)
0290 func = fmov_op;
0291 else if ((insn.mm_fp1_format.op & 0x7f) ==
0292 mm_fabs0_op)
0293 func = fabs_op;
0294 else
0295 func = fneg_op;
0296 mips32_insn.fp0_format.opcode = cop1_op;
0297 mips32_insn.fp0_format.fmt =
0298 sdps_format[insn.mm_fp3_format.fmt];
0299 mips32_insn.fp0_format.ft = 0;
0300 mips32_insn.fp0_format.fs =
0301 insn.mm_fp3_format.fs;
0302 mips32_insn.fp0_format.fd =
0303 insn.mm_fp3_format.rt;
0304 mips32_insn.fp0_format.func = func;
0305 break;
0306 case mm_ffloorl_op:
0307 case mm_ffloorw_op:
0308 case mm_fceill_op:
0309 case mm_fceilw_op:
0310 case mm_ftruncl_op:
0311 case mm_ftruncw_op:
0312 case mm_froundl_op:
0313 case mm_froundw_op:
0314 case mm_fcvtl_op:
0315 case mm_fcvtw_op:
0316 if (insn.mm_fp1_format.op == mm_ffloorl_op)
0317 func = ffloorl_op;
0318 else if (insn.mm_fp1_format.op == mm_ffloorw_op)
0319 func = ffloor_op;
0320 else if (insn.mm_fp1_format.op == mm_fceill_op)
0321 func = fceill_op;
0322 else if (insn.mm_fp1_format.op == mm_fceilw_op)
0323 func = fceil_op;
0324 else if (insn.mm_fp1_format.op == mm_ftruncl_op)
0325 func = ftruncl_op;
0326 else if (insn.mm_fp1_format.op == mm_ftruncw_op)
0327 func = ftrunc_op;
0328 else if (insn.mm_fp1_format.op == mm_froundl_op)
0329 func = froundl_op;
0330 else if (insn.mm_fp1_format.op == mm_froundw_op)
0331 func = fround_op;
0332 else if (insn.mm_fp1_format.op == mm_fcvtl_op)
0333 func = fcvtl_op;
0334 else
0335 func = fcvtw_op;
0336 mips32_insn.fp0_format.opcode = cop1_op;
0337 mips32_insn.fp0_format.fmt =
0338 sd_format[insn.mm_fp1_format.fmt];
0339 mips32_insn.fp0_format.ft = 0;
0340 mips32_insn.fp0_format.fs =
0341 insn.mm_fp1_format.fs;
0342 mips32_insn.fp0_format.fd =
0343 insn.mm_fp1_format.rt;
0344 mips32_insn.fp0_format.func = func;
0345 break;
0346 case mm_frsqrt_op:
0347 case mm_fsqrt_op:
0348 case mm_frecip_op:
0349 if (insn.mm_fp1_format.op == mm_frsqrt_op)
0350 func = frsqrt_op;
0351 else if (insn.mm_fp1_format.op == mm_fsqrt_op)
0352 func = fsqrt_op;
0353 else
0354 func = frecip_op;
0355 mips32_insn.fp0_format.opcode = cop1_op;
0356 mips32_insn.fp0_format.fmt =
0357 sdps_format[insn.mm_fp1_format.fmt];
0358 mips32_insn.fp0_format.ft = 0;
0359 mips32_insn.fp0_format.fs =
0360 insn.mm_fp1_format.fs;
0361 mips32_insn.fp0_format.fd =
0362 insn.mm_fp1_format.rt;
0363 mips32_insn.fp0_format.func = func;
0364 break;
0365 case mm_mfc1_op:
0366 case mm_mtc1_op:
0367 case mm_cfc1_op:
0368 case mm_ctc1_op:
0369 case mm_mfhc1_op:
0370 case mm_mthc1_op:
0371 if (insn.mm_fp1_format.op == mm_mfc1_op)
0372 op = mfc_op;
0373 else if (insn.mm_fp1_format.op == mm_mtc1_op)
0374 op = mtc_op;
0375 else if (insn.mm_fp1_format.op == mm_cfc1_op)
0376 op = cfc_op;
0377 else if (insn.mm_fp1_format.op == mm_ctc1_op)
0378 op = ctc_op;
0379 else if (insn.mm_fp1_format.op == mm_mfhc1_op)
0380 op = mfhc_op;
0381 else
0382 op = mthc_op;
0383 mips32_insn.fp1_format.opcode = cop1_op;
0384 mips32_insn.fp1_format.op = op;
0385 mips32_insn.fp1_format.rt =
0386 insn.mm_fp1_format.rt;
0387 mips32_insn.fp1_format.fs =
0388 insn.mm_fp1_format.fs;
0389 mips32_insn.fp1_format.fd = 0;
0390 mips32_insn.fp1_format.func = 0;
0391 break;
0392 default:
0393 return SIGILL;
0394 }
0395 break;
0396 case mm_32f_74_op:
0397 mips32_insn.fp0_format.opcode = cop1_op;
0398 mips32_insn.fp0_format.fmt =
0399 sdps_format[insn.mm_fp4_format.fmt];
0400 mips32_insn.fp0_format.ft = insn.mm_fp4_format.rt;
0401 mips32_insn.fp0_format.fs = insn.mm_fp4_format.fs;
0402 mips32_insn.fp0_format.fd = insn.mm_fp4_format.cc << 2;
0403 mips32_insn.fp0_format.func =
0404 insn.mm_fp4_format.cond | MM_MIPS32_COND_FC;
0405 break;
0406 default:
0407 return SIGILL;
0408 }
0409 break;
0410 default:
0411 return SIGILL;
0412 }
0413
0414 *insn_ptr = mips32_insn;
0415 return 0;
0416 }
0417
0418
0419
0420
0421
0422
0423
0424 int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
0425 unsigned long *contpc)
0426 {
0427 union mips_instruction insn = (union mips_instruction)dec_insn.insn;
0428 unsigned int fcr31;
0429 unsigned int bit = 0;
0430 unsigned int bit0;
0431 union fpureg *fpr;
0432
0433 switch (insn.i_format.opcode) {
0434 case spec_op:
0435 switch (insn.r_format.func) {
0436 case jalr_op:
0437 if (insn.r_format.rd != 0) {
0438 regs->regs[insn.r_format.rd] =
0439 regs->cp0_epc + dec_insn.pc_inc +
0440 dec_insn.next_pc_inc;
0441 }
0442 fallthrough;
0443 case jr_op:
0444
0445 if (NO_R6EMU && insn.r_format.func == jr_op)
0446 break;
0447 *contpc = regs->regs[insn.r_format.rs];
0448 return 1;
0449 }
0450 break;
0451 case bcond_op:
0452 switch (insn.i_format.rt) {
0453 case bltzal_op:
0454 case bltzall_op:
0455 if (NO_R6EMU && (insn.i_format.rs ||
0456 insn.i_format.rt == bltzall_op))
0457 break;
0458
0459 regs->regs[31] = regs->cp0_epc +
0460 dec_insn.pc_inc +
0461 dec_insn.next_pc_inc;
0462 fallthrough;
0463 case bltzl_op:
0464 if (NO_R6EMU)
0465 break;
0466 fallthrough;
0467 case bltz_op:
0468 if ((long)regs->regs[insn.i_format.rs] < 0)
0469 *contpc = regs->cp0_epc +
0470 dec_insn.pc_inc +
0471 (insn.i_format.simmediate << 2);
0472 else
0473 *contpc = regs->cp0_epc +
0474 dec_insn.pc_inc +
0475 dec_insn.next_pc_inc;
0476 return 1;
0477 case bgezal_op:
0478 case bgezall_op:
0479 if (NO_R6EMU && (insn.i_format.rs ||
0480 insn.i_format.rt == bgezall_op))
0481 break;
0482
0483 regs->regs[31] = regs->cp0_epc +
0484 dec_insn.pc_inc +
0485 dec_insn.next_pc_inc;
0486 fallthrough;
0487 case bgezl_op:
0488 if (NO_R6EMU)
0489 break;
0490 fallthrough;
0491 case bgez_op:
0492 if ((long)regs->regs[insn.i_format.rs] >= 0)
0493 *contpc = regs->cp0_epc +
0494 dec_insn.pc_inc +
0495 (insn.i_format.simmediate << 2);
0496 else
0497 *contpc = regs->cp0_epc +
0498 dec_insn.pc_inc +
0499 dec_insn.next_pc_inc;
0500 return 1;
0501 }
0502 break;
0503 case jalx_op:
0504 set_isa16_mode(bit);
0505 fallthrough;
0506 case jal_op:
0507 regs->regs[31] = regs->cp0_epc +
0508 dec_insn.pc_inc +
0509 dec_insn.next_pc_inc;
0510 fallthrough;
0511 case j_op:
0512 *contpc = regs->cp0_epc + dec_insn.pc_inc;
0513 *contpc >>= 28;
0514 *contpc <<= 28;
0515 *contpc |= (insn.j_format.target << 2);
0516
0517 *contpc ^= bit;
0518 return 1;
0519 case beql_op:
0520 if (NO_R6EMU)
0521 break;
0522 fallthrough;
0523 case beq_op:
0524 if (regs->regs[insn.i_format.rs] ==
0525 regs->regs[insn.i_format.rt])
0526 *contpc = regs->cp0_epc +
0527 dec_insn.pc_inc +
0528 (insn.i_format.simmediate << 2);
0529 else
0530 *contpc = regs->cp0_epc +
0531 dec_insn.pc_inc +
0532 dec_insn.next_pc_inc;
0533 return 1;
0534 case bnel_op:
0535 if (NO_R6EMU)
0536 break;
0537 fallthrough;
0538 case bne_op:
0539 if (regs->regs[insn.i_format.rs] !=
0540 regs->regs[insn.i_format.rt])
0541 *contpc = regs->cp0_epc +
0542 dec_insn.pc_inc +
0543 (insn.i_format.simmediate << 2);
0544 else
0545 *contpc = regs->cp0_epc +
0546 dec_insn.pc_inc +
0547 dec_insn.next_pc_inc;
0548 return 1;
0549 case blezl_op:
0550 if (!insn.i_format.rt && NO_R6EMU)
0551 break;
0552 fallthrough;
0553 case blez_op:
0554
0555
0556
0557
0558
0559
0560
0561
0562
0563
0564
0565
0566
0567 if (cpu_has_mips_r6 && insn.i_format.rt) {
0568 if ((insn.i_format.opcode == blez_op) &&
0569 ((!insn.i_format.rs && insn.i_format.rt) ||
0570 (insn.i_format.rs == insn.i_format.rt)))
0571 regs->regs[31] = regs->cp0_epc +
0572 dec_insn.pc_inc;
0573 *contpc = regs->cp0_epc + dec_insn.pc_inc +
0574 dec_insn.next_pc_inc;
0575
0576 return 1;
0577 }
0578 if ((long)regs->regs[insn.i_format.rs] <= 0)
0579 *contpc = regs->cp0_epc +
0580 dec_insn.pc_inc +
0581 (insn.i_format.simmediate << 2);
0582 else
0583 *contpc = regs->cp0_epc +
0584 dec_insn.pc_inc +
0585 dec_insn.next_pc_inc;
0586 return 1;
0587 case bgtzl_op:
0588 if (!insn.i_format.rt && NO_R6EMU)
0589 break;
0590 fallthrough;
0591 case bgtz_op:
0592
0593
0594
0595
0596
0597
0598
0599
0600
0601
0602
0603
0604
0605 if (cpu_has_mips_r6 && insn.i_format.rt) {
0606 if ((insn.i_format.opcode == blez_op) &&
0607 ((!insn.i_format.rs && insn.i_format.rt) ||
0608 (insn.i_format.rs == insn.i_format.rt)))
0609 regs->regs[31] = regs->cp0_epc +
0610 dec_insn.pc_inc;
0611 *contpc = regs->cp0_epc + dec_insn.pc_inc +
0612 dec_insn.next_pc_inc;
0613
0614 return 1;
0615 }
0616
0617 if ((long)regs->regs[insn.i_format.rs] > 0)
0618 *contpc = regs->cp0_epc +
0619 dec_insn.pc_inc +
0620 (insn.i_format.simmediate << 2);
0621 else
0622 *contpc = regs->cp0_epc +
0623 dec_insn.pc_inc +
0624 dec_insn.next_pc_inc;
0625 return 1;
0626 case pop10_op:
0627 case pop30_op:
0628 if (!cpu_has_mips_r6)
0629 break;
0630 if (insn.i_format.rt && !insn.i_format.rs)
0631 regs->regs[31] = regs->cp0_epc + 4;
0632 *contpc = regs->cp0_epc + dec_insn.pc_inc +
0633 dec_insn.next_pc_inc;
0634
0635 return 1;
0636 #ifdef CONFIG_CPU_CAVIUM_OCTEON
0637 case lwc2_op:
0638 if ((regs->regs[insn.i_format.rs] & (1ull<<insn.i_format.rt)) == 0)
0639 *contpc = regs->cp0_epc + 4 + (insn.i_format.simmediate << 2);
0640 else
0641 *contpc = regs->cp0_epc + 8;
0642 return 1;
0643 case ldc2_op:
0644 if ((regs->regs[insn.i_format.rs] & (1ull<<(insn.i_format.rt + 32))) == 0)
0645 *contpc = regs->cp0_epc + 4 + (insn.i_format.simmediate << 2);
0646 else
0647 *contpc = regs->cp0_epc + 8;
0648 return 1;
0649 case swc2_op:
0650 if (regs->regs[insn.i_format.rs] & (1ull<<insn.i_format.rt))
0651 *contpc = regs->cp0_epc + 4 + (insn.i_format.simmediate << 2);
0652 else
0653 *contpc = regs->cp0_epc + 8;
0654 return 1;
0655 case sdc2_op:
0656 if (regs->regs[insn.i_format.rs] & (1ull<<(insn.i_format.rt + 32)))
0657 *contpc = regs->cp0_epc + 4 + (insn.i_format.simmediate << 2);
0658 else
0659 *contpc = regs->cp0_epc + 8;
0660 return 1;
0661 #else
0662 case bc6_op:
0663
0664
0665
0666
0667
0668 if (!cpu_has_mips_r6)
0669 break;
0670 *contpc = regs->cp0_epc + dec_insn.pc_inc +
0671 dec_insn.next_pc_inc;
0672
0673 return 1;
0674 case balc6_op:
0675 if (!cpu_has_mips_r6)
0676 break;
0677 regs->regs[31] = regs->cp0_epc + 4;
0678 *contpc = regs->cp0_epc + dec_insn.pc_inc +
0679 dec_insn.next_pc_inc;
0680
0681 return 1;
0682 case pop66_op:
0683 if (!cpu_has_mips_r6)
0684 break;
0685 *contpc = regs->cp0_epc + dec_insn.pc_inc +
0686 dec_insn.next_pc_inc;
0687
0688 return 1;
0689 case pop76_op:
0690 if (!cpu_has_mips_r6)
0691 break;
0692 if (!insn.i_format.rs)
0693 regs->regs[31] = regs->cp0_epc + 4;
0694 *contpc = regs->cp0_epc + dec_insn.pc_inc +
0695 dec_insn.next_pc_inc;
0696
0697 return 1;
0698 #endif
0699 case cop0_op:
0700 case cop1_op:
0701
0702 if (cpu_has_mips_r6 &&
0703 ((insn.i_format.rs == bc1eqz_op) ||
0704 (insn.i_format.rs == bc1nez_op))) {
0705 bit = 0;
0706 fpr = ¤t->thread.fpu.fpr[insn.i_format.rt];
0707 bit0 = get_fpr32(fpr, 0) & 0x1;
0708 switch (insn.i_format.rs) {
0709 case bc1eqz_op:
0710 bit = bit0 == 0;
0711 break;
0712 case bc1nez_op:
0713 bit = bit0 != 0;
0714 break;
0715 }
0716 if (bit)
0717 *contpc = regs->cp0_epc +
0718 dec_insn.pc_inc +
0719 (insn.i_format.simmediate << 2);
0720 else
0721 *contpc = regs->cp0_epc +
0722 dec_insn.pc_inc +
0723 dec_insn.next_pc_inc;
0724
0725 return 1;
0726 }
0727
0728 fallthrough;
0729 case cop2_op:
0730 case cop1x_op:
0731 if (insn.i_format.rs == bc_op) {
0732 preempt_disable();
0733 if (is_fpu_owner())
0734 fcr31 = read_32bit_cp1_register(CP1_STATUS);
0735 else
0736 fcr31 = current->thread.fpu.fcr31;
0737 preempt_enable();
0738
0739 bit = (insn.i_format.rt >> 2);
0740 bit += (bit != 0);
0741 bit += 23;
0742 switch (insn.i_format.rt & 3) {
0743 case 0:
0744 case 2:
0745 if (~fcr31 & (1 << bit))
0746 *contpc = regs->cp0_epc +
0747 dec_insn.pc_inc +
0748 (insn.i_format.simmediate << 2);
0749 else
0750 *contpc = regs->cp0_epc +
0751 dec_insn.pc_inc +
0752 dec_insn.next_pc_inc;
0753 return 1;
0754 case 1:
0755 case 3:
0756 if (fcr31 & (1 << bit))
0757 *contpc = regs->cp0_epc +
0758 dec_insn.pc_inc +
0759 (insn.i_format.simmediate << 2);
0760 else
0761 *contpc = regs->cp0_epc +
0762 dec_insn.pc_inc +
0763 dec_insn.next_pc_inc;
0764 return 1;
0765 }
0766 }
0767 break;
0768 }
0769 return 0;
0770 }
0771
0772
0773
0774
0775
0776
0777
0778
0779
0780
0781
0782 static inline int cop1_64bit(struct pt_regs *xcp)
0783 {
0784 if (IS_ENABLED(CONFIG_64BIT) && !IS_ENABLED(CONFIG_MIPS32_O32))
0785 return 1;
0786 else if (IS_ENABLED(CONFIG_32BIT) &&
0787 !IS_ENABLED(CONFIG_MIPS_O32_FP64_SUPPORT))
0788 return 0;
0789
0790 return !test_thread_flag(TIF_32BIT_FPREGS);
0791 }
0792
0793 static inline bool hybrid_fprs(void)
0794 {
0795 return test_thread_flag(TIF_HYBRID_FPREGS);
0796 }
0797
0798 #define SIFROMREG(si, x) \
0799 do { \
0800 if (cop1_64bit(xcp) && !hybrid_fprs()) \
0801 (si) = (int)get_fpr32(&ctx->fpr[x], 0); \
0802 else \
0803 (si) = (int)get_fpr32(&ctx->fpr[(x) & ~1], (x) & 1); \
0804 } while (0)
0805
0806 #define SITOREG(si, x) \
0807 do { \
0808 if (cop1_64bit(xcp) && !hybrid_fprs()) { \
0809 unsigned int i; \
0810 set_fpr32(&ctx->fpr[x], 0, si); \
0811 for (i = 1; i < ARRAY_SIZE(ctx->fpr[x].val32); i++) \
0812 set_fpr32(&ctx->fpr[x], i, 0); \
0813 } else { \
0814 set_fpr32(&ctx->fpr[(x) & ~1], (x) & 1, si); \
0815 } \
0816 } while (0)
0817
0818 #define SIFROMHREG(si, x) ((si) = (int)get_fpr32(&ctx->fpr[x], 1))
0819
0820 #define SITOHREG(si, x) \
0821 do { \
0822 unsigned int i; \
0823 set_fpr32(&ctx->fpr[x], 1, si); \
0824 for (i = 2; i < ARRAY_SIZE(ctx->fpr[x].val32); i++) \
0825 set_fpr32(&ctx->fpr[x], i, 0); \
0826 } while (0)
0827
0828 #define DIFROMREG(di, x) \
0829 ((di) = get_fpr64(&ctx->fpr[(x) & ~(cop1_64bit(xcp) ^ 1)], 0))
0830
0831 #define DITOREG(di, x) \
0832 do { \
0833 unsigned int fpr, i; \
0834 fpr = (x) & ~(cop1_64bit(xcp) ^ 1); \
0835 set_fpr64(&ctx->fpr[fpr], 0, di); \
0836 for (i = 1; i < ARRAY_SIZE(ctx->fpr[x].val64); i++) \
0837 set_fpr64(&ctx->fpr[fpr], i, 0); \
0838 } while (0)
0839
0840 #define SPFROMREG(sp, x) SIFROMREG((sp).bits, x)
0841 #define SPTOREG(sp, x) SITOREG((sp).bits, x)
0842 #define DPFROMREG(dp, x) DIFROMREG((dp).bits, x)
0843 #define DPTOREG(dp, x) DITOREG((dp).bits, x)
0844
0845
0846
0847
0848 static inline void cop1_cfc(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
0849 mips_instruction ir)
0850 {
0851 u32 fcr31 = ctx->fcr31;
0852 u32 value = 0;
0853
0854 switch (MIPSInst_RD(ir)) {
0855 case FPCREG_CSR:
0856 value = fcr31;
0857 pr_debug("%p gpr[%d]<-csr=%08x\n",
0858 (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
0859 break;
0860
0861 case FPCREG_FENR:
0862 if (!cpu_has_mips_r)
0863 break;
0864 value = (fcr31 >> (FPU_CSR_FS_S - MIPS_FENR_FS_S)) &
0865 MIPS_FENR_FS;
0866 value |= fcr31 & (FPU_CSR_ALL_E | FPU_CSR_RM);
0867 pr_debug("%p gpr[%d]<-enr=%08x\n",
0868 (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
0869 break;
0870
0871 case FPCREG_FEXR:
0872 if (!cpu_has_mips_r)
0873 break;
0874 value = fcr31 & (FPU_CSR_ALL_X | FPU_CSR_ALL_S);
0875 pr_debug("%p gpr[%d]<-exr=%08x\n",
0876 (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
0877 break;
0878
0879 case FPCREG_FCCR:
0880 if (!cpu_has_mips_r)
0881 break;
0882 value = (fcr31 >> (FPU_CSR_COND_S - MIPS_FCCR_COND0_S)) &
0883 MIPS_FCCR_COND0;
0884 value |= (fcr31 >> (FPU_CSR_COND1_S - MIPS_FCCR_COND1_S)) &
0885 (MIPS_FCCR_CONDX & ~MIPS_FCCR_COND0);
0886 pr_debug("%p gpr[%d]<-ccr=%08x\n",
0887 (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
0888 break;
0889
0890 case FPCREG_RID:
0891 value = boot_cpu_data.fpu_id;
0892 break;
0893
0894 default:
0895 break;
0896 }
0897
0898 if (MIPSInst_RT(ir))
0899 xcp->regs[MIPSInst_RT(ir)] = value;
0900 }
0901
0902
0903
0904
0905 static inline void cop1_ctc(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
0906 mips_instruction ir)
0907 {
0908 u32 fcr31 = ctx->fcr31;
0909 u32 value;
0910 u32 mask;
0911
0912 if (MIPSInst_RT(ir) == 0)
0913 value = 0;
0914 else
0915 value = xcp->regs[MIPSInst_RT(ir)];
0916
0917 switch (MIPSInst_RD(ir)) {
0918 case FPCREG_CSR:
0919 pr_debug("%p gpr[%d]->csr=%08x\n",
0920 (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
0921
0922
0923 mask = boot_cpu_data.fpu_msk31;
0924 fcr31 = (value & ~mask) | (fcr31 & mask);
0925 break;
0926
0927 case FPCREG_FENR:
0928 if (!cpu_has_mips_r)
0929 break;
0930 pr_debug("%p gpr[%d]->enr=%08x\n",
0931 (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
0932 fcr31 &= ~(FPU_CSR_FS | FPU_CSR_ALL_E | FPU_CSR_RM);
0933 fcr31 |= (value << (FPU_CSR_FS_S - MIPS_FENR_FS_S)) &
0934 FPU_CSR_FS;
0935 fcr31 |= value & (FPU_CSR_ALL_E | FPU_CSR_RM);
0936 break;
0937
0938 case FPCREG_FEXR:
0939 if (!cpu_has_mips_r)
0940 break;
0941 pr_debug("%p gpr[%d]->exr=%08x\n",
0942 (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
0943 fcr31 &= ~(FPU_CSR_ALL_X | FPU_CSR_ALL_S);
0944 fcr31 |= value & (FPU_CSR_ALL_X | FPU_CSR_ALL_S);
0945 break;
0946
0947 case FPCREG_FCCR:
0948 if (!cpu_has_mips_r)
0949 break;
0950 pr_debug("%p gpr[%d]->ccr=%08x\n",
0951 (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
0952 fcr31 &= ~(FPU_CSR_CONDX | FPU_CSR_COND);
0953 fcr31 |= (value << (FPU_CSR_COND_S - MIPS_FCCR_COND0_S)) &
0954 FPU_CSR_COND;
0955 fcr31 |= (value << (FPU_CSR_COND1_S - MIPS_FCCR_COND1_S)) &
0956 FPU_CSR_CONDX;
0957 break;
0958
0959 default:
0960 break;
0961 }
0962
0963 ctx->fcr31 = fcr31;
0964 }
0965
0966
0967
0968
0969
0970
0971 static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
0972 struct mm_decoded_insn dec_insn, void __user **fault_addr)
0973 {
0974 unsigned long contpc = xcp->cp0_epc + dec_insn.pc_inc;
0975 unsigned int cond, cbit, bit0;
0976 mips_instruction ir;
0977 int likely, pc_inc;
0978 union fpureg *fpr;
0979 u32 __user *wva;
0980 u64 __user *dva;
0981 u32 wval;
0982 u64 dval;
0983 int sig;
0984
0985
0986
0987
0988
0989 if (!cpu_has_mmips && dec_insn.micro_mips_mode)
0990 unreachable();
0991
0992
0993 if (delay_slot(xcp)) {
0994 if (dec_insn.micro_mips_mode) {
0995 if (!mm_isBranchInstr(xcp, dec_insn, &contpc))
0996 clear_delay_slot(xcp);
0997 } else {
0998 if (!isBranchInstr(xcp, dec_insn, &contpc))
0999 clear_delay_slot(xcp);
1000 }
1001 }
1002
1003 if (delay_slot(xcp)) {
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016 ir = dec_insn.next_insn;
1017 pc_inc = dec_insn.next_pc_inc;
1018 } else {
1019 ir = dec_insn.insn;
1020 pc_inc = dec_insn.pc_inc;
1021 }
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033 if (dec_insn.micro_mips_mode) {
1034
1035
1036
1037
1038
1039 if ((pc_inc == 2) ||
1040 (microMIPS32_to_MIPS32((union mips_instruction *)&ir)
1041 == SIGILL))
1042 return SIGILL;
1043 }
1044
1045 emul:
1046 perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, xcp, 0);
1047 MIPS_FPU_EMU_INC_STATS(emulated);
1048 switch (MIPSInst_OPCODE(ir)) {
1049 case ldc1_op:
1050 dva = (u64 __user *) (xcp->regs[MIPSInst_RS(ir)] +
1051 MIPSInst_SIMM(ir));
1052 MIPS_FPU_EMU_INC_STATS(loads);
1053
1054 if (!access_ok(dva, sizeof(u64))) {
1055 MIPS_FPU_EMU_INC_STATS(errors);
1056 *fault_addr = dva;
1057 return SIGBUS;
1058 }
1059 if (__get_user(dval, dva)) {
1060 MIPS_FPU_EMU_INC_STATS(errors);
1061 *fault_addr = dva;
1062 return SIGSEGV;
1063 }
1064 DITOREG(dval, MIPSInst_RT(ir));
1065 break;
1066
1067 case sdc1_op:
1068 dva = (u64 __user *) (xcp->regs[MIPSInst_RS(ir)] +
1069 MIPSInst_SIMM(ir));
1070 MIPS_FPU_EMU_INC_STATS(stores);
1071 DIFROMREG(dval, MIPSInst_RT(ir));
1072 if (!access_ok(dva, sizeof(u64))) {
1073 MIPS_FPU_EMU_INC_STATS(errors);
1074 *fault_addr = dva;
1075 return SIGBUS;
1076 }
1077 if (__put_user(dval, dva)) {
1078 MIPS_FPU_EMU_INC_STATS(errors);
1079 *fault_addr = dva;
1080 return SIGSEGV;
1081 }
1082 break;
1083
1084 case lwc1_op:
1085 wva = (u32 __user *) (xcp->regs[MIPSInst_RS(ir)] +
1086 MIPSInst_SIMM(ir));
1087 MIPS_FPU_EMU_INC_STATS(loads);
1088 if (!access_ok(wva, sizeof(u32))) {
1089 MIPS_FPU_EMU_INC_STATS(errors);
1090 *fault_addr = wva;
1091 return SIGBUS;
1092 }
1093 if (__get_user(wval, wva)) {
1094 MIPS_FPU_EMU_INC_STATS(errors);
1095 *fault_addr = wva;
1096 return SIGSEGV;
1097 }
1098 SITOREG(wval, MIPSInst_RT(ir));
1099 break;
1100
1101 case swc1_op:
1102 wva = (u32 __user *) (xcp->regs[MIPSInst_RS(ir)] +
1103 MIPSInst_SIMM(ir));
1104 MIPS_FPU_EMU_INC_STATS(stores);
1105 SIFROMREG(wval, MIPSInst_RT(ir));
1106 if (!access_ok(wva, sizeof(u32))) {
1107 MIPS_FPU_EMU_INC_STATS(errors);
1108 *fault_addr = wva;
1109 return SIGBUS;
1110 }
1111 if (__put_user(wval, wva)) {
1112 MIPS_FPU_EMU_INC_STATS(errors);
1113 *fault_addr = wva;
1114 return SIGSEGV;
1115 }
1116 break;
1117
1118 case cop1_op:
1119 switch (MIPSInst_RS(ir)) {
1120 case dmfc_op:
1121 if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
1122 return SIGILL;
1123
1124
1125 if (MIPSInst_RT(ir) != 0) {
1126 DIFROMREG(xcp->regs[MIPSInst_RT(ir)],
1127 MIPSInst_RD(ir));
1128 }
1129 break;
1130
1131 case dmtc_op:
1132 if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
1133 return SIGILL;
1134
1135
1136 DITOREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
1137 break;
1138
1139 case mfhc_op:
1140 if (!cpu_has_mips_r2_r6)
1141 return SIGILL;
1142
1143
1144 if (MIPSInst_RT(ir) != 0) {
1145 SIFROMHREG(xcp->regs[MIPSInst_RT(ir)],
1146 MIPSInst_RD(ir));
1147 }
1148 break;
1149
1150 case mthc_op:
1151 if (!cpu_has_mips_r2_r6)
1152 return SIGILL;
1153
1154
1155 SITOHREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
1156 break;
1157
1158 case mfc_op:
1159
1160 if (MIPSInst_RT(ir) != 0) {
1161 SIFROMREG(xcp->regs[MIPSInst_RT(ir)],
1162 MIPSInst_RD(ir));
1163 }
1164 break;
1165
1166 case mtc_op:
1167
1168 SITOREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
1169 break;
1170
1171 case cfc_op:
1172
1173 cop1_cfc(xcp, ctx, ir);
1174 break;
1175
1176 case ctc_op:
1177
1178 cop1_ctc(xcp, ctx, ir);
1179 if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
1180 return SIGFPE;
1181 }
1182 break;
1183
1184 case bc1eqz_op:
1185 case bc1nez_op:
1186 if (!cpu_has_mips_r6 || delay_slot(xcp))
1187 return SIGILL;
1188
1189 likely = 0;
1190 cond = 0;
1191 fpr = ¤t->thread.fpu.fpr[MIPSInst_RT(ir)];
1192 bit0 = get_fpr32(fpr, 0) & 0x1;
1193 switch (MIPSInst_RS(ir)) {
1194 case bc1eqz_op:
1195 MIPS_FPU_EMU_INC_STATS(bc1eqz);
1196 cond = bit0 == 0;
1197 break;
1198 case bc1nez_op:
1199 MIPS_FPU_EMU_INC_STATS(bc1nez);
1200 cond = bit0 != 0;
1201 break;
1202 }
1203 goto branch_common;
1204
1205 case bc_op:
1206 if (delay_slot(xcp))
1207 return SIGILL;
1208
1209 if (cpu_has_mips_4_5_r)
1210 cbit = fpucondbit[MIPSInst_RT(ir) >> 2];
1211 else
1212 cbit = FPU_CSR_COND;
1213 cond = ctx->fcr31 & cbit;
1214
1215 likely = 0;
1216 switch (MIPSInst_RT(ir) & 3) {
1217 case bcfl_op:
1218 if (cpu_has_mips_2_3_4_5_r)
1219 likely = 1;
1220 fallthrough;
1221 case bcf_op:
1222 cond = !cond;
1223 break;
1224 case bctl_op:
1225 if (cpu_has_mips_2_3_4_5_r)
1226 likely = 1;
1227 fallthrough;
1228 case bct_op:
1229 break;
1230 }
1231 branch_common:
1232 MIPS_FPU_EMU_INC_STATS(branches);
1233 set_delay_slot(xcp);
1234 if (cond) {
1235
1236
1237
1238 unsigned long bcpc;
1239
1240
1241
1242
1243
1244
1245 bcpc = xcp->cp0_epc;
1246 xcp->cp0_epc += dec_insn.pc_inc;
1247
1248 contpc = MIPSInst_SIMM(ir);
1249 ir = dec_insn.next_insn;
1250 if (dec_insn.micro_mips_mode) {
1251 contpc = (xcp->cp0_epc + (contpc << 1));
1252
1253
1254 if ((dec_insn.next_pc_inc == 2) ||
1255 (microMIPS32_to_MIPS32((union mips_instruction *)&ir) == SIGILL)) {
1256
1257
1258
1259
1260
1261
1262
1263
1264 if (dec_insn.next_pc_inc == 2)
1265 ir = (ir & (~0xffff)) | MM_NOP16;
1266
1267
1268
1269
1270
1271 sig = mips_dsemul(xcp, ir,
1272 bcpc, contpc);
1273 if (sig < 0)
1274 break;
1275 if (sig)
1276 xcp->cp0_epc = bcpc;
1277
1278
1279
1280
1281 return sig ? sig : SIGILL;
1282 }
1283 } else
1284 contpc = (xcp->cp0_epc + (contpc << 2));
1285
1286 switch (MIPSInst_OPCODE(ir)) {
1287 case lwc1_op:
1288 case swc1_op:
1289 goto emul;
1290
1291 case ldc1_op:
1292 case sdc1_op:
1293 if (cpu_has_mips_2_3_4_5_r)
1294 goto emul;
1295
1296 goto bc_sigill;
1297
1298 case cop1_op:
1299 goto emul;
1300
1301 case cop1x_op:
1302 if (cpu_has_mips_4_5_64_r2_r6)
1303
1304 goto emul;
1305
1306 goto bc_sigill;
1307
1308 case spec_op:
1309 switch (MIPSInst_FUNC(ir)) {
1310 case movc_op:
1311 if (cpu_has_mips_4_5_r)
1312 goto emul;
1313
1314 goto bc_sigill;
1315 }
1316 break;
1317
1318 bc_sigill:
1319 xcp->cp0_epc = bcpc;
1320 return SIGILL;
1321 }
1322
1323
1324
1325
1326
1327 sig = mips_dsemul(xcp, ir, bcpc, contpc);
1328 if (sig < 0)
1329 break;
1330 if (sig)
1331 xcp->cp0_epc = bcpc;
1332
1333 return sig ? sig : SIGILL;
1334 } else if (likely) {
1335
1336
1337
1338
1339 xcp->cp0_epc += dec_insn.pc_inc;
1340 contpc += dec_insn.pc_inc;
1341
1342
1343
1344
1345 }
1346 break;
1347
1348 default:
1349 if (!(MIPSInst_RS(ir) & 0x10))
1350 return SIGILL;
1351
1352
1353 sig = fpu_emu(xcp, ctx, ir);
1354 if (sig)
1355 return sig;
1356 }
1357 break;
1358
1359 case cop1x_op:
1360 if (!cpu_has_mips_4_5_64_r2_r6)
1361 return SIGILL;
1362
1363 sig = fpux_emu(xcp, ctx, ir, fault_addr);
1364 if (sig)
1365 return sig;
1366 break;
1367
1368 case spec_op:
1369 if (!cpu_has_mips_4_5_r)
1370 return SIGILL;
1371
1372 if (MIPSInst_FUNC(ir) != movc_op)
1373 return SIGILL;
1374 cond = fpucondbit[MIPSInst_RT(ir) >> 2];
1375 if (((ctx->fcr31 & cond) != 0) == ((MIPSInst_RT(ir) & 1) != 0))
1376 xcp->regs[MIPSInst_RD(ir)] =
1377 xcp->regs[MIPSInst_RS(ir)];
1378 break;
1379 default:
1380 return SIGILL;
1381 }
1382
1383
1384 xcp->cp0_epc = contpc;
1385 clear_delay_slot(xcp);
1386
1387 return 0;
1388 }
1389
1390
1391
1392
1393
1394 static const unsigned char cmptab[8] = {
1395 0,
1396 IEEE754_CUN,
1397 IEEE754_CEQ,
1398 IEEE754_CEQ | IEEE754_CUN,
1399 IEEE754_CLT,
1400 IEEE754_CLT | IEEE754_CUN,
1401 IEEE754_CLT | IEEE754_CEQ,
1402 IEEE754_CLT | IEEE754_CEQ | IEEE754_CUN,
1403 };
1404
1405 static const unsigned char negative_cmptab[8] = {
1406 0,
1407 IEEE754_CLT | IEEE754_CGT | IEEE754_CEQ,
1408 IEEE754_CLT | IEEE754_CGT | IEEE754_CUN,
1409 IEEE754_CLT | IEEE754_CGT,
1410
1411 };
1412
1413
1414
1415
1416
1417
1418 #define DEF3OP(name, p, f1, f2, f3) \
1419 static union ieee754##p fpemu_##p##_##name(union ieee754##p r, \
1420 union ieee754##p s, union ieee754##p t) \
1421 { \
1422 struct _ieee754_csr ieee754_csr_save; \
1423 s = f1(s, t); \
1424 ieee754_csr_save = ieee754_csr; \
1425 s = f2(s, r); \
1426 ieee754_csr_save.cx |= ieee754_csr.cx; \
1427 ieee754_csr_save.sx |= ieee754_csr.sx; \
1428 s = f3(s); \
1429 ieee754_csr.cx |= ieee754_csr_save.cx; \
1430 ieee754_csr.sx |= ieee754_csr_save.sx; \
1431 return s; \
1432 }
1433
1434 static union ieee754dp fpemu_dp_recip(union ieee754dp d)
1435 {
1436 return ieee754dp_div(ieee754dp_one(0), d);
1437 }
1438
1439 static union ieee754dp fpemu_dp_rsqrt(union ieee754dp d)
1440 {
1441 return ieee754dp_div(ieee754dp_one(0), ieee754dp_sqrt(d));
1442 }
1443
1444 static union ieee754sp fpemu_sp_recip(union ieee754sp s)
1445 {
1446 return ieee754sp_div(ieee754sp_one(0), s);
1447 }
1448
1449 static union ieee754sp fpemu_sp_rsqrt(union ieee754sp s)
1450 {
1451 return ieee754sp_div(ieee754sp_one(0), ieee754sp_sqrt(s));
1452 }
1453
1454 DEF3OP(madd, sp, ieee754sp_mul, ieee754sp_add, );
1455 DEF3OP(msub, sp, ieee754sp_mul, ieee754sp_sub, );
1456 DEF3OP(nmadd, sp, ieee754sp_mul, ieee754sp_add, ieee754sp_neg);
1457 DEF3OP(nmsub, sp, ieee754sp_mul, ieee754sp_sub, ieee754sp_neg);
1458 DEF3OP(madd, dp, ieee754dp_mul, ieee754dp_add, );
1459 DEF3OP(msub, dp, ieee754dp_mul, ieee754dp_sub, );
1460 DEF3OP(nmadd, dp, ieee754dp_mul, ieee754dp_add, ieee754dp_neg);
1461 DEF3OP(nmsub, dp, ieee754dp_mul, ieee754dp_sub, ieee754dp_neg);
1462
1463 static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1464 mips_instruction ir, void __user **fault_addr)
1465 {
1466 unsigned int rcsr = 0;
1467
1468 MIPS_FPU_EMU_INC_STATS(cp1xops);
1469
1470 switch (MIPSInst_FMA_FFMT(ir)) {
1471 case s_fmt:{
1472
1473 union ieee754sp(*handler) (union ieee754sp, union ieee754sp, union ieee754sp);
1474 union ieee754sp fd, fr, fs, ft;
1475 u32 __user *va;
1476 u32 val;
1477
1478 switch (MIPSInst_FUNC(ir)) {
1479 case lwxc1_op:
1480 va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
1481 xcp->regs[MIPSInst_FT(ir)]);
1482
1483 MIPS_FPU_EMU_INC_STATS(loads);
1484 if (!access_ok(va, sizeof(u32))) {
1485 MIPS_FPU_EMU_INC_STATS(errors);
1486 *fault_addr = va;
1487 return SIGBUS;
1488 }
1489 if (__get_user(val, va)) {
1490 MIPS_FPU_EMU_INC_STATS(errors);
1491 *fault_addr = va;
1492 return SIGSEGV;
1493 }
1494 SITOREG(val, MIPSInst_FD(ir));
1495 break;
1496
1497 case swxc1_op:
1498 va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
1499 xcp->regs[MIPSInst_FT(ir)]);
1500
1501 MIPS_FPU_EMU_INC_STATS(stores);
1502
1503 SIFROMREG(val, MIPSInst_FS(ir));
1504 if (!access_ok(va, sizeof(u32))) {
1505 MIPS_FPU_EMU_INC_STATS(errors);
1506 *fault_addr = va;
1507 return SIGBUS;
1508 }
1509 if (put_user(val, va)) {
1510 MIPS_FPU_EMU_INC_STATS(errors);
1511 *fault_addr = va;
1512 return SIGSEGV;
1513 }
1514 break;
1515
1516 case madd_s_op:
1517 if (cpu_has_mac2008_only)
1518 handler = ieee754sp_madd;
1519 else
1520 handler = fpemu_sp_madd;
1521 goto scoptop;
1522 case msub_s_op:
1523 if (cpu_has_mac2008_only)
1524 handler = ieee754sp_msub;
1525 else
1526 handler = fpemu_sp_msub;
1527 goto scoptop;
1528 case nmadd_s_op:
1529 if (cpu_has_mac2008_only)
1530 handler = ieee754sp_nmadd;
1531 else
1532 handler = fpemu_sp_nmadd;
1533 goto scoptop;
1534 case nmsub_s_op:
1535 if (cpu_has_mac2008_only)
1536 handler = ieee754sp_nmsub;
1537 else
1538 handler = fpemu_sp_nmsub;
1539 goto scoptop;
1540
1541 scoptop:
1542 SPFROMREG(fr, MIPSInst_FR(ir));
1543 SPFROMREG(fs, MIPSInst_FS(ir));
1544 SPFROMREG(ft, MIPSInst_FT(ir));
1545 fd = (*handler) (fr, fs, ft);
1546 SPTOREG(fd, MIPSInst_FD(ir));
1547
1548 copcsr:
1549 if (ieee754_cxtest(IEEE754_INEXACT)) {
1550 MIPS_FPU_EMU_INC_STATS(ieee754_inexact);
1551 rcsr |= FPU_CSR_INE_X | FPU_CSR_INE_S;
1552 }
1553 if (ieee754_cxtest(IEEE754_UNDERFLOW)) {
1554 MIPS_FPU_EMU_INC_STATS(ieee754_underflow);
1555 rcsr |= FPU_CSR_UDF_X | FPU_CSR_UDF_S;
1556 }
1557 if (ieee754_cxtest(IEEE754_OVERFLOW)) {
1558 MIPS_FPU_EMU_INC_STATS(ieee754_overflow);
1559 rcsr |= FPU_CSR_OVF_X | FPU_CSR_OVF_S;
1560 }
1561 if (ieee754_cxtest(IEEE754_INVALID_OPERATION)) {
1562 MIPS_FPU_EMU_INC_STATS(ieee754_invalidop);
1563 rcsr |= FPU_CSR_INV_X | FPU_CSR_INV_S;
1564 }
1565
1566 ctx->fcr31 = (ctx->fcr31 & ~FPU_CSR_ALL_X) | rcsr;
1567 if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
1568
1569
1570 return SIGFPE;
1571 }
1572
1573 break;
1574
1575 default:
1576 return SIGILL;
1577 }
1578 break;
1579 }
1580
1581 case d_fmt:{
1582 union ieee754dp(*handler) (union ieee754dp, union ieee754dp, union ieee754dp);
1583 union ieee754dp fd, fr, fs, ft;
1584 u64 __user *va;
1585 u64 val;
1586
1587 switch (MIPSInst_FUNC(ir)) {
1588 case ldxc1_op:
1589 va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
1590 xcp->regs[MIPSInst_FT(ir)]);
1591
1592 MIPS_FPU_EMU_INC_STATS(loads);
1593 if (!access_ok(va, sizeof(u64))) {
1594 MIPS_FPU_EMU_INC_STATS(errors);
1595 *fault_addr = va;
1596 return SIGBUS;
1597 }
1598 if (__get_user(val, va)) {
1599 MIPS_FPU_EMU_INC_STATS(errors);
1600 *fault_addr = va;
1601 return SIGSEGV;
1602 }
1603 DITOREG(val, MIPSInst_FD(ir));
1604 break;
1605
1606 case sdxc1_op:
1607 va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
1608 xcp->regs[MIPSInst_FT(ir)]);
1609
1610 MIPS_FPU_EMU_INC_STATS(stores);
1611 DIFROMREG(val, MIPSInst_FS(ir));
1612 if (!access_ok(va, sizeof(u64))) {
1613 MIPS_FPU_EMU_INC_STATS(errors);
1614 *fault_addr = va;
1615 return SIGBUS;
1616 }
1617 if (__put_user(val, va)) {
1618 MIPS_FPU_EMU_INC_STATS(errors);
1619 *fault_addr = va;
1620 return SIGSEGV;
1621 }
1622 break;
1623
1624 case madd_d_op:
1625 if (cpu_has_mac2008_only)
1626 handler = ieee754dp_madd;
1627 else
1628 handler = fpemu_dp_madd;
1629 goto dcoptop;
1630 case msub_d_op:
1631 if (cpu_has_mac2008_only)
1632 handler = ieee754dp_msub;
1633 else
1634 handler = fpemu_dp_msub;
1635 goto dcoptop;
1636 case nmadd_d_op:
1637 if (cpu_has_mac2008_only)
1638 handler = ieee754dp_nmadd;
1639 else
1640 handler = fpemu_dp_nmadd;
1641 goto dcoptop;
1642 case nmsub_d_op:
1643 if (cpu_has_mac2008_only)
1644 handler = ieee754dp_nmsub;
1645 else
1646 handler = fpemu_dp_nmsub;
1647 goto dcoptop;
1648
1649 dcoptop:
1650 DPFROMREG(fr, MIPSInst_FR(ir));
1651 DPFROMREG(fs, MIPSInst_FS(ir));
1652 DPFROMREG(ft, MIPSInst_FT(ir));
1653 fd = (*handler) (fr, fs, ft);
1654 DPTOREG(fd, MIPSInst_FD(ir));
1655 goto copcsr;
1656
1657 default:
1658 return SIGILL;
1659 }
1660 break;
1661 }
1662
1663 case 0x3:
1664 if (MIPSInst_FUNC(ir) != pfetch_op)
1665 return SIGILL;
1666
1667
1668 break;
1669
1670 default:
1671 return SIGILL;
1672 }
1673
1674 return 0;
1675 }
1676
1677
1678
1679
1680
1681
1682 static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1683 mips_instruction ir)
1684 {
1685 int rfmt;
1686 unsigned int rcsr = 0;
1687 unsigned int oldrm;
1688 unsigned int cbit;
1689 unsigned int cond;
1690 union {
1691 union ieee754dp d;
1692 union ieee754sp s;
1693 int w;
1694 s64 l;
1695 } rv;
1696 u64 bits;
1697
1698 MIPS_FPU_EMU_INC_STATS(cp1ops);
1699 switch (rfmt = (MIPSInst_FFMT(ir) & 0xf)) {
1700 case s_fmt: {
1701 union {
1702 union ieee754sp(*b) (union ieee754sp, union ieee754sp);
1703 union ieee754sp(*u) (union ieee754sp);
1704 } handler;
1705 union ieee754sp fd, fs, ft;
1706
1707 switch (MIPSInst_FUNC(ir)) {
1708
1709 case fadd_op:
1710 MIPS_FPU_EMU_INC_STATS(add_s);
1711 handler.b = ieee754sp_add;
1712 goto scopbop;
1713 case fsub_op:
1714 MIPS_FPU_EMU_INC_STATS(sub_s);
1715 handler.b = ieee754sp_sub;
1716 goto scopbop;
1717 case fmul_op:
1718 MIPS_FPU_EMU_INC_STATS(mul_s);
1719 handler.b = ieee754sp_mul;
1720 goto scopbop;
1721 case fdiv_op:
1722 MIPS_FPU_EMU_INC_STATS(div_s);
1723 handler.b = ieee754sp_div;
1724 goto scopbop;
1725
1726
1727 case fsqrt_op:
1728 if (!cpu_has_mips_2_3_4_5_r)
1729 return SIGILL;
1730
1731 MIPS_FPU_EMU_INC_STATS(sqrt_s);
1732 handler.u = ieee754sp_sqrt;
1733 goto scopuop;
1734
1735
1736
1737
1738
1739
1740 case frsqrt_op:
1741 if (!cpu_has_mips_4_5_64_r2_r6)
1742 return SIGILL;
1743
1744 MIPS_FPU_EMU_INC_STATS(rsqrt_s);
1745 handler.u = fpemu_sp_rsqrt;
1746 goto scopuop;
1747
1748 case frecip_op:
1749 if (!cpu_has_mips_4_5_64_r2_r6)
1750 return SIGILL;
1751
1752 MIPS_FPU_EMU_INC_STATS(recip_s);
1753 handler.u = fpemu_sp_recip;
1754 goto scopuop;
1755
1756 case fmovc_op:
1757 if (!cpu_has_mips_4_5_r)
1758 return SIGILL;
1759
1760 cond = fpucondbit[MIPSInst_FT(ir) >> 2];
1761 if (((ctx->fcr31 & cond) != 0) !=
1762 ((MIPSInst_FT(ir) & 1) != 0))
1763 return 0;
1764 SPFROMREG(rv.s, MIPSInst_FS(ir));
1765 break;
1766
1767 case fmovz_op:
1768 if (!cpu_has_mips_4_5_r)
1769 return SIGILL;
1770
1771 if (xcp->regs[MIPSInst_FT(ir)] != 0)
1772 return 0;
1773 SPFROMREG(rv.s, MIPSInst_FS(ir));
1774 break;
1775
1776 case fmovn_op:
1777 if (!cpu_has_mips_4_5_r)
1778 return SIGILL;
1779
1780 if (xcp->regs[MIPSInst_FT(ir)] == 0)
1781 return 0;
1782 SPFROMREG(rv.s, MIPSInst_FS(ir));
1783 break;
1784
1785 case fseleqz_op:
1786 if (!cpu_has_mips_r6)
1787 return SIGILL;
1788
1789 MIPS_FPU_EMU_INC_STATS(seleqz_s);
1790 SPFROMREG(rv.s, MIPSInst_FT(ir));
1791 if (rv.w & 0x1)
1792 rv.w = 0;
1793 else
1794 SPFROMREG(rv.s, MIPSInst_FS(ir));
1795 break;
1796
1797 case fselnez_op:
1798 if (!cpu_has_mips_r6)
1799 return SIGILL;
1800
1801 MIPS_FPU_EMU_INC_STATS(selnez_s);
1802 SPFROMREG(rv.s, MIPSInst_FT(ir));
1803 if (rv.w & 0x1)
1804 SPFROMREG(rv.s, MIPSInst_FS(ir));
1805 else
1806 rv.w = 0;
1807 break;
1808
1809 case fmaddf_op: {
1810 union ieee754sp ft, fs, fd;
1811
1812 if (!cpu_has_mips_r6)
1813 return SIGILL;
1814
1815 MIPS_FPU_EMU_INC_STATS(maddf_s);
1816 SPFROMREG(ft, MIPSInst_FT(ir));
1817 SPFROMREG(fs, MIPSInst_FS(ir));
1818 SPFROMREG(fd, MIPSInst_FD(ir));
1819 rv.s = ieee754sp_maddf(fd, fs, ft);
1820 goto copcsr;
1821 }
1822
1823 case fmsubf_op: {
1824 union ieee754sp ft, fs, fd;
1825
1826 if (!cpu_has_mips_r6)
1827 return SIGILL;
1828
1829 MIPS_FPU_EMU_INC_STATS(msubf_s);
1830 SPFROMREG(ft, MIPSInst_FT(ir));
1831 SPFROMREG(fs, MIPSInst_FS(ir));
1832 SPFROMREG(fd, MIPSInst_FD(ir));
1833 rv.s = ieee754sp_msubf(fd, fs, ft);
1834 goto copcsr;
1835 }
1836
1837 case frint_op: {
1838 union ieee754sp fs;
1839
1840 if (!cpu_has_mips_r6)
1841 return SIGILL;
1842
1843 MIPS_FPU_EMU_INC_STATS(rint_s);
1844 SPFROMREG(fs, MIPSInst_FS(ir));
1845 rv.s = ieee754sp_rint(fs);
1846 goto copcsr;
1847 }
1848
1849 case fclass_op: {
1850 union ieee754sp fs;
1851
1852 if (!cpu_has_mips_r6)
1853 return SIGILL;
1854
1855 MIPS_FPU_EMU_INC_STATS(class_s);
1856 SPFROMREG(fs, MIPSInst_FS(ir));
1857 rv.w = ieee754sp_2008class(fs);
1858 rfmt = w_fmt;
1859 goto copcsr;
1860 }
1861
1862 case fmin_op: {
1863 union ieee754sp fs, ft;
1864
1865 if (!cpu_has_mips_r6)
1866 return SIGILL;
1867
1868 MIPS_FPU_EMU_INC_STATS(min_s);
1869 SPFROMREG(ft, MIPSInst_FT(ir));
1870 SPFROMREG(fs, MIPSInst_FS(ir));
1871 rv.s = ieee754sp_fmin(fs, ft);
1872 goto copcsr;
1873 }
1874
1875 case fmina_op: {
1876 union ieee754sp fs, ft;
1877
1878 if (!cpu_has_mips_r6)
1879 return SIGILL;
1880
1881 MIPS_FPU_EMU_INC_STATS(mina_s);
1882 SPFROMREG(ft, MIPSInst_FT(ir));
1883 SPFROMREG(fs, MIPSInst_FS(ir));
1884 rv.s = ieee754sp_fmina(fs, ft);
1885 goto copcsr;
1886 }
1887
1888 case fmax_op: {
1889 union ieee754sp fs, ft;
1890
1891 if (!cpu_has_mips_r6)
1892 return SIGILL;
1893
1894 MIPS_FPU_EMU_INC_STATS(max_s);
1895 SPFROMREG(ft, MIPSInst_FT(ir));
1896 SPFROMREG(fs, MIPSInst_FS(ir));
1897 rv.s = ieee754sp_fmax(fs, ft);
1898 goto copcsr;
1899 }
1900
1901 case fmaxa_op: {
1902 union ieee754sp fs, ft;
1903
1904 if (!cpu_has_mips_r6)
1905 return SIGILL;
1906
1907 MIPS_FPU_EMU_INC_STATS(maxa_s);
1908 SPFROMREG(ft, MIPSInst_FT(ir));
1909 SPFROMREG(fs, MIPSInst_FS(ir));
1910 rv.s = ieee754sp_fmaxa(fs, ft);
1911 goto copcsr;
1912 }
1913
1914 case fabs_op:
1915 MIPS_FPU_EMU_INC_STATS(abs_s);
1916 handler.u = ieee754sp_abs;
1917 goto scopuop;
1918
1919 case fneg_op:
1920 MIPS_FPU_EMU_INC_STATS(neg_s);
1921 handler.u = ieee754sp_neg;
1922 goto scopuop;
1923
1924 case fmov_op:
1925
1926 MIPS_FPU_EMU_INC_STATS(mov_s);
1927 SPFROMREG(rv.s, MIPSInst_FS(ir));
1928 goto copcsr;
1929
1930
1931 scopbop:
1932 SPFROMREG(fs, MIPSInst_FS(ir));
1933 SPFROMREG(ft, MIPSInst_FT(ir));
1934
1935 rv.s = (*handler.b) (fs, ft);
1936 goto copcsr;
1937 scopuop:
1938 SPFROMREG(fs, MIPSInst_FS(ir));
1939 rv.s = (*handler.u) (fs);
1940 goto copcsr;
1941 copcsr:
1942 if (ieee754_cxtest(IEEE754_INEXACT)) {
1943 MIPS_FPU_EMU_INC_STATS(ieee754_inexact);
1944 rcsr |= FPU_CSR_INE_X | FPU_CSR_INE_S;
1945 }
1946 if (ieee754_cxtest(IEEE754_UNDERFLOW)) {
1947 MIPS_FPU_EMU_INC_STATS(ieee754_underflow);
1948 rcsr |= FPU_CSR_UDF_X | FPU_CSR_UDF_S;
1949 }
1950 if (ieee754_cxtest(IEEE754_OVERFLOW)) {
1951 MIPS_FPU_EMU_INC_STATS(ieee754_overflow);
1952 rcsr |= FPU_CSR_OVF_X | FPU_CSR_OVF_S;
1953 }
1954 if (ieee754_cxtest(IEEE754_ZERO_DIVIDE)) {
1955 MIPS_FPU_EMU_INC_STATS(ieee754_zerodiv);
1956 rcsr |= FPU_CSR_DIV_X | FPU_CSR_DIV_S;
1957 }
1958 if (ieee754_cxtest(IEEE754_INVALID_OPERATION)) {
1959 MIPS_FPU_EMU_INC_STATS(ieee754_invalidop);
1960 rcsr |= FPU_CSR_INV_X | FPU_CSR_INV_S;
1961 }
1962 break;
1963
1964
1965 case fcvts_op:
1966 return SIGILL;
1967
1968 case fcvtd_op:
1969 MIPS_FPU_EMU_INC_STATS(cvt_d_s);
1970 SPFROMREG(fs, MIPSInst_FS(ir));
1971 rv.d = ieee754dp_fsp(fs);
1972 rfmt = d_fmt;
1973 goto copcsr;
1974
1975 case fcvtw_op:
1976 MIPS_FPU_EMU_INC_STATS(cvt_w_s);
1977 SPFROMREG(fs, MIPSInst_FS(ir));
1978 rv.w = ieee754sp_tint(fs);
1979 rfmt = w_fmt;
1980 goto copcsr;
1981
1982 case fround_op:
1983 case ftrunc_op:
1984 case fceil_op:
1985 case ffloor_op:
1986 if (!cpu_has_mips_2_3_4_5_r)
1987 return SIGILL;
1988
1989 if (MIPSInst_FUNC(ir) == fceil_op)
1990 MIPS_FPU_EMU_INC_STATS(ceil_w_s);
1991 if (MIPSInst_FUNC(ir) == ffloor_op)
1992 MIPS_FPU_EMU_INC_STATS(floor_w_s);
1993 if (MIPSInst_FUNC(ir) == fround_op)
1994 MIPS_FPU_EMU_INC_STATS(round_w_s);
1995 if (MIPSInst_FUNC(ir) == ftrunc_op)
1996 MIPS_FPU_EMU_INC_STATS(trunc_w_s);
1997
1998 oldrm = ieee754_csr.rm;
1999 SPFROMREG(fs, MIPSInst_FS(ir));
2000 ieee754_csr.rm = MIPSInst_FUNC(ir);
2001 rv.w = ieee754sp_tint(fs);
2002 ieee754_csr.rm = oldrm;
2003 rfmt = w_fmt;
2004 goto copcsr;
2005
2006 case fsel_op:
2007 if (!cpu_has_mips_r6)
2008 return SIGILL;
2009
2010 MIPS_FPU_EMU_INC_STATS(sel_s);
2011 SPFROMREG(fd, MIPSInst_FD(ir));
2012 if (fd.bits & 0x1)
2013 SPFROMREG(rv.s, MIPSInst_FT(ir));
2014 else
2015 SPFROMREG(rv.s, MIPSInst_FS(ir));
2016 break;
2017
2018 case fcvtl_op:
2019 if (!cpu_has_mips_3_4_5_64_r2_r6)
2020 return SIGILL;
2021
2022 MIPS_FPU_EMU_INC_STATS(cvt_l_s);
2023 SPFROMREG(fs, MIPSInst_FS(ir));
2024 rv.l = ieee754sp_tlong(fs);
2025 rfmt = l_fmt;
2026 goto copcsr;
2027
2028 case froundl_op:
2029 case ftruncl_op:
2030 case fceill_op:
2031 case ffloorl_op:
2032 if (!cpu_has_mips_3_4_5_64_r2_r6)
2033 return SIGILL;
2034
2035 if (MIPSInst_FUNC(ir) == fceill_op)
2036 MIPS_FPU_EMU_INC_STATS(ceil_l_s);
2037 if (MIPSInst_FUNC(ir) == ffloorl_op)
2038 MIPS_FPU_EMU_INC_STATS(floor_l_s);
2039 if (MIPSInst_FUNC(ir) == froundl_op)
2040 MIPS_FPU_EMU_INC_STATS(round_l_s);
2041 if (MIPSInst_FUNC(ir) == ftruncl_op)
2042 MIPS_FPU_EMU_INC_STATS(trunc_l_s);
2043
2044 oldrm = ieee754_csr.rm;
2045 SPFROMREG(fs, MIPSInst_FS(ir));
2046 ieee754_csr.rm = MIPSInst_FUNC(ir);
2047 rv.l = ieee754sp_tlong(fs);
2048 ieee754_csr.rm = oldrm;
2049 rfmt = l_fmt;
2050 goto copcsr;
2051
2052 default:
2053 if (!NO_R6EMU && MIPSInst_FUNC(ir) >= fcmp_op) {
2054 unsigned int cmpop;
2055 union ieee754sp fs, ft;
2056
2057 cmpop = MIPSInst_FUNC(ir) - fcmp_op;
2058 SPFROMREG(fs, MIPSInst_FS(ir));
2059 SPFROMREG(ft, MIPSInst_FT(ir));
2060 rv.w = ieee754sp_cmp(fs, ft,
2061 cmptab[cmpop & 0x7], cmpop & 0x8);
2062 rfmt = -1;
2063 if ((cmpop & 0x8) && ieee754_cxtest
2064 (IEEE754_INVALID_OPERATION))
2065 rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
2066 else
2067 goto copcsr;
2068
2069 } else
2070 return SIGILL;
2071 break;
2072 }
2073 break;
2074 }
2075
2076 case d_fmt: {
2077 union ieee754dp fd, fs, ft;
2078 union {
2079 union ieee754dp(*b) (union ieee754dp, union ieee754dp);
2080 union ieee754dp(*u) (union ieee754dp);
2081 } handler;
2082
2083 switch (MIPSInst_FUNC(ir)) {
2084
2085 case fadd_op:
2086 MIPS_FPU_EMU_INC_STATS(add_d);
2087 handler.b = ieee754dp_add;
2088 goto dcopbop;
2089 case fsub_op:
2090 MIPS_FPU_EMU_INC_STATS(sub_d);
2091 handler.b = ieee754dp_sub;
2092 goto dcopbop;
2093 case fmul_op:
2094 MIPS_FPU_EMU_INC_STATS(mul_d);
2095 handler.b = ieee754dp_mul;
2096 goto dcopbop;
2097 case fdiv_op:
2098 MIPS_FPU_EMU_INC_STATS(div_d);
2099 handler.b = ieee754dp_div;
2100 goto dcopbop;
2101
2102
2103 case fsqrt_op:
2104 if (!cpu_has_mips_2_3_4_5_r)
2105 return SIGILL;
2106
2107 MIPS_FPU_EMU_INC_STATS(sqrt_d);
2108 handler.u = ieee754dp_sqrt;
2109 goto dcopuop;
2110
2111
2112
2113
2114
2115 case frsqrt_op:
2116 if (!cpu_has_mips_4_5_64_r2_r6)
2117 return SIGILL;
2118
2119 MIPS_FPU_EMU_INC_STATS(rsqrt_d);
2120 handler.u = fpemu_dp_rsqrt;
2121 goto dcopuop;
2122 case frecip_op:
2123 if (!cpu_has_mips_4_5_64_r2_r6)
2124 return SIGILL;
2125
2126 MIPS_FPU_EMU_INC_STATS(recip_d);
2127 handler.u = fpemu_dp_recip;
2128 goto dcopuop;
2129 case fmovc_op:
2130 if (!cpu_has_mips_4_5_r)
2131 return SIGILL;
2132
2133 cond = fpucondbit[MIPSInst_FT(ir) >> 2];
2134 if (((ctx->fcr31 & cond) != 0) !=
2135 ((MIPSInst_FT(ir) & 1) != 0))
2136 return 0;
2137 DPFROMREG(rv.d, MIPSInst_FS(ir));
2138 break;
2139 case fmovz_op:
2140 if (!cpu_has_mips_4_5_r)
2141 return SIGILL;
2142
2143 if (xcp->regs[MIPSInst_FT(ir)] != 0)
2144 return 0;
2145 DPFROMREG(rv.d, MIPSInst_FS(ir));
2146 break;
2147 case fmovn_op:
2148 if (!cpu_has_mips_4_5_r)
2149 return SIGILL;
2150
2151 if (xcp->regs[MIPSInst_FT(ir)] == 0)
2152 return 0;
2153 DPFROMREG(rv.d, MIPSInst_FS(ir));
2154 break;
2155
2156 case fseleqz_op:
2157 if (!cpu_has_mips_r6)
2158 return SIGILL;
2159
2160 MIPS_FPU_EMU_INC_STATS(seleqz_d);
2161 DPFROMREG(rv.d, MIPSInst_FT(ir));
2162 if (rv.l & 0x1)
2163 rv.l = 0;
2164 else
2165 DPFROMREG(rv.d, MIPSInst_FS(ir));
2166 break;
2167
2168 case fselnez_op:
2169 if (!cpu_has_mips_r6)
2170 return SIGILL;
2171
2172 MIPS_FPU_EMU_INC_STATS(selnez_d);
2173 DPFROMREG(rv.d, MIPSInst_FT(ir));
2174 if (rv.l & 0x1)
2175 DPFROMREG(rv.d, MIPSInst_FS(ir));
2176 else
2177 rv.l = 0;
2178 break;
2179
2180 case fmaddf_op: {
2181 union ieee754dp ft, fs, fd;
2182
2183 if (!cpu_has_mips_r6)
2184 return SIGILL;
2185
2186 MIPS_FPU_EMU_INC_STATS(maddf_d);
2187 DPFROMREG(ft, MIPSInst_FT(ir));
2188 DPFROMREG(fs, MIPSInst_FS(ir));
2189 DPFROMREG(fd, MIPSInst_FD(ir));
2190 rv.d = ieee754dp_maddf(fd, fs, ft);
2191 goto copcsr;
2192 }
2193
2194 case fmsubf_op: {
2195 union ieee754dp ft, fs, fd;
2196
2197 if (!cpu_has_mips_r6)
2198 return SIGILL;
2199
2200 MIPS_FPU_EMU_INC_STATS(msubf_d);
2201 DPFROMREG(ft, MIPSInst_FT(ir));
2202 DPFROMREG(fs, MIPSInst_FS(ir));
2203 DPFROMREG(fd, MIPSInst_FD(ir));
2204 rv.d = ieee754dp_msubf(fd, fs, ft);
2205 goto copcsr;
2206 }
2207
2208 case frint_op: {
2209 union ieee754dp fs;
2210
2211 if (!cpu_has_mips_r6)
2212 return SIGILL;
2213
2214 MIPS_FPU_EMU_INC_STATS(rint_d);
2215 DPFROMREG(fs, MIPSInst_FS(ir));
2216 rv.d = ieee754dp_rint(fs);
2217 goto copcsr;
2218 }
2219
2220 case fclass_op: {
2221 union ieee754dp fs;
2222
2223 if (!cpu_has_mips_r6)
2224 return SIGILL;
2225
2226 MIPS_FPU_EMU_INC_STATS(class_d);
2227 DPFROMREG(fs, MIPSInst_FS(ir));
2228 rv.l = ieee754dp_2008class(fs);
2229 rfmt = l_fmt;
2230 goto copcsr;
2231 }
2232
2233 case fmin_op: {
2234 union ieee754dp fs, ft;
2235
2236 if (!cpu_has_mips_r6)
2237 return SIGILL;
2238
2239 MIPS_FPU_EMU_INC_STATS(min_d);
2240 DPFROMREG(ft, MIPSInst_FT(ir));
2241 DPFROMREG(fs, MIPSInst_FS(ir));
2242 rv.d = ieee754dp_fmin(fs, ft);
2243 goto copcsr;
2244 }
2245
2246 case fmina_op: {
2247 union ieee754dp fs, ft;
2248
2249 if (!cpu_has_mips_r6)
2250 return SIGILL;
2251
2252 MIPS_FPU_EMU_INC_STATS(mina_d);
2253 DPFROMREG(ft, MIPSInst_FT(ir));
2254 DPFROMREG(fs, MIPSInst_FS(ir));
2255 rv.d = ieee754dp_fmina(fs, ft);
2256 goto copcsr;
2257 }
2258
2259 case fmax_op: {
2260 union ieee754dp fs, ft;
2261
2262 if (!cpu_has_mips_r6)
2263 return SIGILL;
2264
2265 MIPS_FPU_EMU_INC_STATS(max_d);
2266 DPFROMREG(ft, MIPSInst_FT(ir));
2267 DPFROMREG(fs, MIPSInst_FS(ir));
2268 rv.d = ieee754dp_fmax(fs, ft);
2269 goto copcsr;
2270 }
2271
2272 case fmaxa_op: {
2273 union ieee754dp fs, ft;
2274
2275 if (!cpu_has_mips_r6)
2276 return SIGILL;
2277
2278 MIPS_FPU_EMU_INC_STATS(maxa_d);
2279 DPFROMREG(ft, MIPSInst_FT(ir));
2280 DPFROMREG(fs, MIPSInst_FS(ir));
2281 rv.d = ieee754dp_fmaxa(fs, ft);
2282 goto copcsr;
2283 }
2284
2285 case fabs_op:
2286 MIPS_FPU_EMU_INC_STATS(abs_d);
2287 handler.u = ieee754dp_abs;
2288 goto dcopuop;
2289
2290 case fneg_op:
2291 MIPS_FPU_EMU_INC_STATS(neg_d);
2292 handler.u = ieee754dp_neg;
2293 goto dcopuop;
2294
2295 case fmov_op:
2296
2297 MIPS_FPU_EMU_INC_STATS(mov_d);
2298 DPFROMREG(rv.d, MIPSInst_FS(ir));
2299 goto copcsr;
2300
2301
2302 dcopbop:
2303 DPFROMREG(fs, MIPSInst_FS(ir));
2304 DPFROMREG(ft, MIPSInst_FT(ir));
2305
2306 rv.d = (*handler.b) (fs, ft);
2307 goto copcsr;
2308 dcopuop:
2309 DPFROMREG(fs, MIPSInst_FS(ir));
2310 rv.d = (*handler.u) (fs);
2311 goto copcsr;
2312
2313
2314
2315
2316 case fcvts_op:
2317 MIPS_FPU_EMU_INC_STATS(cvt_s_d);
2318 DPFROMREG(fs, MIPSInst_FS(ir));
2319 rv.s = ieee754sp_fdp(fs);
2320 rfmt = s_fmt;
2321 goto copcsr;
2322
2323 case fcvtd_op:
2324 return SIGILL;
2325
2326 case fcvtw_op:
2327 MIPS_FPU_EMU_INC_STATS(cvt_w_d);
2328 DPFROMREG(fs, MIPSInst_FS(ir));
2329 rv.w = ieee754dp_tint(fs);
2330 rfmt = w_fmt;
2331 goto copcsr;
2332
2333 case fround_op:
2334 case ftrunc_op:
2335 case fceil_op:
2336 case ffloor_op:
2337 if (!cpu_has_mips_2_3_4_5_r)
2338 return SIGILL;
2339
2340 if (MIPSInst_FUNC(ir) == fceil_op)
2341 MIPS_FPU_EMU_INC_STATS(ceil_w_d);
2342 if (MIPSInst_FUNC(ir) == ffloor_op)
2343 MIPS_FPU_EMU_INC_STATS(floor_w_d);
2344 if (MIPSInst_FUNC(ir) == fround_op)
2345 MIPS_FPU_EMU_INC_STATS(round_w_d);
2346 if (MIPSInst_FUNC(ir) == ftrunc_op)
2347 MIPS_FPU_EMU_INC_STATS(trunc_w_d);
2348
2349 oldrm = ieee754_csr.rm;
2350 DPFROMREG(fs, MIPSInst_FS(ir));
2351 ieee754_csr.rm = MIPSInst_FUNC(ir);
2352 rv.w = ieee754dp_tint(fs);
2353 ieee754_csr.rm = oldrm;
2354 rfmt = w_fmt;
2355 goto copcsr;
2356
2357 case fsel_op:
2358 if (!cpu_has_mips_r6)
2359 return SIGILL;
2360
2361 MIPS_FPU_EMU_INC_STATS(sel_d);
2362 DPFROMREG(fd, MIPSInst_FD(ir));
2363 if (fd.bits & 0x1)
2364 DPFROMREG(rv.d, MIPSInst_FT(ir));
2365 else
2366 DPFROMREG(rv.d, MIPSInst_FS(ir));
2367 break;
2368
2369 case fcvtl_op:
2370 if (!cpu_has_mips_3_4_5_64_r2_r6)
2371 return SIGILL;
2372
2373 MIPS_FPU_EMU_INC_STATS(cvt_l_d);
2374 DPFROMREG(fs, MIPSInst_FS(ir));
2375 rv.l = ieee754dp_tlong(fs);
2376 rfmt = l_fmt;
2377 goto copcsr;
2378
2379 case froundl_op:
2380 case ftruncl_op:
2381 case fceill_op:
2382 case ffloorl_op:
2383 if (!cpu_has_mips_3_4_5_64_r2_r6)
2384 return SIGILL;
2385
2386 if (MIPSInst_FUNC(ir) == fceill_op)
2387 MIPS_FPU_EMU_INC_STATS(ceil_l_d);
2388 if (MIPSInst_FUNC(ir) == ffloorl_op)
2389 MIPS_FPU_EMU_INC_STATS(floor_l_d);
2390 if (MIPSInst_FUNC(ir) == froundl_op)
2391 MIPS_FPU_EMU_INC_STATS(round_l_d);
2392 if (MIPSInst_FUNC(ir) == ftruncl_op)
2393 MIPS_FPU_EMU_INC_STATS(trunc_l_d);
2394
2395 oldrm = ieee754_csr.rm;
2396 DPFROMREG(fs, MIPSInst_FS(ir));
2397 ieee754_csr.rm = MIPSInst_FUNC(ir);
2398 rv.l = ieee754dp_tlong(fs);
2399 ieee754_csr.rm = oldrm;
2400 rfmt = l_fmt;
2401 goto copcsr;
2402
2403 default:
2404 if (!NO_R6EMU && MIPSInst_FUNC(ir) >= fcmp_op) {
2405 unsigned int cmpop;
2406 union ieee754dp fs, ft;
2407
2408 cmpop = MIPSInst_FUNC(ir) - fcmp_op;
2409 DPFROMREG(fs, MIPSInst_FS(ir));
2410 DPFROMREG(ft, MIPSInst_FT(ir));
2411 rv.w = ieee754dp_cmp(fs, ft,
2412 cmptab[cmpop & 0x7], cmpop & 0x8);
2413 rfmt = -1;
2414 if ((cmpop & 0x8)
2415 &&
2416 ieee754_cxtest
2417 (IEEE754_INVALID_OPERATION))
2418 rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
2419 else
2420 goto copcsr;
2421
2422 }
2423 else {
2424 return SIGILL;
2425 }
2426 break;
2427 }
2428 break;
2429 }
2430
2431 case w_fmt: {
2432 union ieee754dp fs;
2433
2434 switch (MIPSInst_FUNC(ir)) {
2435 case fcvts_op:
2436
2437 MIPS_FPU_EMU_INC_STATS(cvt_s_w);
2438 SPFROMREG(fs, MIPSInst_FS(ir));
2439 rv.s = ieee754sp_fint(fs.bits);
2440 rfmt = s_fmt;
2441 goto copcsr;
2442 case fcvtd_op:
2443
2444 MIPS_FPU_EMU_INC_STATS(cvt_d_w);
2445 SPFROMREG(fs, MIPSInst_FS(ir));
2446 rv.d = ieee754dp_fint(fs.bits);
2447 rfmt = d_fmt;
2448 goto copcsr;
2449 default: {
2450
2451 #define CMPOP_MASK 0x7
2452 #define SIGN_BIT (0x1 << 3)
2453 #define PREDICATE_BIT (0x1 << 4)
2454
2455 int cmpop = MIPSInst_FUNC(ir) & CMPOP_MASK;
2456 int sig = MIPSInst_FUNC(ir) & SIGN_BIT;
2457 union ieee754sp fs, ft;
2458
2459
2460 if (!cpu_has_mips_r6 ||
2461 (MIPSInst_FUNC(ir) & 0x20))
2462 return SIGILL;
2463
2464 if (!sig) {
2465 if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) {
2466 switch (cmpop) {
2467 case 0:
2468 MIPS_FPU_EMU_INC_STATS(cmp_af_s);
2469 break;
2470 case 1:
2471 MIPS_FPU_EMU_INC_STATS(cmp_un_s);
2472 break;
2473 case 2:
2474 MIPS_FPU_EMU_INC_STATS(cmp_eq_s);
2475 break;
2476 case 3:
2477 MIPS_FPU_EMU_INC_STATS(cmp_ueq_s);
2478 break;
2479 case 4:
2480 MIPS_FPU_EMU_INC_STATS(cmp_lt_s);
2481 break;
2482 case 5:
2483 MIPS_FPU_EMU_INC_STATS(cmp_ult_s);
2484 break;
2485 case 6:
2486 MIPS_FPU_EMU_INC_STATS(cmp_le_s);
2487 break;
2488 case 7:
2489 MIPS_FPU_EMU_INC_STATS(cmp_ule_s);
2490 break;
2491 }
2492 } else {
2493 switch (cmpop) {
2494 case 1:
2495 MIPS_FPU_EMU_INC_STATS(cmp_or_s);
2496 break;
2497 case 2:
2498 MIPS_FPU_EMU_INC_STATS(cmp_une_s);
2499 break;
2500 case 3:
2501 MIPS_FPU_EMU_INC_STATS(cmp_ne_s);
2502 break;
2503 }
2504 }
2505 } else {
2506 if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) {
2507 switch (cmpop) {
2508 case 0:
2509 MIPS_FPU_EMU_INC_STATS(cmp_saf_s);
2510 break;
2511 case 1:
2512 MIPS_FPU_EMU_INC_STATS(cmp_sun_s);
2513 break;
2514 case 2:
2515 MIPS_FPU_EMU_INC_STATS(cmp_seq_s);
2516 break;
2517 case 3:
2518 MIPS_FPU_EMU_INC_STATS(cmp_sueq_s);
2519 break;
2520 case 4:
2521 MIPS_FPU_EMU_INC_STATS(cmp_slt_s);
2522 break;
2523 case 5:
2524 MIPS_FPU_EMU_INC_STATS(cmp_sult_s);
2525 break;
2526 case 6:
2527 MIPS_FPU_EMU_INC_STATS(cmp_sle_s);
2528 break;
2529 case 7:
2530 MIPS_FPU_EMU_INC_STATS(cmp_sule_s);
2531 break;
2532 }
2533 } else {
2534 switch (cmpop) {
2535 case 1:
2536 MIPS_FPU_EMU_INC_STATS(cmp_sor_s);
2537 break;
2538 case 2:
2539 MIPS_FPU_EMU_INC_STATS(cmp_sune_s);
2540 break;
2541 case 3:
2542 MIPS_FPU_EMU_INC_STATS(cmp_sne_s);
2543 break;
2544 }
2545 }
2546 }
2547
2548
2549 rfmt = s_fmt;
2550
2551 rv.w = 0;
2552
2553
2554 SPFROMREG(fs, MIPSInst_FS(ir));
2555 SPFROMREG(ft, MIPSInst_FT(ir));
2556
2557
2558 if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) {
2559 if (ieee754sp_cmp(fs, ft, cmptab[cmpop],
2560 sig))
2561 rv.w = -1;
2562 if ((sig) &&
2563 ieee754_cxtest(IEEE754_INVALID_OPERATION))
2564 rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
2565 else
2566 goto copcsr;
2567 } else {
2568
2569 switch (cmpop) {
2570 case 1:
2571 case 2:
2572 case 3:
2573 if (ieee754sp_cmp(fs, ft,
2574 negative_cmptab[cmpop],
2575 sig))
2576 rv.w = -1;
2577 if (sig &&
2578 ieee754_cxtest(IEEE754_INVALID_OPERATION))
2579 rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
2580 else
2581 goto copcsr;
2582 break;
2583 default:
2584
2585 return SIGILL;
2586 }
2587 }
2588 break;
2589 }
2590 }
2591 break;
2592 }
2593
2594 case l_fmt:
2595
2596 if (!cpu_has_mips_3_4_5_64_r2_r6)
2597 return SIGILL;
2598
2599 DIFROMREG(bits, MIPSInst_FS(ir));
2600
2601 switch (MIPSInst_FUNC(ir)) {
2602 case fcvts_op:
2603
2604 MIPS_FPU_EMU_INC_STATS(cvt_s_l);
2605 rv.s = ieee754sp_flong(bits);
2606 rfmt = s_fmt;
2607 goto copcsr;
2608 case fcvtd_op:
2609
2610 MIPS_FPU_EMU_INC_STATS(cvt_d_l);
2611 rv.d = ieee754dp_flong(bits);
2612 rfmt = d_fmt;
2613 goto copcsr;
2614 default: {
2615
2616 int cmpop = MIPSInst_FUNC(ir) & CMPOP_MASK;
2617 int sig = MIPSInst_FUNC(ir) & SIGN_BIT;
2618 union ieee754dp fs, ft;
2619
2620 if (!cpu_has_mips_r6 ||
2621 (MIPSInst_FUNC(ir) & 0x20))
2622 return SIGILL;
2623
2624 if (!sig) {
2625 if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) {
2626 switch (cmpop) {
2627 case 0:
2628 MIPS_FPU_EMU_INC_STATS(cmp_af_d);
2629 break;
2630 case 1:
2631 MIPS_FPU_EMU_INC_STATS(cmp_un_d);
2632 break;
2633 case 2:
2634 MIPS_FPU_EMU_INC_STATS(cmp_eq_d);
2635 break;
2636 case 3:
2637 MIPS_FPU_EMU_INC_STATS(cmp_ueq_d);
2638 break;
2639 case 4:
2640 MIPS_FPU_EMU_INC_STATS(cmp_lt_d);
2641 break;
2642 case 5:
2643 MIPS_FPU_EMU_INC_STATS(cmp_ult_d);
2644 break;
2645 case 6:
2646 MIPS_FPU_EMU_INC_STATS(cmp_le_d);
2647 break;
2648 case 7:
2649 MIPS_FPU_EMU_INC_STATS(cmp_ule_d);
2650 break;
2651 }
2652 } else {
2653 switch (cmpop) {
2654 case 1:
2655 MIPS_FPU_EMU_INC_STATS(cmp_or_d);
2656 break;
2657 case 2:
2658 MIPS_FPU_EMU_INC_STATS(cmp_une_d);
2659 break;
2660 case 3:
2661 MIPS_FPU_EMU_INC_STATS(cmp_ne_d);
2662 break;
2663 }
2664 }
2665 } else {
2666 if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) {
2667 switch (cmpop) {
2668 case 0:
2669 MIPS_FPU_EMU_INC_STATS(cmp_saf_d);
2670 break;
2671 case 1:
2672 MIPS_FPU_EMU_INC_STATS(cmp_sun_d);
2673 break;
2674 case 2:
2675 MIPS_FPU_EMU_INC_STATS(cmp_seq_d);
2676 break;
2677 case 3:
2678 MIPS_FPU_EMU_INC_STATS(cmp_sueq_d);
2679 break;
2680 case 4:
2681 MIPS_FPU_EMU_INC_STATS(cmp_slt_d);
2682 break;
2683 case 5:
2684 MIPS_FPU_EMU_INC_STATS(cmp_sult_d);
2685 break;
2686 case 6:
2687 MIPS_FPU_EMU_INC_STATS(cmp_sle_d);
2688 break;
2689 case 7:
2690 MIPS_FPU_EMU_INC_STATS(cmp_sule_d);
2691 break;
2692 }
2693 } else {
2694 switch (cmpop) {
2695 case 1:
2696 MIPS_FPU_EMU_INC_STATS(cmp_sor_d);
2697 break;
2698 case 2:
2699 MIPS_FPU_EMU_INC_STATS(cmp_sune_d);
2700 break;
2701 case 3:
2702 MIPS_FPU_EMU_INC_STATS(cmp_sne_d);
2703 break;
2704 }
2705 }
2706 }
2707
2708
2709 rfmt = d_fmt;
2710
2711 rv.l = 0;
2712
2713
2714 DPFROMREG(fs, MIPSInst_FS(ir));
2715 DPFROMREG(ft, MIPSInst_FT(ir));
2716
2717
2718 if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) {
2719 if (ieee754dp_cmp(fs, ft,
2720 cmptab[cmpop], sig))
2721 rv.l = -1LL;
2722 if (sig &&
2723 ieee754_cxtest(IEEE754_INVALID_OPERATION))
2724 rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
2725 else
2726 goto copcsr;
2727 } else {
2728
2729 switch (cmpop) {
2730 case 1:
2731 case 2:
2732 case 3:
2733 if (ieee754dp_cmp(fs, ft,
2734 negative_cmptab[cmpop],
2735 sig))
2736 rv.l = -1LL;
2737 if (sig &&
2738 ieee754_cxtest(IEEE754_INVALID_OPERATION))
2739 rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
2740 else
2741 goto copcsr;
2742 break;
2743 default:
2744
2745 return SIGILL;
2746 }
2747 }
2748 break;
2749 }
2750 }
2751 break;
2752
2753 default:
2754 return SIGILL;
2755 }
2756
2757
2758
2759
2760
2761
2762
2763
2764 ctx->fcr31 = (ctx->fcr31 & ~FPU_CSR_ALL_X) | rcsr;
2765 if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
2766
2767 return SIGFPE;
2768 }
2769
2770
2771
2772
2773 switch (rfmt) {
2774 case -1:
2775
2776 if (cpu_has_mips_4_5_r)
2777 cbit = fpucondbit[MIPSInst_FD(ir) >> 2];
2778 else
2779 cbit = FPU_CSR_COND;
2780 if (rv.w)
2781 ctx->fcr31 |= cbit;
2782 else
2783 ctx->fcr31 &= ~cbit;
2784 break;
2785
2786 case d_fmt:
2787 DPTOREG(rv.d, MIPSInst_FD(ir));
2788 break;
2789 case s_fmt:
2790 SPTOREG(rv.s, MIPSInst_FD(ir));
2791 break;
2792 case w_fmt:
2793 SITOREG(rv.w, MIPSInst_FD(ir));
2794 break;
2795 case l_fmt:
2796 if (!cpu_has_mips_3_4_5_64_r2_r6)
2797 return SIGILL;
2798
2799 DITOREG(rv.l, MIPSInst_FD(ir));
2800 break;
2801 default:
2802 return SIGILL;
2803 }
2804
2805 return 0;
2806 }
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837 int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
2838 int has_fpu, void __user **fault_addr)
2839 {
2840 unsigned long oldepc, prevepc;
2841 struct mm_decoded_insn dec_insn;
2842 u16 instr[4];
2843 u16 *instr_ptr;
2844 int sig = 0;
2845
2846
2847
2848
2849
2850 if (!init_fp_ctx(current))
2851 lose_fpu(1);
2852
2853 oldepc = xcp->cp0_epc;
2854 do {
2855 prevepc = xcp->cp0_epc;
2856
2857 if (get_isa16_mode(prevepc) && cpu_has_mmips) {
2858
2859
2860
2861
2862 if ((get_user(instr[0], (u16 __user *)msk_isa16_mode(xcp->cp0_epc))) ||
2863 (get_user(instr[1], (u16 __user *)msk_isa16_mode(xcp->cp0_epc + 2))) ||
2864 (get_user(instr[2], (u16 __user *)msk_isa16_mode(xcp->cp0_epc + 4))) ||
2865 (get_user(instr[3], (u16 __user *)msk_isa16_mode(xcp->cp0_epc + 6)))) {
2866 MIPS_FPU_EMU_INC_STATS(errors);
2867 return SIGBUS;
2868 }
2869 instr_ptr = instr;
2870
2871
2872 if (mm_insn_16bit(*instr_ptr)) {
2873
2874 dec_insn.insn = (*instr_ptr << 16) |
2875 (*instr_ptr);
2876
2877 dec_insn.pc_inc = 2;
2878 instr_ptr += 1;
2879 } else {
2880 dec_insn.insn = (*instr_ptr << 16) |
2881 *(instr_ptr+1);
2882
2883 dec_insn.pc_inc = 4;
2884 instr_ptr += 2;
2885 }
2886
2887 if (mm_insn_16bit(*instr_ptr)) {
2888
2889 dec_insn.next_insn = (*instr_ptr << 16) |
2890 (*instr_ptr);
2891
2892 dec_insn.next_pc_inc = 2;
2893 } else {
2894 dec_insn.next_insn = (*instr_ptr << 16) |
2895 *(instr_ptr+1);
2896
2897 dec_insn.next_pc_inc = 4;
2898 }
2899 dec_insn.micro_mips_mode = 1;
2900 } else {
2901 if ((get_user(dec_insn.insn,
2902 (mips_instruction __user *) xcp->cp0_epc)) ||
2903 (get_user(dec_insn.next_insn,
2904 (mips_instruction __user *)(xcp->cp0_epc+4)))) {
2905 MIPS_FPU_EMU_INC_STATS(errors);
2906 return SIGBUS;
2907 }
2908 dec_insn.pc_inc = 4;
2909 dec_insn.next_pc_inc = 4;
2910 dec_insn.micro_mips_mode = 0;
2911 }
2912
2913 if ((dec_insn.insn == 0) ||
2914 ((dec_insn.pc_inc == 2) &&
2915 ((dec_insn.insn & 0xffff) == MM_NOP16)))
2916 xcp->cp0_epc += dec_insn.pc_inc;
2917 else {
2918
2919
2920
2921
2922 sig = cop1Emulate(xcp, ctx, dec_insn, fault_addr);
2923 }
2924
2925 if (has_fpu)
2926 break;
2927 if (sig)
2928 break;
2929
2930
2931
2932
2933
2934
2935
2936 if ((xcp->cp0_epc ^ prevepc) & 0x1)
2937 break;
2938
2939 cond_resched();
2940 } while (xcp->cp0_epc > prevepc);
2941
2942
2943 if (sig == SIGILL && xcp->cp0_epc != oldepc)
2944
2945 sig = 0;
2946
2947 return sig;
2948 }