MIPS: math-emu: Correct delay-slot exception propagation
[firefly-linux-kernel-4.4.55.git] / arch / mips / math-emu / cp1emu.c
index 9dfcd7fc1bc3dd712980c93f95ea4b8c1f3049d9..acfef06b83112b88a43d913eced9ac5b1d94659a 100644 (file)
@@ -48,6 +48,7 @@
 #include <asm/processor.h>
 #include <asm/fpu_emulator.h>
 #include <asm/fpu.h>
+#include <asm/mips-r2-to-r6-emul.h>
 
 #include "ieee754.h"
 
@@ -64,11 +65,8 @@ static int fpux_emu(struct pt_regs *,
 #define FPCREG_RID     0       /* $0  = revision id */
 #define FPCREG_CSR     31      /* $31 = csr */
 
-/* Determine rounding mode from the RM bits of the FCSR */
-#define modeindex(v) ((v) & FPU_CSR_RM)
-
 /* convert condition code register number to csr bit */
-static const unsigned int fpucondbit[8] = {
+const unsigned int fpucondbit[8] = {
        FPU_CSR_COND0,
        FPU_CSR_COND1,
        FPU_CSR_COND2,
@@ -448,6 +446,9 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
                                dec_insn.next_pc_inc;
                        /* Fall through */
                case jr_op:
+                       /* For R6, JR already emulated in jalr_op */
+                       if (NO_R6EMU && insn.r_format.opcode == jr_op)
+                               break;
                        *contpc = regs->regs[insn.r_format.rs];
                        return 1;
                }
@@ -456,12 +457,18 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
                switch (insn.i_format.rt) {
                case bltzal_op:
                case bltzall_op:
+                       if (NO_R6EMU && (insn.i_format.rs ||
+                           insn.i_format.rt == bltzall_op))
+                               break;
+
                        regs->regs[31] = regs->cp0_epc +
                                dec_insn.pc_inc +
                                dec_insn.next_pc_inc;
                        /* Fall through */
-               case bltz_op:
                case bltzl_op:
+                       if (NO_R6EMU)
+                               break;
+               case bltz_op:
                        if ((long)regs->regs[insn.i_format.rs] < 0)
                                *contpc = regs->cp0_epc +
                                        dec_insn.pc_inc +
@@ -473,12 +480,18 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
                        return 1;
                case bgezal_op:
                case bgezall_op:
+                       if (NO_R6EMU && (insn.i_format.rs ||
+                           insn.i_format.rt == bgezall_op))
+                               break;
+
                        regs->regs[31] = regs->cp0_epc +
                                dec_insn.pc_inc +
                                dec_insn.next_pc_inc;
                        /* Fall through */
-               case bgez_op:
                case bgezl_op:
+                       if (NO_R6EMU)
+                               break;
+               case bgez_op:
                        if ((long)regs->regs[insn.i_format.rs] >= 0)
                                *contpc = regs->cp0_epc +
                                        dec_insn.pc_inc +
@@ -505,8 +518,10 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
                /* Set microMIPS mode bit: XOR for jalx. */
                *contpc ^= bit;
                return 1;
-       case beq_op:
        case beql_op:
+               if (NO_R6EMU)
+                       break;
+       case beq_op:
                if (regs->regs[insn.i_format.rs] ==
                    regs->regs[insn.i_format.rt])
                        *contpc = regs->cp0_epc +
@@ -517,8 +532,10 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
                                dec_insn.pc_inc +
                                dec_insn.next_pc_inc;
                return 1;
-       case bne_op:
        case bnel_op:
+               if (NO_R6EMU)
+                       break;
+       case bne_op:
                if (regs->regs[insn.i_format.rs] !=
                    regs->regs[insn.i_format.rt])
                        *contpc = regs->cp0_epc +
@@ -529,8 +546,34 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
                                dec_insn.pc_inc +
                                dec_insn.next_pc_inc;
                return 1;
-       case blez_op:
        case blezl_op:
+               if (NO_R6EMU)
+                       break;
+       case blez_op:
+
+               /*
+                * Compact branches for R6 for the
+                * blez and blezl opcodes.
+                * BLEZ  | rs = 0 | rt != 0  == BLEZALC
+                * BLEZ  | rs = rt != 0      == BGEZALC
+                * BLEZ  | rs != 0 | rt != 0 == BGEUC
+                * BLEZL | rs = 0 | rt != 0  == BLEZC
+                * BLEZL | rs = rt != 0      == BGEZC
+                * BLEZL | rs != 0 | rt != 0 == BGEC
+                *
+                * For real BLEZ{,L}, rt is always 0.
+                */
+               if (cpu_has_mips_r6 && insn.i_format.rt) {
+                       if ((insn.i_format.opcode == blez_op) &&
+                           ((!insn.i_format.rs && insn.i_format.rt) ||
+                            (insn.i_format.rs == insn.i_format.rt)))
+                               regs->regs[31] = regs->cp0_epc +
+                                       dec_insn.pc_inc;
+                       *contpc = regs->cp0_epc + dec_insn.pc_inc +
+                               dec_insn.next_pc_inc;
+
+                       return 1;
+               }
                if ((long)regs->regs[insn.i_format.rs] <= 0)
                        *contpc = regs->cp0_epc +
                                dec_insn.pc_inc +
@@ -540,8 +583,35 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
                                dec_insn.pc_inc +
                                dec_insn.next_pc_inc;
                return 1;
-       case bgtz_op:
        case bgtzl_op:
+               if (NO_R6EMU)
+                       break;
+       case bgtz_op:
+               /*
+                * Compact branches for R6 for the
+                * bgtz and bgtzl opcodes.
+                * BGTZ  | rs = 0 | rt != 0  == BGTZALC
+                * BGTZ  | rs = rt != 0      == BLTZALC
+                * BGTZ  | rs != 0 | rt != 0 == BLTUC
+                * BGTZL | rs = 0 | rt != 0  == BGTZC
+                * BGTZL | rs = rt != 0      == BLTZC
+                * BGTZL | rs != 0 | rt != 0 == BLTC
+                *
+                * *ZALC varint for BGTZ &&& rt != 0
+                * For real GTZ{,L}, rt is always 0.
+                */
+               if (cpu_has_mips_r6 && insn.i_format.rt) {
+                       if ((insn.i_format.opcode == blez_op) &&
+                           ((!insn.i_format.rs && insn.i_format.rt) ||
+                            (insn.i_format.rs == insn.i_format.rt)))
+                               regs->regs[31] = regs->cp0_epc +
+                                       dec_insn.pc_inc;
+                       *contpc = regs->cp0_epc + dec_insn.pc_inc +
+                               dec_insn.next_pc_inc;
+
+                       return 1;
+               }
+
                if ((long)regs->regs[insn.i_format.rs] > 0)
                        *contpc = regs->cp0_epc +
                                dec_insn.pc_inc +
@@ -551,6 +621,16 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
                                dec_insn.pc_inc +
                                dec_insn.next_pc_inc;
                return 1;
+       case cbcond0_op:
+       case cbcond1_op:
+               if (!cpu_has_mips_r6)
+                       break;
+               if (insn.i_format.rt && !insn.i_format.rs)
+                       regs->regs[31] = regs->cp0_epc + 4;
+               *contpc = regs->cp0_epc + dec_insn.pc_inc +
+                       dec_insn.next_pc_inc;
+
+               return 1;
 #ifdef CONFIG_CPU_CAVIUM_OCTEON
        case lwc2_op: /* This is bbit0 on Octeon */
                if ((regs->regs[insn.i_format.rs] & (1ull<<insn.i_format.rt)) == 0)
@@ -576,9 +656,73 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
                else
                        *contpc = regs->cp0_epc + 8;
                return 1;
+#else
+       case bc6_op:
+               /*
+                * Only valid for MIPS R6 but we can still end up
+                * here from a broken userland so just tell emulator
+                * this is not a branch and let it break later on.
+                */
+               if  (!cpu_has_mips_r6)
+                       break;
+               *contpc = regs->cp0_epc + dec_insn.pc_inc +
+                       dec_insn.next_pc_inc;
+
+               return 1;
+       case balc6_op:
+               if (!cpu_has_mips_r6)
+                       break;
+               regs->regs[31] = regs->cp0_epc + 4;
+               *contpc = regs->cp0_epc + dec_insn.pc_inc +
+                       dec_insn.next_pc_inc;
+
+               return 1;
+       case beqzcjic_op:
+               if (!cpu_has_mips_r6)
+                       break;
+               *contpc = regs->cp0_epc + dec_insn.pc_inc +
+                       dec_insn.next_pc_inc;
+
+               return 1;
+       case bnezcjialc_op:
+               if (!cpu_has_mips_r6)
+                       break;
+               if (!insn.i_format.rs)
+                       regs->regs[31] = regs->cp0_epc + 4;
+               *contpc = regs->cp0_epc + dec_insn.pc_inc +
+                       dec_insn.next_pc_inc;
+
+               return 1;
 #endif
        case cop0_op:
        case cop1_op:
+               /* Need to check for R6 bc1nez and bc1eqz branches */
+               if (cpu_has_mips_r6 &&
+                   ((insn.i_format.rs == bc1eqz_op) ||
+                    (insn.i_format.rs == bc1nez_op))) {
+                       bit = 0;
+                       switch (insn.i_format.rs) {
+                       case bc1eqz_op:
+                               if (get_fpr32(&current->thread.fpu.fpr[insn.i_format.rt], 0) & 0x1)
+                                   bit = 1;
+                               break;
+                       case bc1nez_op:
+                               if (!(get_fpr32(&current->thread.fpu.fpr[insn.i_format.rt], 0) & 0x1))
+                                   bit = 1;
+                               break;
+                       }
+                       if (bit)
+                               *contpc = regs->cp0_epc +
+                                       dec_insn.pc_inc +
+                                       (insn.i_format.simmediate << 2);
+                       else
+                               *contpc = regs->cp0_epc +
+                                       dec_insn.pc_inc +
+                                       dec_insn.next_pc_inc;
+
+                       return 1;
+               }
+               /* R2/R6 compatible cop1 instruction. Fall through */
        case cop2_op:
        case cop1x_op:
                if (insn.i_format.rs == bc_op) {
@@ -695,6 +839,52 @@ do {                                                                       \
 #define DPFROMREG(dp, x)       DIFROMREG((dp).bits, x)
 #define DPTOREG(dp, x) DITOREG((dp).bits, x)
 
+/*
+ * Emulate a CFC1 instruction.
+ */
+static inline void cop1_cfc(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
+                           mips_instruction ir)
+{
+       u32 value;
+
+       if (MIPSInst_RD(ir) == FPCREG_CSR) {
+               value = ctx->fcr31;
+               pr_debug("%p gpr[%d]<-csr=%08x\n",
+                        (void *)xcp->cp0_epc,
+                        MIPSInst_RT(ir), value);
+       } else if (MIPSInst_RD(ir) == FPCREG_RID)
+               value = 0;
+       else
+               value = 0;
+       if (MIPSInst_RT(ir))
+               xcp->regs[MIPSInst_RT(ir)] = value;
+}
+
+/*
+ * Emulate a CTC1 instruction.
+ */
+static inline void cop1_ctc(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
+                           mips_instruction ir)
+{
+       u32 value;
+
+       if (MIPSInst_RT(ir) == 0)
+               value = 0;
+       else
+               value = xcp->regs[MIPSInst_RT(ir)];
+
+       /* we only have one writable control reg
+        */
+       if (MIPSInst_RD(ir) == FPCREG_CSR) {
+               pr_debug("%p gpr[%d]->csr=%08x\n",
+                        (void *)xcp->cp0_epc,
+                        MIPSInst_RT(ir), value);
+
+               /* Don't write reserved bits.  */
+               ctx->fcr31 = value & ~FPU_CSR_RSVD;
+       }
+}
+
 /*
  * Emulate the single floating point instruction pointed at by EPC.
  * Two instructions if the instruction is in a branch delay slot.
@@ -709,7 +899,6 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
        int likely, pc_inc;
        u32 __user *wva;
        u64 __user *dva;
-       u32 value;
        u32 wval;
        u64 dval;
        int sig;
@@ -902,42 +1091,12 @@ emul:
 
                case cfc_op:
                        /* cop control register rd -> gpr[rt] */
-                       if (MIPSInst_RD(ir) == FPCREG_CSR) {
-                               value = ctx->fcr31;
-                               value = (value & ~FPU_CSR_RM) | modeindex(value);
-                               pr_debug("%p gpr[%d]<-csr=%08x\n",
-                                        (void *) (xcp->cp0_epc),
-                                        MIPSInst_RT(ir), value);
-                       }
-                       else if (MIPSInst_RD(ir) == FPCREG_RID)
-                               value = 0;
-                       else
-                               value = 0;
-                       if (MIPSInst_RT(ir))
-                               xcp->regs[MIPSInst_RT(ir)] = value;
+                       cop1_cfc(xcp, ctx, ir);
                        break;
 
                case ctc_op:
                        /* copregister rd <- rt */
-                       if (MIPSInst_RT(ir) == 0)
-                               value = 0;
-                       else
-                               value = xcp->regs[MIPSInst_RT(ir)];
-
-                       /* we only have one writable control reg
-                        */
-                       if (MIPSInst_RD(ir) == FPCREG_CSR) {
-                               pr_debug("%p gpr[%d]->csr=%08x\n",
-                                        (void *) (xcp->cp0_epc),
-                                        MIPSInst_RT(ir), value);
-
-                               /*
-                                * Don't write reserved bits,
-                                * and convert to ieee library modes
-                                */
-                               ctx->fcr31 = (value & ~(FPU_CSR_RSVD | FPU_CSR_RM)) |
-                                            modeindex(value);
-                       }
+                       cop1_ctc(xcp, ctx, ir);
                        if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
                                return SIGFPE;
                        }
@@ -956,17 +1115,18 @@ emul:
                        likely = 0;
                        switch (MIPSInst_RT(ir) & 3) {
                        case bcfl_op:
-                               likely = 1;
+                               if (cpu_has_mips_2_3_4_5_r)
+                                       likely = 1;
+                               /* Fall through */
                        case bcf_op:
                                cond = !cond;
                                break;
                        case bctl_op:
-                               likely = 1;
+                               if (cpu_has_mips_2_3_4_5_r)
+                                       likely = 1;
+                               /* Fall through */
                        case bct_op:
                                break;
-                       default:
-                               /* thats an illegal instruction */
-                               return SIGILL;
                        }
 
                        set_delay_slot(xcp);
@@ -974,6 +1134,14 @@ emul:
                                /*
                                 * Branch taken: emulate dslot instruction
                                 */
+                               unsigned long bcpc;
+
+                               /*
+                                * Remember EPC at the branch to point back
+                                * at so that any delay-slot instruction
+                                * signal is not silently ignored.
+                                */
+                               bcpc = xcp->cp0_epc;
                                xcp->cp0_epc += dec_insn.pc_inc;
 
                                contpc = MIPSInst_SIMM(ir);
@@ -999,63 +1167,77 @@ emul:
                                                 * Single step the non-CP1
                                                 * instruction in the dslot.
                                                 */
-                                               return mips_dsemul(xcp, ir, contpc);
+                                               sig = mips_dsemul(xcp, ir,
+                                                                 contpc);
+                                               if (sig)
+                                                       xcp->cp0_epc = bcpc;
+                                               /*
+                                                * SIGILL forces out of
+                                                * the emulation loop.
+                                                */
+                                               return sig ? sig : SIGILL;
                                        }
                                } else
                                        contpc = (xcp->cp0_epc + (contpc << 2));
 
                                switch (MIPSInst_OPCODE(ir)) {
                                case lwc1_op:
-                                       goto emul;
-
                                case swc1_op:
                                        goto emul;
 
                                case ldc1_op:
                                case sdc1_op:
-                                       if (cpu_has_mips_2_3_4_5 ||
-                                           cpu_has_mips64)
+                                       if (cpu_has_mips_2_3_4_5_r)
                                                goto emul;
 
-                                       return SIGILL;
-                                       goto emul;
+                                       goto bc_sigill;
 
                                case cop1_op:
                                        goto emul;
 
                                case cop1x_op:
-                                       if (cpu_has_mips_4_5 || cpu_has_mips64 || cpu_has_mips32r2)
+                                       if (cpu_has_mips_4_5_64_r2_r6)
                                                /* its one of ours */
                                                goto emul;
 
-                                       return SIGILL;
+                                       goto bc_sigill;
 
                                case spec_op:
-                                       if (!cpu_has_mips_4_5_r)
-                                               return SIGILL;
+                                       switch (MIPSInst_FUNC(ir)) {
+                                       case movc_op:
+                                               if (cpu_has_mips_4_5_r)
+                                                       goto emul;
 
-                                       if (MIPSInst_FUNC(ir) == movc_op)
-                                               goto emul;
+                                               goto bc_sigill;
+                                       }
                                        break;
+
+                               bc_sigill:
+                                       xcp->cp0_epc = bcpc;
+                                       return SIGILL;
                                }
 
                                /*
                                 * Single step the non-cp1
                                 * instruction in the dslot
                                 */
-                               return mips_dsemul(xcp, ir, contpc);
+                               sig = mips_dsemul(xcp, ir, contpc);
+                               if (sig)
+                                       xcp->cp0_epc = bcpc;
+                               /* SIGILL forces out of the emulation loop.  */
+                               return sig ? sig : SIGILL;
                        } else if (likely) {    /* branch not taken */
-                                       /*
-                                        * branch likely nullifies
-                                        * dslot if not taken
-                                        */
-                                       xcp->cp0_epc += dec_insn.pc_inc;
-                                       contpc += dec_insn.pc_inc;
-                                       /*
-                                        * else continue & execute
-                                        * dslot as normal insn
-                                        */
-                               }
+                               /*
+                                * branch likely nullifies
+                                * dslot if not taken
+                                */
+                               xcp->cp0_epc += dec_insn.pc_inc;
+                               contpc += dec_insn.pc_inc;
+                               /*
+                                * else continue & execute
+                                * dslot as normal insn
+                                */
+                       }
                        break;
 
                default:
