1/* 2 * cp1emu.c: a MIPS coprocessor 1 (fpu) instruction emulator 3 * 4 * MIPS floating point support 5 * Copyright (C) 1994-2000 Algorithmics Ltd. 6 * http://www.algor.co.uk 7 * 8 * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com 9 * Copyright (C) 2000 MIPS Technologies, Inc. 10 * 11 * This program is free software; you can distribute it and/or modify it 12 * under the terms of the GNU General Public License (Version 2) as 13 * published by the Free Software Foundation. 14 * 15 * This program is distributed in the hope it will be useful, but WITHOUT 16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 18 * for more details. 19 * 20 * You should have received a copy of the GNU General Public License along 21 * with this program; if not, write to the Free Software Foundation, Inc., 22 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. 23 * 24 * A complete emulator for MIPS coprocessor 1 instructions. This is 25 * required for #float(switch) or #float(trap), where it catches all 26 * COP1 instructions via the "CoProcessor Unusable" exception. 27 * 28 * More surprisingly it is also required for #float(ieee), to help out 29 * the hardware fpu at the boundaries of the IEEE-754 representation 30 * (denormalised values, infinities, underflow, etc). It is made 31 * quite nasty because emulation of some non-COP1 instructions is 32 * required, e.g. in branch delay slots. 33 * 34 * Note if you know that you won't have an fpu, then you'll get much 35 * better performance by compiling with -msoft-float! 36 */ 37#include <linux/sched.h> 38#include <linux/module.h> 39#include <linux/debugfs.h> 40 41#include <asm/inst.h> 42#include <asm/bootinfo.h> 43#include <asm/processor.h> 44#include <asm/ptrace.h> 45#include <asm/signal.h> 46#include <asm/mipsregs.h> 47#include <asm/fpu_emulator.h> 48#include <asm/fpu.h> 49#include <asm/uaccess.h> 50#include <asm/branch.h> 51 52#include "ieee754.h" 53 54/* Strap kernel emulator for full MIPS IV emulation */ 55 56#ifdef __mips 57#undef __mips 58#endif 59#define __mips 4 60 61/* Function which emulates a floating point instruction. */ 62 63static int fpu_emu(struct pt_regs *, struct mips_fpu_struct *, 64 mips_instruction); 65 66#if __mips >= 4 && __mips != 32 67static int fpux_emu(struct pt_regs *, 68 struct mips_fpu_struct *, mips_instruction, void *__user *); 69#endif 70 71/* Further private data for which no space exists in mips_fpu_struct */ 72 73#ifdef CONFIG_DEBUG_FS 74DEFINE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats); 75#endif 76 77/* Control registers */ 78 79#define FPCREG_RID 0 /* $0 = revision id */ 80#define FPCREG_CSR 31 /* $31 = csr */ 81 82/* Determine rounding mode from the RM bits of the FCSR */ 83#define modeindex(v) ((v) & FPU_CSR_RM) 84 85/* Convert Mips rounding mode (0..3) to IEEE library modes. */ 86static const unsigned char ieee_rm[4] = { 87 [FPU_CSR_RN] = IEEE754_RN, 88 [FPU_CSR_RZ] = IEEE754_RZ, 89 [FPU_CSR_RU] = IEEE754_RU, 90 [FPU_CSR_RD] = IEEE754_RD, 91}; 92/* Convert IEEE library modes to Mips rounding mode (0..3). */ 93static const unsigned char mips_rm[4] = { 94 [IEEE754_RN] = FPU_CSR_RN, 95 [IEEE754_RZ] = FPU_CSR_RZ, 96 [IEEE754_RD] = FPU_CSR_RD, 97 [IEEE754_RU] = FPU_CSR_RU, 98}; 99 100#if __mips >= 4 101/* convert condition code register number to csr bit */ 102static const unsigned int fpucondbit[8] = { 103 FPU_CSR_COND0, 104 FPU_CSR_COND1, 105 FPU_CSR_COND2, 106 FPU_CSR_COND3, 107 FPU_CSR_COND4, 108 FPU_CSR_COND5, 109 FPU_CSR_COND6, 110 FPU_CSR_COND7 111}; 112#endif 113 114/* convert 16-bit register encoding to 32-bit register encoding */ 115static const unsigned int reg16to32map[8] = {16, 17, 2, 3, 4, 5, 6, 7}; 116 117/* convert micro_mips to mips32 format */ 118static const int sd_format[] = {16, 17, 0, 0, 0, 0, 0, 0}; 119static const int sdps_format[] = {16, 17, 22, 0, 0, 0, 0, 0}; 120static const int dwl_format[] = {17, 20, 21, 0, 0, 0, 0, 0}; 121static const int swl_format[] = {16, 20, 21, 0, 0, 0, 0, 0}; 122 123/* 124 * This functions translates a 32 bit micro_mips instr into a 32 bit mips32 instr. 125 * It return 0 or SIGILL. 126 */ 127static int micro_mips32_to_mips32(union mips_instruction *insn_ptr) 128{ 129 union mips_instruction insn = *insn_ptr; 130 union mips_instruction mips32_insn = insn; /* assume they are the same */ 131 int func; 132 int fmt; 133 int op; 134 135 switch (insn.mm_i_format.opcode) { 136 case mm_ldc132_op: 137 mips32_insn.mm_i_format.opcode = ldc1_op; 138 mips32_insn.mm_i_format.rt = insn.mm_i_format.rs; 139 mips32_insn.mm_i_format.rs = insn.mm_i_format.rt; 140 break; 141 case mm_lwc132_op: 142 mips32_insn.mm_i_format.opcode = lwc1_op; 143 mips32_insn.mm_i_format.rt = insn.mm_i_format.rs; 144 mips32_insn.mm_i_format.rs = insn.mm_i_format.rt; 145 break; 146 case mm_sdc132_op: 147 mips32_insn.mm_i_format.opcode = sdc1_op; 148 mips32_insn.mm_i_format.rt = insn.mm_i_format.rs; 149 mips32_insn.mm_i_format.rs = insn.mm_i_format.rt; 150 break; 151 case mm_swc132_op: 152 mips32_insn.mm_i_format.opcode = swc1_op; 153 mips32_insn.mm_i_format.rt = insn.mm_i_format.rs; 154 mips32_insn.mm_i_format.rs = insn.mm_i_format.rt; 155 break; 156 case mm_pool32i_op: 157 /* NOTE: offset is << by 1 if in micro_mips mode */ 158 if ((insn.mm_i_format.rt == mm_bc1f_op) || (insn.mm_i_format.rt == mm_bc1t_op)) { 159 mips32_insn.fb_format.opcode = cop1_op; 160 mips32_insn.fb_format.bc = bc_op; 161 mips32_insn.fb_format.flag = (insn.mm_i_format.rt == mm_bc1t_op) ? 1 : 0; 162 } else 163 return SIGILL; 164 break; 165 case mm_pool32f_op: 166 switch (insn.mm_fp0_format.func) { 167 case mm_32f_01_op: 168 case mm_32f_11_op: 169 case mm_32f_02_op: 170 case mm_32f_12_op: 171 case mm_32f_41_op: 172 case mm_32f_51_op: 173 case mm_32f_42_op: 174 case mm_32f_52_op: 175 op = insn.mm_fp0_format.func; 176 if (op == mm_32f_01_op) 177 func = madd_s_op; 178 else if (op == mm_32f_11_op) 179 func = madd_d_op; 180 else if (op == mm_32f_02_op) 181 func = nmadd_s_op; 182 else if (op == mm_32f_12_op) 183 func = nmadd_d_op; 184 else if (op == mm_32f_41_op) 185 func = msub_s_op; 186 else if (op == mm_32f_51_op) 187 func = msub_d_op; 188 else if (op == mm_32f_42_op) 189 func = nmsub_s_op; 190 else 191 func = nmsub_d_op; 192 mips32_insn.fp6_format.opcode = cop1x_op; 193 mips32_insn.fp6_format.fr = insn.mm_fp6_format.fr; 194 mips32_insn.fp6_format.ft = insn.mm_fp6_format.ft; 195 mips32_insn.fp6_format.fs = insn.mm_fp6_format.fs; 196 mips32_insn.fp6_format.fd = insn.mm_fp6_format.fd; 197 mips32_insn.fp6_format.func = func; 198 break; 199 case mm_32f_10_op: 200 func = -1; /* set to invalid value */ 201 op = insn.mm_fp5_format.op & 0x7; 202 if (op == mm_ldxc1_op) 203 func = ldxc1_op; 204 else if (op == mm_sdxc1_op) 205 func = sdxc1_op; 206 else if (op == mm_lwxc1_op) 207 func = lwxc1_op; 208 else if (op == mm_swxc1_op) 209 func = swxc1_op; 210 211 if (func != -1) { 212 mips32_insn.r_format.opcode = cop1x_op; 213 mips32_insn.r_format.rs = insn.mm_fp5_format.base; 214 mips32_insn.r_format.rt = insn.mm_fp5_format.index; 215 mips32_insn.r_format.rd = 0; 216 mips32_insn.r_format.re = insn.mm_fp5_format.fd; 217 mips32_insn.r_format.func = func; 218 } else 219 return SIGILL; 220 break; 221 case mm_32f_40_op: 222 op = -1; /* set to invalid value */ 223 if (insn.mm_fp2_format.op == mm_fmovt_op) 224 op = 1; 225 else if (insn.mm_fp2_format.op == mm_fmovf_op) 226 op = 0; 227 if (op != -1) { 228 mips32_insn.fp0_format.opcode = cop1_op; 229 mips32_insn.fp0_format.fmt = sdps_format[insn.mm_fp2_format.fmt]; 230 mips32_insn.fp0_format.ft = (insn.mm_fp2_format.cc<<2) + op; 231 mips32_insn.fp0_format.fs = insn.mm_fp2_format.fs; 232 mips32_insn.fp0_format.fd = insn.mm_fp2_format.fd; 233 mips32_insn.fp0_format.func = fmovc_op; 234 } else 235 return SIGILL; 236 break; 237 case mm_32f_60_op: 238 func = -1; /* set to invalid value */ 239 if (insn.mm_fp0_format.op == mm_fadd_op) 240 func = fadd_op; 241 else if (insn.mm_fp0_format.op == mm_fsub_op) 242 func = fsub_op; 243 else if (insn.mm_fp0_format.op == mm_fmul_op) 244 func = fmul_op; 245 else if (insn.mm_fp0_format.op == mm_fdiv_op) 246 func = fdiv_op; 247 if (func != -1) { 248 mips32_insn.fp0_format.opcode = cop1_op; 249 mips32_insn.fp0_format.fmt = sdps_format[insn.mm_fp0_format.fmt]; 250 mips32_insn.fp0_format.ft = insn.mm_fp0_format.ft; 251 mips32_insn.fp0_format.fs = insn.mm_fp0_format.fs; 252 mips32_insn.fp0_format.fd = insn.mm_fp0_format.fd; 253 mips32_insn.fp0_format.func = func; 254 } else 255 return SIGILL; 256 break; 257 case mm_32f_70_op: 258 func = -1; /* set to invalid value */ 259 if (insn.mm_fp0_format.op == mm_fmovn_op) 260 func = fmovn_op; 261 else if (insn.mm_fp0_format.op == mm_fmovz_op) 262 func = fmovz_op; 263 if (func != -1) { 264 mips32_insn.fp0_format.opcode = cop1_op; 265 mips32_insn.fp0_format.fmt = sdps_format[insn.mm_fp0_format.fmt]; 266 mips32_insn.fp0_format.ft = insn.mm_fp0_format.ft; 267 mips32_insn.fp0_format.fs = insn.mm_fp0_format.fs; 268 mips32_insn.fp0_format.fd = insn.mm_fp0_format.fd; 269 mips32_insn.fp0_format.func = func; 270 } else 271 return SIGILL; 272 break; 273 case mm_32f_73_op: /* POOL32FXF */ 274 switch (insn.mm_fp1_format.op) { 275 case mm_movf0_op: 276 case mm_movf1_op: 277 case mm_movt0_op: 278 case mm_movt1_op: 279 if ((insn.mm_fp1_format.op & 0x7f) == mm_movf0_op) 280 op = 0; 281 else 282 op = 1; 283 mips32_insn.r_format.opcode = spec_op; 284 mips32_insn.r_format.rs = insn.mm_fp4_format.fs; 285 mips32_insn.r_format.rt = (insn.mm_fp4_format.cc<<2) + op; 286 mips32_insn.r_format.rd = insn.mm_fp4_format.rt; 287 mips32_insn.r_format.re = 0; 288 mips32_insn.r_format.func = movc_op; 289 break; 290 case mm_fcvtd0_op: 291 case mm_fcvtd1_op: 292 case mm_fcvts0_op: 293 case mm_fcvts1_op: 294 if ((insn.mm_fp1_format.op & 0x7f) == mm_fcvtd0_op) { 295 func = fcvtd_op; 296 fmt = swl_format[insn.mm_fp3_format.fmt]; 297 } else { 298 func = fcvts_op; 299 fmt = dwl_format[insn.mm_fp3_format.fmt]; 300 } 301 mips32_insn.fp0_format.opcode = cop1_op; 302 mips32_insn.fp0_format.fmt = fmt; 303 mips32_insn.fp0_format.ft = 0; 304 mips32_insn.fp0_format.fs = insn.mm_fp3_format.fs; 305 mips32_insn.fp0_format.fd = insn.mm_fp3_format.rt; 306 mips32_insn.fp0_format.func = func; 307 break; 308 case mm_fmov0_op: 309 case mm_fmov1_op: 310 case mm_fabs0_op: 311 case mm_fabs1_op: 312 case mm_fneg0_op: 313 case mm_fneg1_op: 314 if ((insn.mm_fp1_format.op & 0x7f) == mm_fmov0_op) 315 func = fmov_op; 316 else if ((insn.mm_fp1_format.op & 0x7f) == mm_fabs0_op) 317 func = fabs_op; 318 else 319 func = fneg_op; 320 mips32_insn.fp0_format.opcode = cop1_op; 321 mips32_insn.fp0_format.fmt = sdps_format[insn.mm_fp3_format.fmt]; 322 mips32_insn.fp0_format.ft = 0; 323 mips32_insn.fp0_format.fs = insn.mm_fp3_format.fs; 324 mips32_insn.fp0_format.fd = insn.mm_fp3_format.rt; 325 mips32_insn.fp0_format.func = func; 326 break; 327 case mm_ffloorl_op: 328 case mm_ffloorw_op: 329 case mm_fceill_op: 330 case mm_fceilw_op: 331 case mm_ftruncl_op: 332 case mm_ftruncw_op: 333 case mm_froundl_op: 334 case mm_froundw_op: 335 case mm_fcvtl_op: 336 case mm_fcvtw_op: 337 if (insn.mm_fp1_format.op == mm_ffloorl_op) 338 func = ffloorl_op; 339 else if (insn.mm_fp1_format.op == mm_ffloorw_op) 340 func = ffloor_op; 341 else if (insn.mm_fp1_format.op == mm_fceill_op) 342 func = fceill_op; 343 else if (insn.mm_fp1_format.op == mm_fceilw_op) 344 func = fceil_op; 345 else if (insn.mm_fp1_format.op == mm_ftruncl_op) 346 func = ftruncl_op; 347 else if (insn.mm_fp1_format.op == mm_ftruncw_op) 348 func = ftrunc_op; 349 else if (insn.mm_fp1_format.op == mm_froundl_op) 350 func = froundl_op; 351 else if (insn.mm_fp1_format.op == mm_froundw_op) 352 func = fround_op; 353 else if (insn.mm_fp1_format.op == mm_fcvtl_op) 354 func = fcvtl_op; 355 else 356 func = fcvtw_op; 357 mips32_insn.fp0_format.opcode = cop1_op; 358 mips32_insn.fp0_format.fmt = sd_format[insn.mm_fp1_format.fmt]; 359 mips32_insn.fp0_format.ft = 0; 360 mips32_insn.fp0_format.fs = insn.mm_fp1_format.fs; 361 mips32_insn.fp0_format.fd = insn.mm_fp1_format.rt; 362 mips32_insn.fp0_format.func = func; 363 break; 364 case mm_frsqrt_op: 365 case mm_fsqrt_op: 366 case mm_frecip_op: 367 if (insn.mm_fp1_format.op == mm_frsqrt_op) 368 func = frsqrt_op; 369 else if (insn.mm_fp1_format.op == mm_fsqrt_op) 370 func = fsqrt_op; 371 else 372 func = frecip_op; 373 mips32_insn.fp0_format.opcode = cop1_op; 374 mips32_insn.fp0_format.fmt = sdps_format[insn.mm_fp1_format.fmt]; 375 mips32_insn.fp0_format.ft = 0; 376 mips32_insn.fp0_format.fs = insn.mm_fp1_format.fs; 377 mips32_insn.fp0_format.fd = insn.mm_fp1_format.rt; 378 mips32_insn.fp0_format.func = func; 379 break; 380 case mm_mfc1_op: 381 case mm_mtc1_op: 382 case mm_cfc1_op: 383 case mm_ctc1_op: 384 if (insn.mm_fp1_format.op == mm_mfc1_op) 385 op = mfc_op; 386 else if (insn.mm_fp1_format.op == mm_mtc1_op) 387 op = mtc_op; 388 else if (insn.mm_fp1_format.op == mm_cfc1_op) 389 op = cfc_op; 390 else 391 op = ctc_op; 392 mips32_insn.fp1_format.opcode = cop1_op; 393 mips32_insn.fp1_format.op = op; 394 mips32_insn.fp1_format.rt = insn.mm_fp1_format.rt; 395 mips32_insn.fp1_format.fs = insn.mm_fp1_format.fs; 396 mips32_insn.fp1_format.fd = 0; 397 mips32_insn.fp1_format.func = 0; 398 break; 399 default: 400 return SIGILL; 401 break; 402 } 403 break; 404 case mm_32f_74_op: /* c.cond.fmt */ 405 mips32_insn.fp0_format.opcode = cop1_op; 406 mips32_insn.fp0_format.fmt = sdps_format[insn.mm_fp4_format.fmt]; 407 mips32_insn.fp0_format.ft = insn.mm_fp4_format.rt; 408 mips32_insn.fp0_format.fs = insn.mm_fp4_format.fs; 409 mips32_insn.fp0_format.fd = insn.mm_fp4_format.cc<<2; 410 mips32_insn.fp0_format.func = insn.mm_fp4_format.cond | MIPS32_COND_FC; 411 break; 412 default: 413 return SIGILL; 414 break; 415 } 416 break; 417 default: 418 return SIGILL; 419 break; 420 } 421 422 *insn_ptr = mips32_insn; 423 return 0; 424} 425 426/* micro_mips version of isBranchInstr() */ 427int mm_isBranchInstr(struct pt_regs *regs, struct decoded_instn dec_insn, 428 unsigned long *contpc) 429{ 430 union mips_instruction insn = (union mips_instruction)dec_insn.insn; 431 int bc_false = 0; 432 unsigned int fcr31; 433 unsigned int bit; 434 435 /* NOTE: for 16-bit instructions, they are duplicated and stored as a 32-bit value. */ 436 switch (insn.mm_i_format.opcode) { 437 case mm_pool32a_op: 438 if ((insn.mm_i_format.simmediate & MM_POOL32A_MINOR_MSK) == mm_pool32axf_op) { 439 switch (insn.mm_i_format.simmediate >> MM_POOL32A_MINOR_SFT) { 440 case mm_jalr_op: 441 case mm_jalrhb_op: 442 case mm_jalrs_op: 443 case mm_jalrshb_op: 444 if (insn.mm_i_format.rt != 0) /* not a mm_jr_op */ 445 regs->regs[insn.mm_i_format.rt] = regs->cp0_epc + dec_insn.pc_inc + dec_insn.next_pc_inc; 446 *contpc = regs->regs[insn.mm_i_format.rs]; 447 return 1; 448 break; 449 } 450 } 451 break; 452 case mm_pool32i_op: 453 switch (insn.mm_i_format.rt) { 454 case mm_bltzals_op: 455 case mm_bltzal_op: 456 regs->regs[31] = regs->cp0_epc + dec_insn.pc_inc + dec_insn.next_pc_inc; 457 /* Fall through */ 458 case mm_bltz_op: 459 if ((long)regs->regs[insn.mm_i_format.rs] < 0) 460 *contpc = regs->cp0_epc + dec_insn.pc_inc + (insn.mm_i_format.simmediate << 1); 461 else 462 *contpc = regs->cp0_epc + dec_insn.pc_inc + dec_insn.next_pc_inc; 463 return 1; 464 break; 465 case mm_bgezals_op: 466 case mm_bgezal_op: 467 regs->regs[31] = regs->cp0_epc + dec_insn.pc_inc + dec_insn.next_pc_inc; 468 /* Fall through */ 469 case mm_bgez_op: 470 if ((long)regs->regs[insn.mm_i_format.rs] >= 0) 471 *contpc = regs->cp0_epc + dec_insn.pc_inc + (insn.mm_i_format.simmediate << 1); 472 else 473 *contpc = regs->cp0_epc + dec_insn.pc_inc + dec_insn.next_pc_inc; 474 return 1; 475 break; 476 case mm_blez_op: 477 if ((long)regs->regs[insn.mm_i_format.rs] <= 0) 478 *contpc = regs->cp0_epc + dec_insn.pc_inc + (insn.mm_i_format.simmediate << 1); 479 else 480 *contpc = regs->cp0_epc + dec_insn.pc_inc + dec_insn.next_pc_inc; 481 return 1; 482 break; 483 case mm_bgtz_op: 484 if ((long)regs->regs[insn.mm_i_format.rs] <= 0) 485 *contpc = regs->cp0_epc + dec_insn.pc_inc + (insn.mm_i_format.simmediate << 1); 486 else 487 *contpc = regs->cp0_epc + dec_insn.pc_inc + dec_insn.next_pc_inc; 488 return 1; 489 break; 490 case mm_bc2f_op: 491 case mm_bc1f_op: 492 bc_false = 1; 493 /* Fall through */ 494 case mm_bc2t_op: 495 case mm_bc1t_op: 496 preempt_disable(); 497 if (is_fpu_owner()) 498 asm volatile("cfc1\t%0,$31" : "=r" (fcr31)); 499 else 500 fcr31 = current->thread.fpu.fcr31; 501 preempt_enable(); 502 503 if (bc_false) 504 fcr31 = ~fcr31; 505 506 bit = (insn.mm_i_format.rs >> 2); 507 bit += (bit != 0); 508 bit += 23; 509 if (fcr31 & (1 << bit)) 510 *contpc = regs->cp0_epc + dec_insn.pc_inc + (insn.mm_i_format.simmediate << 1); 511 else 512 *contpc = regs->cp0_epc + dec_insn.pc_inc + dec_insn.next_pc_inc; 513 return 1; 514 break; 515 } 516 break; 517 case mm_pool16c_op: 518 switch (insn.mm_i_format.rt) { 519 case mm_jalr16_op: 520 case mm_jalrs16_op: 521 regs->regs[31] = regs->cp0_epc + dec_insn.pc_inc + dec_insn.next_pc_inc; 522 /* Fall through */ 523 case mm_jr16_op: 524 *contpc = regs->regs[insn.mm_i_format.rs]; 525 return 1; 526 break; 527 } 528 break; 529 case mm_beqz16_op: 530 if ((long)regs->regs[reg16to32map[insn.mm16b1_format.rs]] == 0) 531 *contpc = regs->cp0_epc + dec_insn.pc_inc + (insn.mm16b1_format.simmediate << 1); 532 else 533 *contpc = regs->cp0_epc + dec_insn.pc_inc + dec_insn.next_pc_inc; 534 return 1; 535 break; 536 case mm_bnez16_op: 537 if ((long)regs->regs[reg16to32map[insn.mm16b1_format.rs]] != 0) 538 *contpc = regs->cp0_epc + dec_insn.pc_inc + (insn.mm16b1_format.simmediate << 1); 539 else 540 *contpc = regs->cp0_epc + dec_insn.pc_inc + dec_insn.next_pc_inc; 541 return 1; 542 break; 543 case mm_b16_op: 544 *contpc = regs->cp0_epc + dec_insn.pc_inc + (insn.mm16b0_format.simmediate << 1); 545 return 1; 546 break; 547 case mm_beq32_op: 548 if (regs->regs[insn.mm_i_format.rs] == regs->regs[insn.mm_i_format.rt]) 549 *contpc = regs->cp0_epc + dec_insn.pc_inc + (insn.mm_i_format.simmediate << 1); 550 else 551 *contpc = regs->cp0_epc + dec_insn.pc_inc + dec_insn.next_pc_inc; 552 return 1; 553 break; 554 case mm_bne32_op: 555 if (regs->regs[insn.mm_i_format.rs] != regs->regs[insn.mm_i_format.rt]) 556 *contpc = regs->cp0_epc + dec_insn.pc_inc + (insn.mm_i_format.simmediate << 1); 557 else 558 *contpc = regs->cp0_epc + dec_insn.pc_inc + dec_insn.next_pc_inc; 559 return 1; 560 break; 561 case mm_jalx32_op: 562 regs->regs[31] = regs->cp0_epc + dec_insn.pc_inc + 563 dec_insn.next_pc_inc; 564 *contpc = regs->cp0_epc + dec_insn.pc_inc; 565 *contpc >>= 28; 566 *contpc <<= 28; 567 *contpc |= (insn.j_format.target << 2); 568 return 1; 569 break; 570 case mm_jals32_op: 571 case mm_jal32_op: 572 regs->regs[31] = regs->cp0_epc + dec_insn.pc_inc + dec_insn.next_pc_inc; 573 /* Fall through */ 574 case mm_j32_op: 575 *contpc = regs->cp0_epc + dec_insn.pc_inc; 576 *contpc >>= 27; 577 *contpc <<= 27; 578 *contpc |= (insn.j_format.target << 1); 579 *contpc |= MIPS_ISA_MODE; 580 return 1; 581 break; 582 } 583 return 0; 584} 585 586/* 587 * Redundant with logic already in kernel/branch.c, 588 * embedded in compute_return_epc. At some point, 589 * a single subroutine should be used across both 590 * modules. 591 */ 592static int isBranchInstr(struct pt_regs *regs, struct decoded_instn dec_insn, unsigned long *contpc) 593{ 594 union mips_instruction insn = (union mips_instruction)dec_insn.insn; 595 unsigned int fcr31; 596 unsigned int bit = 0; 597 598 switch (insn.i_format.opcode) { 599 case spec_op: 600 switch (insn.r_format.func) { 601 case jalr_op: 602 regs->regs[insn.r_format.rd] = regs->cp0_epc + dec_insn.pc_inc + dec_insn.next_pc_inc; 603 /* Fall through */ 604 case jr_op: 605 *contpc = regs->regs[insn.r_format.rs]; 606 return 1; 607 break; 608 } 609 break; 610 case bcond_op: 611 switch (insn.i_format.rt) { 612 case bltzal_op: 613 case bltzall_op: 614 regs->regs[31] = regs->cp0_epc + dec_insn.pc_inc + dec_insn.next_pc_inc; 615 /* Fall through */ 616 case bltz_op: 617 case bltzl_op: 618 if ((long)regs->regs[insn.i_format.rs] < 0) 619 *contpc = regs->cp0_epc + dec_insn.pc_inc + (insn.i_format.simmediate << 2); 620 else 621 *contpc = regs->cp0_epc + dec_insn.pc_inc + dec_insn.next_pc_inc; 622 return 1; 623 break; 624 case bgezal_op: 625 case bgezall_op: 626 regs->regs[31] = regs->cp0_epc + dec_insn.pc_inc + dec_insn.next_pc_inc; 627 /* Fall through */ 628 case bgez_op: 629 case bgezl_op: 630 if ((long)regs->regs[insn.i_format.rs] >= 0) 631 *contpc = regs->cp0_epc + dec_insn.pc_inc + (insn.i_format.simmediate << 2); 632 else 633 *contpc = regs->cp0_epc + dec_insn.pc_inc + dec_insn.next_pc_inc; 634 return 1; 635 break; 636 } 637 break; 638 case jalx_op: 639 bit = MIPS_ISA_MODE; 640 case jal_op: 641 regs->regs[31] = regs->cp0_epc + dec_insn.pc_inc + dec_insn.next_pc_inc; 642 /* Fall through */ 643 case j_op: 644 *contpc = regs->cp0_epc + dec_insn.pc_inc; 645 *contpc >>= 28; 646 *contpc <<= 28; 647 *contpc |= (insn.j_format.target << 2); 648 /* set micro_mips mode bit: xor for jalx. LY22 */ 649 *contpc ^= bit; 650 return 1; 651 break; 652 case beq_op: 653 case beql_op: 654 if (regs->regs[insn.i_format.rs] == regs->regs[insn.i_format.rt]) 655 *contpc = regs->cp0_epc + dec_insn.pc_inc + (insn.i_format.simmediate << 2); 656 else 657 *contpc = regs->cp0_epc + dec_insn.pc_inc + dec_insn.next_pc_inc; 658 return 1; 659 break; 660 case bne_op: 661 case bnel_op: 662 if (regs->regs[insn.i_format.rs] != regs->regs[insn.i_format.rt]) 663 *contpc = regs->cp0_epc + dec_insn.pc_inc + (insn.i_format.simmediate << 2); 664 else 665 *contpc = regs->cp0_epc + dec_insn.pc_inc + dec_insn.next_pc_inc; 666 return 1; 667 break; 668 case blez_op: 669 case blezl_op: 670 if ((long)regs->regs[insn.i_format.rs] <= 0) 671 *contpc = regs->cp0_epc + dec_insn.pc_inc + (insn.i_format.simmediate << 2); 672 else 673 *contpc = regs->cp0_epc + dec_insn.pc_inc + dec_insn.next_pc_inc; 674 return 1; 675 break; 676 case bgtz_op: 677 case bgtzl_op: 678 if ((long)regs->regs[insn.i_format.rs] > 0) 679 *contpc = regs->cp0_epc + dec_insn.pc_inc + (insn.i_format.simmediate << 2); 680 else 681 *contpc = regs->cp0_epc + dec_insn.pc_inc + dec_insn.next_pc_inc; 682 return 1; 683 break; 684 case cop0_op: 685 case cop1_op: 686 case cop2_op: 687 case cop1x_op: 688 if (insn.i_format.rs == bc_op) { 689 preempt_disable(); 690 if (is_fpu_owner()) 691 asm volatile("cfc1\t%0,$31" : "=r" (fcr31)); 692 else 693 fcr31 = current->thread.fpu.fcr31; 694 preempt_enable(); 695 696 bit = (insn.i_format.rt >> 2); 697 bit += (bit != 0); 698 bit += 23; 699 switch (insn.i_format.rt & 3) { 700 case 0: /* bc1f */ 701 case 2: /* bc1fl */ 702 if (~fcr31 & (1 << bit)) 703 *contpc = regs->cp0_epc + dec_insn.pc_inc + (insn.i_format.simmediate << 2); 704 else 705 *contpc = regs->cp0_epc + dec_insn.pc_inc + dec_insn.next_pc_inc; 706 return 1; 707 break; 708 case 1: /* bc1t */ 709 case 3: /* bc1tl */ 710 if (fcr31 & (1 << bit)) 711 *contpc = regs->cp0_epc + dec_insn.pc_inc + (insn.i_format.simmediate << 2); 712 else 713 *contpc = regs->cp0_epc + dec_insn.pc_inc + dec_insn.next_pc_inc; 714 return 1; 715 break; 716 } /* end of inner switch-statement */ 717 } 718 break; 719 } 720 return 0; 721} 722 723/* 724 * In the Linux kernel, we support selection of FPR format on the 725 * basis of the Status.FR bit. If an FPU is not present, the FR bit 726 * is hardwired to zero, which would imply a 32-bit FPU even for 727 * 64-bit CPUs. For 64-bit kernels with no FPU we use TIF_32BIT_REGS 728 * as a proxy for the FR bit so that a 64-bit FPU is emulated. In any 729 * case, for a 32-bit kernel which uses the O32 MIPS ABI, only the 730 * even FPRs are used (Status.FR = 0). 731 */ 732static inline int cop1_64bit(struct pt_regs *xcp) 733{ 734 if (cpu_has_fpu) 735 return xcp->cp0_status & ST0_FR; 736#ifdef CONFIG_64BIT 737 return !test_thread_flag(TIF_32BIT_REGS); 738#else 739 return 0; 740#endif 741} 742 743#define SIFROMREG(si, x) ((si) = cop1_64bit(xcp) || !(x & 1) ? \ 744 (int)ctx->fpr[x] : (int)(ctx->fpr[x & ~1] >> 32)) 745 746#define SITOREG(si, x) (ctx->fpr[x & ~(cop1_64bit(xcp) == 0)] = \ 747 cop1_64bit(xcp) || !(x & 1) ? \ 748 ctx->fpr[x & ~1] >> 32 << 32 | (u32)(si) : \ 749 ctx->fpr[x & ~1] << 32 >> 32 | (u64)(si) << 32) 750 751#define DIFROMREG(di, x) ((di) = ctx->fpr[x & ~(cop1_64bit(xcp) == 0)]) 752#define DITOREG(di, x) (ctx->fpr[x & ~(cop1_64bit(xcp) == 0)] = (di)) 753 754#define SPFROMREG(sp, x) SIFROMREG((sp).bits, x) 755#define SPTOREG(sp, x) SITOREG((sp).bits, x) 756#define DPFROMREG(dp, x) DIFROMREG((dp).bits, x) 757#define DPTOREG(dp, x) DITOREG((dp).bits, x) 758 759/* 760 * Emulate the single floating point instruction pointed at by EPC. 761 * Two instructions if the instruction is in a branch delay slot. 762 */ 763 764static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx, 765 struct decoded_instn dec_insn, void *__user *fault_addr) 766{ 767 mips_instruction ir; 768 unsigned long contpc = xcp->cp0_epc + dec_insn.pc_inc; 769 unsigned int cond; 770 int pc_inc; 771 772 if (xcp->cp0_cause & CAUSEF_BD) { 773 if (dec_insn.micro_mips_mode) { 774 if (!mm_isBranchInstr(xcp, dec_insn, &contpc)) 775 xcp->cp0_cause &= ~CAUSEF_BD; 776 } else { 777 if (!isBranchInstr(xcp, dec_insn, &contpc)) 778 xcp->cp0_cause &= ~CAUSEF_BD; 779 } 780 } 781 782 if (xcp->cp0_cause & CAUSEF_BD) { 783 /* 784 * The instruction to be emulated is in a branch delay slot 785 * which means that we have to emulate the branch instruction 786 * BEFORE we do the cop1 instruction. 787 * 788 * This branch could be a COP1 branch, but in that case we 789 * would have had a trap for that instruction, and would not 790 * come through this route. 791 * 792 * Linux MIPS branch emulator operates on context, updating the 793 * cp0_epc. 794 */ 795 796 /* NOTE: contpc is modified by isBranchInstr() if it is a branch instr */ 797 798 ir = dec_insn.next_insn; /* process delay slot instr */ 799 pc_inc = dec_insn.next_pc_inc; 800 } else { 801 ir = dec_insn.insn; /* process current instr */ 802 pc_inc = dec_insn.pc_inc; 803 } 804 805 /* Since micro_mips FPU instructios are a subset of mips32 FPU instructions, */ 806 /* we want to convert micro_mips FPU instructions into mips32 instrunction so */ 807 /* that we could reuse all of the FPU emulation code. */ 808 /* NOTE: we can't do this for branch instructions since they are not a subset */ 809 /* ex: can't emulate a 16-bit aligned target address with a mips32 instn */ 810 if (dec_insn.micro_mips_mode) { 811 /* if next instn is a 16-bit instn then it can't be FPU instn */ 812 /* This could happen since this function can be called with non FPU instructions. */ 813 if ((pc_inc == 2) || 814 (micro_mips32_to_mips32((union mips_instruction *)&ir) == SIGILL)) 815 return SIGILL; 816 } 817 818 emul: 819 MIPS_FPU_EMU_INC_STATS(emulated); 820 switch (MIPSInst_OPCODE(ir)) { 821 case ldc1_op:{ 822 u64 __user *va = (u64 __user *) (xcp->regs[MIPSInst_RS(ir)] + 823 MIPSInst_SIMM(ir)); 824 u64 val; 825 826 MIPS_FPU_EMU_INC_STATS(loads); 827 828 if (!access_ok(VERIFY_READ, va, sizeof(u64))) { 829 MIPS_FPU_EMU_INC_STATS(errors); 830 *fault_addr = va; 831 return SIGBUS; 832 } 833 if (__get_user(val, va)) { 834 MIPS_FPU_EMU_INC_STATS(errors); 835 *fault_addr = va; 836 return SIGSEGV; 837 } 838 DITOREG(val, MIPSInst_RT(ir)); 839 break; 840 } 841 842 case sdc1_op:{ 843 u64 __user *va = (u64 __user *) (xcp->regs[MIPSInst_RS(ir)] + 844 MIPSInst_SIMM(ir)); 845 u64 val; 846 847 MIPS_FPU_EMU_INC_STATS(stores); 848 DIFROMREG(val, MIPSInst_RT(ir)); 849 if (!access_ok(VERIFY_WRITE, va, sizeof(u64))) { 850 MIPS_FPU_EMU_INC_STATS(errors); 851 *fault_addr = va; 852 return SIGBUS; 853 } 854 if (__put_user(val, va)) { 855 MIPS_FPU_EMU_INC_STATS(errors); 856 *fault_addr = va; 857 return SIGSEGV; 858 } 859 break; 860 } 861 862 case lwc1_op:{ 863 u32 __user *va = (u32 __user *) (xcp->regs[MIPSInst_RS(ir)] + 864 MIPSInst_SIMM(ir)); 865 u32 val; 866 867 MIPS_FPU_EMU_INC_STATS(loads); 868 if (!access_ok(VERIFY_READ, va, sizeof(u32))) { 869 MIPS_FPU_EMU_INC_STATS(errors); 870 *fault_addr = va; 871 return SIGBUS; 872 } 873 if (__get_user(val, va)) { 874 MIPS_FPU_EMU_INC_STATS(errors); 875 *fault_addr = va; 876 return SIGSEGV; 877 } 878 SITOREG(val, MIPSInst_RT(ir)); 879 break; 880 } 881 882 case swc1_op:{ 883 u32 __user *va = (u32 __user *) (xcp->regs[MIPSInst_RS(ir)] + 884 MIPSInst_SIMM(ir)); 885 u32 val; 886 887 MIPS_FPU_EMU_INC_STATS(stores); 888 SIFROMREG(val, MIPSInst_RT(ir)); 889 if (!access_ok(VERIFY_WRITE, va, sizeof(u32))) { 890 MIPS_FPU_EMU_INC_STATS(errors); 891 *fault_addr = va; 892 return SIGBUS; 893 } 894 if (__put_user(val, va)) { 895 MIPS_FPU_EMU_INC_STATS(errors); 896 *fault_addr = va; 897 return SIGSEGV; 898 } 899 break; 900 } 901 902 case cop1_op: 903 switch (MIPSInst_RS(ir)) { 904 905#if defined(__mips64) 906 case dmfc_op: 907 /* copregister fs -> gpr[rt] */ 908 if (MIPSInst_RT(ir) != 0) { 909 DIFROMREG(xcp->regs[MIPSInst_RT(ir)], 910 MIPSInst_RD(ir)); 911 } 912 break; 913 914 case dmtc_op: 915 /* copregister fs <- rt */ 916 DITOREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir)); 917 break; 918#endif 919 920 case mfc_op: 921 /* copregister rd -> gpr[rt] */ 922 if (MIPSInst_RT(ir) != 0) { 923 SIFROMREG(xcp->regs[MIPSInst_RT(ir)], 924 MIPSInst_RD(ir)); 925 } 926 break; 927 928 case mtc_op: 929 /* copregister rd <- rt */ 930 SITOREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir)); 931 break; 932 933 case cfc_op:{ 934 /* cop control register rd -> gpr[rt] */ 935 u32 value; 936 937 if (MIPSInst_RD(ir) == FPCREG_CSR) { 938 value = ctx->fcr31; 939 value = (value & ~FPU_CSR_RM) | 940 mips_rm[modeindex(value)]; 941#ifdef CSRTRACE 942 printk("%p gpr[%d]<-csr=%08x\n", 943 (void *) (xcp->cp0_epc), 944 MIPSInst_RT(ir), value); 945#endif 946 } 947 else if (MIPSInst_RD(ir) == FPCREG_RID) 948 value = 0; 949 else 950 value = 0; 951 if (MIPSInst_RT(ir)) 952 xcp->regs[MIPSInst_RT(ir)] = value; 953 break; 954 } 955 956 case ctc_op:{ 957 /* copregister rd <- rt */ 958 u32 value; 959 960 if (MIPSInst_RT(ir) == 0) 961 value = 0; 962 else 963 value = xcp->regs[MIPSInst_RT(ir)]; 964 965 /* we only have one writable control reg 966 */ 967 if (MIPSInst_RD(ir) == FPCREG_CSR) { 968#ifdef CSRTRACE 969 printk("%p gpr[%d]->csr=%08x\n", 970 (void *) (xcp->cp0_epc), 971 MIPSInst_RT(ir), value); 972#endif 973 974 /* 975 * Don't write reserved bits, 976 * and convert to ieee library modes 977 */ 978 ctx->fcr31 = (value & 979 ~(FPU_CSR_RSVD | FPU_CSR_RM)) | 980 ieee_rm[modeindex(value)]; 981 } 982 if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) { 983 return SIGFPE; 984 } 985 break; 986 } 987 988 case bc_op:{ 989 int likely = 0; 990 991 if (xcp->cp0_cause & CAUSEF_BD) 992 return SIGILL; 993 994#if __mips >= 4 995 cond = ctx->fcr31 & fpucondbit[MIPSInst_RT(ir) >> 2]; 996#else 997 cond = ctx->fcr31 & FPU_CSR_COND; 998#endif 999 switch (MIPSInst_RT(ir) & 3) { 1000 case bcfl_op: 1001 likely = 1; 1002 case bcf_op: 1003 cond = !cond; 1004 break; 1005 case bctl_op: 1006 likely = 1; 1007 case bct_op: 1008 break; 1009 default: 1010 /* thats an illegal instruction */ 1011 return SIGILL; 1012 } 1013 1014 xcp->cp0_cause |= CAUSEF_BD; 1015 if (cond) { 1016 /* branch taken: emulate dslot 1017 * instruction 1018 */ 1019 xcp->cp0_epc += dec_insn.pc_inc; 1020 1021 contpc = MIPSInst_SIMM(ir); 1022 ir = dec_insn.next_insn; 1023 if (dec_insn.micro_mips_mode) { 1024 contpc = (xcp->cp0_epc + (contpc << 1)); 1025 1026 /* if next instn is a 16-bit instn then it can't be FPU instn */ 1027 if ((dec_insn.next_pc_inc == 2) || 1028 (micro_mips32_to_mips32((union mips_instruction *)&ir) == SIGILL)) { 1029 1030 /* since this instn will be put on the stack with 32-bit words */ 1031 /* get around this problem by putting a NOP16 as the 2nd instn */ 1032 if (dec_insn.next_pc_inc == 2) 1033 ir = (ir & (~0xffff)) | MM_NOP16; 1034 1035 /* 1036 * Single step the non-cp1 1037 * instruction in the dslot 1038 */ 1039 return mips_dsemul(xcp, ir, contpc); 1040 } 1041 } else 1042 contpc = (xcp->cp0_epc + (contpc << 2)); 1043 1044 switch (MIPSInst_OPCODE(ir)) { 1045 case lwc1_op: 1046 case swc1_op: 1047#if (__mips >= 2 || defined(__mips64)) 1048 case ldc1_op: 1049 case sdc1_op: 1050#endif 1051 case cop1_op: 1052#if __mips >= 4 && __mips != 32 1053 case cop1x_op: 1054#endif 1055 /* its one of ours */ 1056 goto emul; 1057#if __mips >= 4 1058 case spec_op: 1059 if (MIPSInst_FUNC(ir) == movc_op) 1060 goto emul; 1061 break; 1062#endif 1063 } 1064 1065 /* 1066 * Single step the non-cp1 1067 * instruction in the dslot 1068 */ 1069 return mips_dsemul(xcp, ir, contpc); 1070 } 1071 else { 1072 /* branch not taken */ 1073 if (likely) { 1074 /* 1075 * branch likely nullifies 1076 * dslot if not taken 1077 */ 1078 xcp->cp0_epc += dec_insn.pc_inc; 1079 contpc += dec_insn.pc_inc; 1080 /* 1081 * else continue & execute 1082 * dslot as normal insn 1083 */ 1084 } 1085 } 1086 break; 1087 } 1088 1089 default: 1090 if (!(MIPSInst_RS(ir) & 0x10)) 1091 return SIGILL; 1092 { 1093 int sig; 1094 1095 /* a real fpu computation instruction */ 1096 if ((sig = fpu_emu(xcp, ctx, ir))) 1097 return sig; 1098 } 1099 } 1100 break; 1101 1102#if __mips >= 4 && __mips != 32 1103 case cop1x_op:{ 1104 int sig = fpux_emu(xcp, ctx, ir, fault_addr); 1105 if (sig) 1106 return sig; 1107 break; 1108 } 1109#endif 1110 1111#if __mips >= 4 1112 case spec_op: 1113 if (MIPSInst_FUNC(ir) != movc_op) 1114 return SIGILL; 1115 cond = fpucondbit[MIPSInst_RT(ir) >> 2]; 1116 if (((ctx->fcr31 & cond) != 0) == ((MIPSInst_RT(ir) & 1) != 0)) 1117 xcp->regs[MIPSInst_RD(ir)] = 1118 xcp->regs[MIPSInst_RS(ir)]; 1119 break; 1120#endif 1121 1122 default: 1123 return SIGILL; 1124 } 1125 1126 /* we did it !! */ 1127 xcp->cp0_epc = contpc; 1128 xcp->cp0_cause &= ~CAUSEF_BD; 1129 1130 return 0; 1131} 1132 1133/* 1134 * Conversion table from MIPS compare ops 48-63 1135 * cond = ieee754dp_cmp(x,y,IEEE754_UN,sig); 1136 */ 1137static const unsigned char cmptab[8] = { 1138 0, /* cmp_0 (sig) cmp_sf */ 1139 IEEE754_CUN, /* cmp_un (sig) cmp_ngle */ 1140 IEEE754_CEQ, /* cmp_eq (sig) cmp_seq */ 1141 IEEE754_CEQ | IEEE754_CUN, /* cmp_ueq (sig) cmp_ngl */ 1142 IEEE754_CLT, /* cmp_olt (sig) cmp_lt */ 1143 IEEE754_CLT | IEEE754_CUN, /* cmp_ult (sig) cmp_nge */ 1144 IEEE754_CLT | IEEE754_CEQ, /* cmp_ole (sig) cmp_le */ 1145 IEEE754_CLT | IEEE754_CEQ | IEEE754_CUN, /* cmp_ule (sig) cmp_ngt */ 1146}; 1147 1148 1149#if __mips >= 4 && __mips != 32 1150 1151/* 1152 * Additional MIPS4 instructions 1153 */ 1154 1155#define DEF3OP(name, p, f1, f2, f3) \ 1156static ieee754##p fpemu_##p##_##name(ieee754##p r, ieee754##p s, \ 1157 ieee754##p t) \ 1158{ \ 1159 struct _ieee754_csr ieee754_csr_save; \ 1160 s = f1(s, t); \ 1161 ieee754_csr_save = ieee754_csr; \ 1162 s = f2(s, r); \ 1163 ieee754_csr_save.cx |= ieee754_csr.cx; \ 1164 ieee754_csr_save.sx |= ieee754_csr.sx; \ 1165 s = f3(s); \ 1166 ieee754_csr.cx |= ieee754_csr_save.cx; \ 1167 ieee754_csr.sx |= ieee754_csr_save.sx; \ 1168 return s; \ 1169} 1170 1171static ieee754dp fpemu_dp_recip(ieee754dp d) 1172{ 1173 return ieee754dp_div(ieee754dp_one(0), d); 1174} 1175 1176static ieee754dp fpemu_dp_rsqrt(ieee754dp d) 1177{ 1178 return ieee754dp_div(ieee754dp_one(0), ieee754dp_sqrt(d)); 1179} 1180 1181static ieee754sp fpemu_sp_recip(ieee754sp s) 1182{ 1183 return ieee754sp_div(ieee754sp_one(0), s); 1184} 1185 1186static ieee754sp fpemu_sp_rsqrt(ieee754sp s) 1187{ 1188 return ieee754sp_div(ieee754sp_one(0), ieee754sp_sqrt(s)); 1189} 1190 1191DEF3OP(madd, sp, ieee754sp_mul, ieee754sp_add, ); 1192DEF3OP(msub, sp, ieee754sp_mul, ieee754sp_sub, ); 1193DEF3OP(nmadd, sp, ieee754sp_mul, ieee754sp_add, ieee754sp_neg); 1194DEF3OP(nmsub, sp, ieee754sp_mul, ieee754sp_sub, ieee754sp_neg); 1195DEF3OP(madd, dp, ieee754dp_mul, ieee754dp_add, ); 1196DEF3OP(msub, dp, ieee754dp_mul, ieee754dp_sub, ); 1197DEF3OP(nmadd, dp, ieee754dp_mul, ieee754dp_add, ieee754dp_neg); 1198DEF3OP(nmsub, dp, ieee754dp_mul, ieee754dp_sub, ieee754dp_neg); 1199 1200static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, 1201 mips_instruction ir, void *__user *fault_addr) 1202{ 1203 unsigned rcsr = 0; /* resulting csr */ 1204 1205 MIPS_FPU_EMU_INC_STATS(cp1xops); 1206 1207 switch (MIPSInst_FMA_FFMT(ir)) { 1208 case s_fmt:{ /* 0 */ 1209 1210 ieee754sp(*handler) (ieee754sp, ieee754sp, ieee754sp); 1211 ieee754sp fd, fr, fs, ft; 1212 u32 __user *va; 1213 u32 val; 1214 1215 switch (MIPSInst_FUNC(ir)) { 1216 case lwxc1_op: 1217 va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] + 1218 xcp->regs[MIPSInst_FT(ir)]); 1219 1220 MIPS_FPU_EMU_INC_STATS(loads); 1221 if (!access_ok(VERIFY_READ, va, sizeof(u32))) { 1222 MIPS_FPU_EMU_INC_STATS(errors); 1223 *fault_addr = va; 1224 return SIGBUS; 1225 } 1226 if (__get_user(val, va)) { 1227 MIPS_FPU_EMU_INC_STATS(errors); 1228 *fault_addr = va; 1229 return SIGSEGV; 1230 } 1231 SITOREG(val, MIPSInst_FD(ir)); 1232 break; 1233 1234 case swxc1_op: 1235 va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] + 1236 xcp->regs[MIPSInst_FT(ir)]); 1237 1238 MIPS_FPU_EMU_INC_STATS(stores); 1239 1240 SIFROMREG(val, MIPSInst_FS(ir)); 1241 if (!access_ok(VERIFY_WRITE, va, sizeof(u32))) { 1242 MIPS_FPU_EMU_INC_STATS(errors); 1243 *fault_addr = va; 1244 return SIGBUS; 1245 } 1246 if (put_user(val, va)) { 1247 MIPS_FPU_EMU_INC_STATS(errors); 1248 *fault_addr = va; 1249 return SIGSEGV; 1250 } 1251 break; 1252 1253 case madd_s_op: 1254 handler = fpemu_sp_madd; 1255 goto scoptop; 1256 case msub_s_op: 1257 handler = fpemu_sp_msub; 1258 goto scoptop; 1259 case nmadd_s_op: 1260 handler = fpemu_sp_nmadd; 1261 goto scoptop; 1262 case nmsub_s_op: 1263 handler = fpemu_sp_nmsub; 1264 goto scoptop; 1265 1266 scoptop: 1267 SPFROMREG(fr, MIPSInst_FR(ir)); 1268 SPFROMREG(fs, MIPSInst_FS(ir)); 1269 SPFROMREG(ft, MIPSInst_FT(ir)); 1270 fd = (*handler) (fr, fs, ft); 1271 SPTOREG(fd, MIPSInst_FD(ir)); 1272 1273 copcsr: 1274 if (ieee754_cxtest(IEEE754_INEXACT)) 1275 rcsr |= FPU_CSR_INE_X | FPU_CSR_INE_S; 1276 if (ieee754_cxtest(IEEE754_UNDERFLOW)) 1277 rcsr |= FPU_CSR_UDF_X | FPU_CSR_UDF_S; 1278 if (ieee754_cxtest(IEEE754_OVERFLOW)) 1279 rcsr |= FPU_CSR_OVF_X | FPU_CSR_OVF_S; 1280 if (ieee754_cxtest(IEEE754_INVALID_OPERATION)) 1281 rcsr |= FPU_CSR_INV_X | FPU_CSR_INV_S; 1282 1283 ctx->fcr31 = (ctx->fcr31 & ~FPU_CSR_ALL_X) | rcsr; 1284 if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) { 1285 /*printk ("SIGFPE: fpu csr = %08x\n", 1286 ctx->fcr31); */ 1287 return SIGFPE; 1288 } 1289 1290 break; 1291 1292 default: 1293 return SIGILL; 1294 } 1295 break; 1296 } 1297 1298 case d_fmt:{ /* 1 */ 1299 ieee754dp(*handler) (ieee754dp, ieee754dp, ieee754dp); 1300 ieee754dp fd, fr, fs, ft; 1301 u64 __user *va; 1302 u64 val; 1303 1304 switch (MIPSInst_FUNC(ir)) { 1305 case ldxc1_op: 1306 va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] + 1307 xcp->regs[MIPSInst_FT(ir)]); 1308 1309 MIPS_FPU_EMU_INC_STATS(loads); 1310 if (!access_ok(VERIFY_READ, va, sizeof(u64))) { 1311 MIPS_FPU_EMU_INC_STATS(errors); 1312 *fault_addr = va; 1313 return SIGBUS; 1314 } 1315 if (__get_user(val, va)) { 1316 MIPS_FPU_EMU_INC_STATS(errors); 1317 *fault_addr = va; 1318 return SIGSEGV; 1319 } 1320 DITOREG(val, MIPSInst_FD(ir)); 1321 break; 1322 1323 case sdxc1_op: 1324 va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] + 1325 xcp->regs[MIPSInst_FT(ir)]); 1326 1327 MIPS_FPU_EMU_INC_STATS(stores); 1328 DIFROMREG(val, MIPSInst_FS(ir)); 1329 if (!access_ok(VERIFY_WRITE, va, sizeof(u64))) { 1330 MIPS_FPU_EMU_INC_STATS(errors); 1331 *fault_addr = va; 1332 return SIGBUS; 1333 } 1334 if (__put_user(val, va)) { 1335 MIPS_FPU_EMU_INC_STATS(errors); 1336 *fault_addr = va; 1337 return SIGSEGV; 1338 } 1339 break; 1340 1341 case madd_d_op: 1342 handler = fpemu_dp_madd; 1343 goto dcoptop; 1344 case msub_d_op: 1345 handler = fpemu_dp_msub; 1346 goto dcoptop; 1347 case nmadd_d_op: 1348 handler = fpemu_dp_nmadd; 1349 goto dcoptop; 1350 case nmsub_d_op: 1351 handler = fpemu_dp_nmsub; 1352 goto dcoptop; 1353 1354 dcoptop: 1355 DPFROMREG(fr, MIPSInst_FR(ir)); 1356 DPFROMREG(fs, MIPSInst_FS(ir)); 1357 DPFROMREG(ft, MIPSInst_FT(ir)); 1358 fd = (*handler) (fr, fs, ft); 1359 DPTOREG(fd, MIPSInst_FD(ir)); 1360 goto copcsr; 1361 1362 default: 1363 return SIGILL; 1364 } 1365 break; 1366 } 1367 1368 case 0x7: /* 7 */ 1369 if (MIPSInst_FUNC(ir) != pfetch_op) { 1370 return SIGILL; 1371 } 1372 /* ignore prefx operation */ 1373 break; 1374 1375 default: 1376 return SIGILL; 1377 } 1378 1379 return 0; 1380} 1381#endif 1382 1383 1384 1385/* 1386 * Emulate a single COP1 arithmetic instruction. 1387 */ 1388static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, 1389 mips_instruction ir) 1390{ 1391 int rfmt; /* resulting format */ 1392 unsigned rcsr = 0; /* resulting csr */ 1393 unsigned cond; 1394 union { 1395 ieee754dp d; 1396 ieee754sp s; 1397 int w; 1398#ifdef __mips64 1399 s64 l; 1400#endif 1401 } rv; /* resulting value */ 1402 1403 MIPS_FPU_EMU_INC_STATS(cp1ops); 1404 switch (rfmt = (MIPSInst_FFMT(ir) & 0xf)) { 1405 case s_fmt:{ /* 0 */ 1406 union { 1407 ieee754sp(*b) (ieee754sp, ieee754sp); 1408 ieee754sp(*u) (ieee754sp); 1409 } handler; 1410 1411 switch (MIPSInst_FUNC(ir)) { 1412 /* binary ops */ 1413 case fadd_op: 1414 handler.b = ieee754sp_add; 1415 goto scopbop; 1416 case fsub_op: 1417 handler.b = ieee754sp_sub; 1418 goto scopbop; 1419 case fmul_op: 1420 handler.b = ieee754sp_mul; 1421 goto scopbop; 1422 case fdiv_op: 1423 handler.b = ieee754sp_div; 1424 goto scopbop; 1425 1426 /* unary ops */ 1427#if __mips >= 2 || defined(__mips64) 1428 case fsqrt_op: 1429 handler.u = ieee754sp_sqrt; 1430 goto scopuop; 1431#endif 1432#if __mips >= 4 && __mips != 32 1433 case frsqrt_op: 1434 handler.u = fpemu_sp_rsqrt; 1435 goto scopuop; 1436 case frecip_op: 1437 handler.u = fpemu_sp_recip; 1438 goto scopuop; 1439#endif 1440#if __mips >= 4 1441 case fmovc_op: 1442 cond = fpucondbit[MIPSInst_FT(ir) >> 2]; 1443 if (((ctx->fcr31 & cond) != 0) != 1444 ((MIPSInst_FT(ir) & 1) != 0)) 1445 return 0; 1446 SPFROMREG(rv.s, MIPSInst_FS(ir)); 1447 break; 1448 case fmovz_op: 1449 if (xcp->regs[MIPSInst_FT(ir)] != 0) 1450 return 0; 1451 SPFROMREG(rv.s, MIPSInst_FS(ir)); 1452 break; 1453 case fmovn_op: 1454 if (xcp->regs[MIPSInst_FT(ir)] == 0) 1455 return 0; 1456 SPFROMREG(rv.s, MIPSInst_FS(ir)); 1457 break; 1458#endif 1459 case fabs_op: 1460 handler.u = ieee754sp_abs; 1461 goto scopuop; 1462 case fneg_op: 1463 handler.u = ieee754sp_neg; 1464 goto scopuop; 1465 case fmov_op: 1466 /* an easy one */ 1467 SPFROMREG(rv.s, MIPSInst_FS(ir)); 1468 goto copcsr; 1469 1470 /* binary op on handler */ 1471 scopbop: 1472 { 1473 ieee754sp fs, ft; 1474 1475 SPFROMREG(fs, MIPSInst_FS(ir)); 1476 SPFROMREG(ft, MIPSInst_FT(ir)); 1477 1478 rv.s = (*handler.b) (fs, ft); 1479 goto copcsr; 1480 } 1481 scopuop: 1482 { 1483 ieee754sp fs; 1484 1485 SPFROMREG(fs, MIPSInst_FS(ir)); 1486 rv.s = (*handler.u) (fs); 1487 goto copcsr; 1488 } 1489 copcsr: 1490 if (ieee754_cxtest(IEEE754_INEXACT)) 1491 rcsr |= FPU_CSR_INE_X | FPU_CSR_INE_S; 1492 if (ieee754_cxtest(IEEE754_UNDERFLOW)) 1493 rcsr |= FPU_CSR_UDF_X | FPU_CSR_UDF_S; 1494 if (ieee754_cxtest(IEEE754_OVERFLOW)) 1495 rcsr |= FPU_CSR_OVF_X | FPU_CSR_OVF_S; 1496 if (ieee754_cxtest(IEEE754_ZERO_DIVIDE)) 1497 rcsr |= FPU_CSR_DIV_X | FPU_CSR_DIV_S; 1498 if (ieee754_cxtest(IEEE754_INVALID_OPERATION)) 1499 rcsr |= FPU_CSR_INV_X | FPU_CSR_INV_S; 1500 break; 1501 1502 /* unary conv ops */ 1503 case fcvts_op: 1504 return SIGILL; /* not defined */ 1505 case fcvtd_op:{ 1506 ieee754sp fs; 1507 1508 SPFROMREG(fs, MIPSInst_FS(ir)); 1509 rv.d = ieee754dp_fsp(fs); 1510 rfmt = d_fmt; 1511 goto copcsr; 1512 } 1513 case fcvtw_op:{ 1514 ieee754sp fs; 1515 1516 SPFROMREG(fs, MIPSInst_FS(ir)); 1517 rv.w = ieee754sp_tint(fs); 1518 rfmt = w_fmt; 1519 goto copcsr; 1520 } 1521 1522#if __mips >= 2 || defined(__mips64) 1523 case fround_op: 1524 case ftrunc_op: 1525 case fceil_op: 1526 case ffloor_op:{ 1527 unsigned int oldrm = ieee754_csr.rm; 1528 ieee754sp fs; 1529 1530 SPFROMREG(fs, MIPSInst_FS(ir)); 1531 ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))]; 1532 rv.w = ieee754sp_tint(fs); 1533 ieee754_csr.rm = oldrm; 1534 rfmt = w_fmt; 1535 goto copcsr; 1536 } 1537#endif /* __mips >= 2 */ 1538 1539#if defined(__mips64) 1540 case fcvtl_op:{ 1541 ieee754sp fs; 1542 1543 SPFROMREG(fs, MIPSInst_FS(ir)); 1544 rv.l = ieee754sp_tlong(fs); 1545 rfmt = l_fmt; 1546 goto copcsr; 1547 } 1548 1549 case froundl_op: 1550 case ftruncl_op: 1551 case fceill_op: 1552 case ffloorl_op:{ 1553 unsigned int oldrm = ieee754_csr.rm; 1554 ieee754sp fs; 1555 1556 SPFROMREG(fs, MIPSInst_FS(ir)); 1557 ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))]; 1558 rv.l = ieee754sp_tlong(fs); 1559 ieee754_csr.rm = oldrm; 1560 rfmt = l_fmt; 1561 goto copcsr; 1562 } 1563#endif /* defined(__mips64) */ 1564 1565 default: 1566 if (MIPSInst_FUNC(ir) >= fcmp_op) { 1567 unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op; 1568 ieee754sp fs, ft; 1569 1570 SPFROMREG(fs, MIPSInst_FS(ir)); 1571 SPFROMREG(ft, MIPSInst_FT(ir)); 1572 rv.w = ieee754sp_cmp(fs, ft, 1573 cmptab[cmpop & 0x7], cmpop & 0x8); 1574 rfmt = -1; 1575 if ((cmpop & 0x8) && ieee754_cxtest 1576 (IEEE754_INVALID_OPERATION)) 1577 rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S; 1578 else 1579 goto copcsr; 1580 1581 } 1582 else { 1583 return SIGILL; 1584 } 1585 break; 1586 } 1587 break; 1588 } 1589 1590 case d_fmt:{ 1591 union { 1592 ieee754dp(*b) (ieee754dp, ieee754dp); 1593 ieee754dp(*u) (ieee754dp); 1594 } handler; 1595 1596 switch (MIPSInst_FUNC(ir)) { 1597 /* binary ops */ 1598 case fadd_op: 1599 handler.b = ieee754dp_add; 1600 goto dcopbop; 1601 case fsub_op: 1602 handler.b = ieee754dp_sub; 1603 goto dcopbop; 1604 case fmul_op: 1605 handler.b = ieee754dp_mul; 1606 goto dcopbop; 1607 case fdiv_op: 1608 handler.b = ieee754dp_div; 1609 goto dcopbop; 1610 1611 /* unary ops */ 1612#if __mips >= 2 || defined(__mips64) 1613 case fsqrt_op: 1614 handler.u = ieee754dp_sqrt; 1615 goto dcopuop; 1616#endif 1617#if __mips >= 4 && __mips != 32 1618 case frsqrt_op: 1619 handler.u = fpemu_dp_rsqrt; 1620 goto dcopuop; 1621 case frecip_op: 1622 handler.u = fpemu_dp_recip; 1623 goto dcopuop; 1624#endif 1625#if __mips >= 4 1626 case fmovc_op: 1627 cond = fpucondbit[MIPSInst_FT(ir) >> 2]; 1628 if (((ctx->fcr31 & cond) != 0) != 1629 ((MIPSInst_FT(ir) & 1) != 0)) 1630 return 0; 1631 DPFROMREG(rv.d, MIPSInst_FS(ir)); 1632 break; 1633 case fmovz_op: 1634 if (xcp->regs[MIPSInst_FT(ir)] != 0) 1635 return 0; 1636 DPFROMREG(rv.d, MIPSInst_FS(ir)); 1637 break; 1638 case fmovn_op: 1639 if (xcp->regs[MIPSInst_FT(ir)] == 0) 1640 return 0; 1641 DPFROMREG(rv.d, MIPSInst_FS(ir)); 1642 break; 1643#endif 1644 case fabs_op: 1645 handler.u = ieee754dp_abs; 1646 goto dcopuop; 1647 1648 case fneg_op: 1649 handler.u = ieee754dp_neg; 1650 goto dcopuop; 1651 1652 case fmov_op: 1653 /* an easy one */ 1654 DPFROMREG(rv.d, MIPSInst_FS(ir)); 1655 goto copcsr; 1656 1657 /* binary op on handler */ 1658 dcopbop:{ 1659 ieee754dp fs, ft; 1660 1661 DPFROMREG(fs, MIPSInst_FS(ir)); 1662 DPFROMREG(ft, MIPSInst_FT(ir)); 1663 1664 rv.d = (*handler.b) (fs, ft); 1665 goto copcsr; 1666 } 1667 dcopuop:{ 1668 ieee754dp fs; 1669 1670 DPFROMREG(fs, MIPSInst_FS(ir)); 1671 rv.d = (*handler.u) (fs); 1672 goto copcsr; 1673 } 1674 1675 /* unary conv ops */ 1676 case fcvts_op:{ 1677 ieee754dp fs; 1678 1679 DPFROMREG(fs, MIPSInst_FS(ir)); 1680 rv.s = ieee754sp_fdp(fs); 1681 rfmt = s_fmt; 1682 goto copcsr; 1683 } 1684 case fcvtd_op: 1685 return SIGILL; /* not defined */ 1686 1687 case fcvtw_op:{ 1688 ieee754dp fs; 1689 1690 DPFROMREG(fs, MIPSInst_FS(ir)); 1691 rv.w = ieee754dp_tint(fs); /* wrong */ 1692 rfmt = w_fmt; 1693 goto copcsr; 1694 } 1695 1696#if __mips >= 2 || defined(__mips64) 1697 case fround_op: 1698 case ftrunc_op: 1699 case fceil_op: 1700 case ffloor_op:{ 1701 unsigned int oldrm = ieee754_csr.rm; 1702 ieee754dp fs; 1703 1704 DPFROMREG(fs, MIPSInst_FS(ir)); 1705 ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))]; 1706 rv.w = ieee754dp_tint(fs); 1707 ieee754_csr.rm = oldrm; 1708 rfmt = w_fmt; 1709 goto copcsr; 1710 } 1711#endif 1712 1713#if defined(__mips64) 1714 case fcvtl_op:{ 1715 ieee754dp fs; 1716 1717 DPFROMREG(fs, MIPSInst_FS(ir)); 1718 rv.l = ieee754dp_tlong(fs); 1719 rfmt = l_fmt; 1720 goto copcsr; 1721 } 1722 1723 case froundl_op: 1724 case ftruncl_op: 1725 case fceill_op: 1726 case ffloorl_op:{ 1727 unsigned int oldrm = ieee754_csr.rm; 1728 ieee754dp fs; 1729 1730 DPFROMREG(fs, MIPSInst_FS(ir)); 1731 ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))]; 1732 rv.l = ieee754dp_tlong(fs); 1733 ieee754_csr.rm = oldrm; 1734 rfmt = l_fmt; 1735 goto copcsr; 1736 } 1737#endif /* __mips >= 3 */ 1738 1739 default: 1740 if (MIPSInst_FUNC(ir) >= fcmp_op) { 1741 unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op; 1742 ieee754dp fs, ft; 1743 1744 DPFROMREG(fs, MIPSInst_FS(ir)); 1745 DPFROMREG(ft, MIPSInst_FT(ir)); 1746 rv.w = ieee754dp_cmp(fs, ft, 1747 cmptab[cmpop & 0x7], cmpop & 0x8); 1748 rfmt = -1; 1749 if ((cmpop & 0x8) 1750 && 1751 ieee754_cxtest 1752 (IEEE754_INVALID_OPERATION)) 1753 rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S; 1754 else 1755 goto copcsr; 1756 1757 } 1758 else { 1759 return SIGILL; 1760 } 1761 break; 1762 } 1763 break; 1764 } 1765 1766 case w_fmt:{ 1767 ieee754sp fs; 1768 1769 switch (MIPSInst_FUNC(ir)) { 1770 case fcvts_op: 1771 /* convert word to single precision real */ 1772 SPFROMREG(fs, MIPSInst_FS(ir)); 1773 rv.s = ieee754sp_fint(fs.bits); 1774 rfmt = s_fmt; 1775 goto copcsr; 1776 case fcvtd_op: 1777 /* convert word to double precision real */ 1778 SPFROMREG(fs, MIPSInst_FS(ir)); 1779 rv.d = ieee754dp_fint(fs.bits); 1780 rfmt = d_fmt; 1781 goto copcsr; 1782 default: 1783 return SIGILL; 1784 } 1785 break; 1786 } 1787 1788#if defined(__mips64) 1789 case l_fmt:{ 1790 switch (MIPSInst_FUNC(ir)) { 1791 case fcvts_op: 1792 /* convert long to single precision real */ 1793 rv.s = ieee754sp_flong(ctx->fpr[MIPSInst_FS(ir)]); 1794 rfmt = s_fmt; 1795 goto copcsr; 1796 case fcvtd_op: 1797 /* convert long to double precision real */ 1798 rv.d = ieee754dp_flong(ctx->fpr[MIPSInst_FS(ir)]); 1799 rfmt = d_fmt; 1800 goto copcsr; 1801 default: 1802 return SIGILL; 1803 } 1804 break; 1805 } 1806#endif 1807 1808 default: 1809 return SIGILL; 1810 } 1811 1812 /* 1813 * Update the fpu CSR register for this operation. 1814 * If an exception is required, generate a tidy SIGFPE exception, 1815 * without updating the result register. 1816 * Note: cause exception bits do not accumulate, they are rewritten 1817 * for each op; only the flag/sticky bits accumulate. 1818 */ 1819 ctx->fcr31 = (ctx->fcr31 & ~FPU_CSR_ALL_X) | rcsr; 1820 if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) { 1821 /*printk ("SIGFPE: fpu csr = %08x\n",ctx->fcr31); */ 1822 return SIGFPE; 1823 } 1824 1825 /* 1826 * Now we can safely write the result back to the register file. 1827 */ 1828 switch (rfmt) { 1829 case -1:{ 1830#if __mips >= 4 1831 cond = fpucondbit[MIPSInst_FD(ir) >> 2]; 1832#else 1833 cond = FPU_CSR_COND; 1834#endif 1835 if (rv.w) 1836 ctx->fcr31 |= cond; 1837 else 1838 ctx->fcr31 &= ~cond; 1839 break; 1840 } 1841 case d_fmt: 1842 DPTOREG(rv.d, MIPSInst_FD(ir)); 1843 break; 1844 case s_fmt: 1845 SPTOREG(rv.s, MIPSInst_FD(ir)); 1846 break; 1847 case w_fmt: 1848 SITOREG(rv.w, MIPSInst_FD(ir)); 1849 break; 1850#if defined(__mips64) 1851 case l_fmt: 1852 DITOREG(rv.l, MIPSInst_FD(ir)); 1853 break; 1854#endif 1855 default: 1856 return SIGILL; 1857 } 1858 1859 return 0; 1860} 1861 1862int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx, 1863 int has_fpu, void *__user *fault_addr) 1864{ 1865 unsigned long oldepc, prevepc; 1866 struct decoded_instn dec_insn; 1867 u16 instr[4]; 1868 u16 *instr_ptr; 1869 int sig = 0; 1870 1871 oldepc = xcp->cp0_epc; 1872 do { 1873 prevepc = xcp->cp0_epc; 1874 1875 if (is16mode(xcp) && cpu_has_mmips) { 1876 /* get the next 2 micro_mips instn and decode them into 2 mips32 instn */ 1877 if ((get_user(instr[0], (u16 __user *)(xcp->cp0_epc & ~MIPS_ISA_MODE))) || 1878 (get_user(instr[1], (u16 __user *)((xcp->cp0_epc+2) & ~MIPS_ISA_MODE))) || 1879 (get_user(instr[2], (u16 __user *)((xcp->cp0_epc+4) & ~MIPS_ISA_MODE))) || 1880 (get_user(instr[3], (u16 __user *)((xcp->cp0_epc+6) & ~MIPS_ISA_MODE)))) { 1881 MIPS_FPU_EMU_INC_STATS(errors); 1882 return SIGBUS; 1883 } 1884 instr_ptr = instr; 1885 /* get 1st instruction */ 1886 if (mm_is16bit(*instr_ptr)) { 1887 dec_insn.insn = (*instr_ptr << 16) | (*instr_ptr); /* duplicate the half-word */ 1888 dec_insn.pc_inc = 2; /* 16 bit instr */ 1889 instr_ptr += 1; 1890 } else { 1891 dec_insn.insn = (*instr_ptr << 16) | *(instr_ptr+1); 1892 dec_insn.pc_inc = 4; /* 32 bit instr */ 1893 instr_ptr += 2; 1894 } 1895 /* get 2nd instruction */ 1896 if (mm_is16bit(*instr_ptr)) { 1897 dec_insn.next_insn = (*instr_ptr << 16) | (*instr_ptr); /* duplicate the half-word */ 1898 dec_insn.next_pc_inc = 2; /* 16 bit instr */ 1899 } else { 1900 dec_insn.next_insn = (*instr_ptr << 16) | *(instr_ptr+1); 1901 dec_insn.next_pc_inc = 4; /* 32 bit instr */ 1902 } 1903 dec_insn.micro_mips_mode = 1; 1904 } else { 1905 if ((get_user(dec_insn.insn, (mips_instruction __user *) xcp->cp0_epc)) || 1906 (get_user(dec_insn.next_insn, (mips_instruction __user *)(xcp->cp0_epc+4)))) { 1907 MIPS_FPU_EMU_INC_STATS(errors); 1908 return SIGBUS; 1909 } 1910 dec_insn.pc_inc = 4; 1911 dec_insn.next_pc_inc = 4; 1912 dec_insn.micro_mips_mode = 0; 1913 } 1914 1915 if ((dec_insn.insn == 0) || 1916 ((dec_insn.pc_inc == 2) && ((dec_insn.insn & 0xffff) == MM_NOP16))) 1917 xcp->cp0_epc += dec_insn.pc_inc; /* skip nops */ 1918 else { 1919 /* 1920 * The 'ieee754_csr' is an alias of 1921 * ctx->fcr31. No need to copy ctx->fcr31 to 1922 * ieee754_csr. But ieee754_csr.rm is ieee 1923 * library modes. (not mips rounding mode) 1924 */ 1925 /* convert to ieee library modes */ 1926 ieee754_csr.rm = ieee_rm[ieee754_csr.rm]; 1927 sig = cop1Emulate(xcp, ctx, dec_insn, fault_addr); 1928 /* revert to mips rounding mode */ 1929 ieee754_csr.rm = mips_rm[ieee754_csr.rm]; 1930 } 1931 1932 if (has_fpu) 1933 break; 1934 if (sig) 1935 break; 1936 1937 cond_resched(); 1938 } while (xcp->cp0_epc > prevepc); 1939 1940 /* SIGILL indicates a non-fpu instruction */ 1941 if (sig == SIGILL && xcp->cp0_epc != oldepc) 1942 /* but if epc has advanced, then ignore it */ 1943 sig = 0; 1944 1945 /*if (sig == SIGILL) printk("Illegal micro_mips FPU instruction: 0x%x, 0x%x\n", dec_insn.insn, dec_insn.next_insn);*/ 1946 1947 return sig; 1948} 1949 1950#ifdef CONFIG_DEBUG_FS 1951 1952static int fpuemu_stat_get(void *data, u64 *val) 1953{ 1954 int cpu; 1955 unsigned long sum = 0; 1956 for_each_online_cpu(cpu) { 1957 struct mips_fpu_emulator_stats *ps; 1958 local_t *pv; 1959 ps = &per_cpu(fpuemustats, cpu); 1960 pv = (void *)ps + (unsigned long)data; 1961 sum += local_read(pv); 1962 } 1963 *val = sum; 1964 return 0; 1965} 1966DEFINE_SIMPLE_ATTRIBUTE(fops_fpuemu_stat, fpuemu_stat_get, NULL, "%llu\n"); 1967 1968extern struct dentry *mips_debugfs_dir; 1969static int __init debugfs_fpuemu(void) 1970{ 1971 struct dentry *d, *dir; 1972 1973 if (!mips_debugfs_dir) 1974 return -ENODEV; 1975 dir = debugfs_create_dir("fpuemustats", mips_debugfs_dir); 1976 if (!dir) 1977 return -ENOMEM; 1978 1979#define FPU_STAT_CREATE(M) \ 1980 do { \ 1981 d = debugfs_create_file(#M , S_IRUGO, dir, \ 1982 (void *)offsetof(struct mips_fpu_emulator_stats, M), \ 1983 &fops_fpuemu_stat); \ 1984 if (!d) \ 1985 return -ENOMEM; \ 1986 } while (0) 1987 1988 FPU_STAT_CREATE(emulated); 1989 FPU_STAT_CREATE(loads); 1990 FPU_STAT_CREATE(stores); 1991 FPU_STAT_CREATE(cp1ops); 1992 FPU_STAT_CREATE(cp1xops); 1993 FPU_STAT_CREATE(errors); 1994 1995 return 0; 1996} 1997__initcall(debugfs_fpuemu); 1998#endif 1999