--- zzzz-none-000/linux-3.10.107/arch/mips/math-emu/cp1emu.c 2017-06-27 09:49:32.000000000 +0000 +++ vr9-7490-729/linux-3.10.107/arch/mips/math-emu/cp1emu.c 2021-11-10 11:53:54.000000000 +0000 @@ -417,14 +417,20 @@ case mm_mtc1_op: case mm_cfc1_op: case mm_ctc1_op: + case mm_mfhc1_op: + case mm_mthc1_op: if (insn.mm_fp1_format.op == mm_mfc1_op) op = mfc_op; else if (insn.mm_fp1_format.op == mm_mtc1_op) op = mtc_op; else if (insn.mm_fp1_format.op == mm_cfc1_op) op = cfc_op; - else + else if (insn.mm_fp1_format.op == mm_ctc1_op) op = ctc_op; + else if (insn.mm_fp1_format.op == mm_mfhc1_op) + op = mfhc_op; + else + op = mthc_op; mips32_insn.fp1_format.opcode = cop1_op; mips32_insn.fp1_format.op = op; mips32_insn.fp1_format.rt = @@ -471,6 +477,9 @@ unsigned int fcr31; unsigned int bit; + if (!cpu_has_mmips) + return 0; + switch (insn.mm_i_format.opcode) { case mm_pool32a_op: if ((insn.mm_i_format.simmediate & MM_POOL32A_MINOR_MASK) == @@ -861,13 +870,7 @@ */ static inline int cop1_64bit(struct pt_regs *xcp) { -#if defined(CONFIG_64BIT) && !defined(CONFIG_MIPS32_O32) - return 1; -#elif defined(CONFIG_64BIT) && defined(CONFIG_MIPS32_O32) return !test_thread_flag(TIF_32BIT_REGS); -#else - return 0; -#endif } #define SIFROMREG(si, x) ((si) = cop1_64bit(xcp) || !(x & 1) ? \ @@ -886,6 +889,10 @@ #define DPFROMREG(dp, x) DIFROMREG((dp).bits, x) #define DPTOREG(dp, x) DITOREG((dp).bits, x) +#define SIFROMHREG(si, x) ((si) = (int)(ctx->fpr[x] >> 32)) +#define SITOHREG(si, x) (ctx->fpr[x] = \ + ctx->fpr[x] << 32 >> 32 | (u64)(si) << 32) + /* * Emulate the single floating point instruction pointed at by EPC. * Two instructions if the instruction is in a branch delay slot. @@ -1055,6 +1062,21 @@ break; #endif +#ifdef CONFIG_CPU_MIPSR2 + case mfhc_op: + /* copregister rd -> gpr[rt] */ + if (MIPSInst_RT(ir) != 0) { + SIFROMHREG(xcp->regs[MIPSInst_RT(ir)], + MIPSInst_RD(ir)); + } + break; + + case mthc_op: + /* copregister rd <- gpr[rt] */ + SITOHREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir)); + break; +#endif + case mfc_op: /* copregister rd -> gpr[rt] */ if (MIPSInst_RT(ir) != 0) {