@@ -1069,7 +1251,7 @@ emul:
                break;
 
        case cop1x_op:
-               if (!cpu_has_mips_4_5 && !cpu_has_mips64 && !cpu_has_mips32r2)
+               if (!cpu_has_mips_4_5_64_r2_r6)
                        return SIGILL;
 
                sig = fpux_emu(xcp, ctx, ir, fault_addr);
@@ -1402,7 +1584,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
 
                        /* unary  ops */
                case fsqrt_op:
-                       if (!cpu_has_mips_4_5_r)
+                       if (!cpu_has_mips_2_3_4_5_r)
                                return SIGILL;
 
                        handler.u = ieee754sp_sqrt;
@@ -1414,14 +1596,14 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
                 * achieve full IEEE-754 accuracy - however this emulator does.
                 */
                case frsqrt_op:
-                       if (!cpu_has_mips_4_5_r2)
+                       if (!cpu_has_mips_4_5_64_r2_r6)
                                return SIGILL;
 
                        handler.u = fpemu_sp_rsqrt;
                        goto scopuop;
 
                case frecip_op:
-                       if (!cpu_has_mips_4_5_r2)
+                       if (!cpu_has_mips_4_5_64_r2_r6)
                                return SIGILL;
 
                        handler.u = fpemu_sp_recip;
