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