@@ -1523,19 +1705,19 @@ copcsr:
                case ftrunc_op:
                case fceil_op:
                case ffloor_op:
-                       if (!cpu_has_mips_2_3_4_5 && !cpu_has_mips64)
+                       if (!cpu_has_mips_2_3_4_5_r)
                                return SIGILL;
 
                        oldrm = ieee754_csr.rm;
                        SPFROMREG(fs, MIPSInst_FS(ir));
-                       ieee754_csr.rm = modeindex(MIPSInst_FUNC(ir));
+                       ieee754_csr.rm = MIPSInst_FUNC(ir);
                        rv.w = ieee754sp_tint(fs);
                        ieee754_csr.rm = oldrm;
                        rfmt = w_fmt;
                        goto copcsr;
 
                case fcvtl_op:
-                       if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
+                       if (!cpu_has_mips_3_4_5_64_r2_r6)
                                return SIGILL;
 
                        SPFROMREG(fs, MIPSInst_FS(ir));
@@ -1547,12 +1729,12 @@ copcsr:
                case ftruncl_op:
                case fceill_op:
                case ffloorl_op:
-                       if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
+                       if (!cpu_has_mips_3_4_5_64_r2_r6)
                                return SIGILL;
 
                        oldrm = ieee754_csr.rm;
                        SPFROMREG(fs, MIPSInst_FS(ir));
-                       ieee754_csr.rm = modeindex(MIPSInst_FUNC(ir));
+                       ieee754_csr.rm = MIPSInst_FUNC(ir);
                        rv.l = ieee754sp_tlong(fs);
                        ieee754_csr.rm = oldrm;
                        rfmt = l_fmt;
@@ -1616,13 +1798,13 @@ copcsr:
                 * achieve full IEEE-754 accuracy - however this emulator does.
                 */
                case frsqrt_op:
-                       if (!cpu_has_mips_4_5_r2)
+                       if (!cpu_has_mips_4_5_64_r2_r6)
                                return SIGILL;
 
                        handler.u = fpemu_dp_rsqrt;
                        goto dcopuop;
                case frecip_op:
-                       if (!cpu_has_mips_4_5_r2)
+                       if (!cpu_has_mips_4_5_64_r2_r6)
                                return SIGILL;
 
                        handler.u = fpemu_dp_recip;
@@ -1705,14 +1887,14 @@ dcopuop:
 
                        oldrm = ieee754_csr.rm;
                        DPFROMREG(fs, MIPSInst_FS(ir));
-                       ieee754_csr.rm = modeindex(MIPSInst_FUNC(ir));
+                       ieee754_csr.rm = MIPSInst_FUNC(ir);
                        rv.w = ieee754dp_tint(fs);
                        ieee754_csr.rm = oldrm;
                        rfmt = w_fmt;
                        goto copcsr;
 
                case fcvtl_op:
-                       if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
+                       if (!cpu_has_mips_3_4_5_64_r2_r6)
                                return SIGILL;
 
                        DPFROMREG(fs, MIPSInst_FS(ir));
@@ -1724,12 +1906,12 @@ dcopuop:
                case ftruncl_op:
                case fceill_op:
                case ffloorl_op:
-                       if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
+                       if (!cpu_has_mips_3_4_5_64_r2_r6)
                                return SIGILL;
 
                        oldrm = ieee754_csr.rm;
                        DPFROMREG(fs, MIPSInst_FS(ir));
-                       ieee754_csr.rm = modeindex(MIPSInst_FUNC(ir));
+                       ieee754_csr.rm = MIPSInst_FUNC(ir);
                        rv.l = ieee754dp_tlong(fs);
                        ieee754_csr.rm = oldrm;
                        rfmt = l_fmt;
@@ -1783,7 +1965,7 @@ dcopuop:
 
        case l_fmt:
 
-               if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
+               if (!cpu_has_mips_3_4_5_64_r2_r6)
                        return SIGILL;
 
                DIFROMREG(bits, MIPSInst_FS(ir));
@@ -1847,7 +2029,7 @@ dcopuop:
                SITOREG(rv.w, MIPSInst_FD(ir));
                break;
        case l_fmt:
-               if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
+               if (!cpu_has_mips_3_4_5_64_r2_r6)
                        return SIGILL;
 
                DITOREG(rv.l, MIPSInst_FD(ir));
@@ -1934,10 +2116,8 @@ int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
                        xcp->cp0_epc += dec_insn.pc_inc;        /* Skip NOPs */
                else {
                        /*
-                        * The 'ieee754_csr' is an alias of
-                        * ctx->fcr31.  No need to copy ctx->fcr31 to
-                        * ieee754_csr.  But ieee754_csr.rm is ieee
-                        * library modes. (not mips rounding mode)
+                        * The 'ieee754_csr' is an alias of ctx->fcr31.
+                        * No need to copy ctx->fcr31 to ieee754_csr.
                         */
                        sig = cop1Emulate(xcp, ctx, dec_insn, fault_addr);
                }