|
@@ -878,6 +878,10 @@ static inline int cop1_64bit(struct pt_regs *xcp)
|
|
|
ctx->fpr[x & ~1] >> 32 << 32 | (u32)(si) : \
|
|
|
ctx->fpr[x & ~1] << 32 >> 32 | (u64)(si) << 32)
|
|
|
|
|
|
+#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)
|
|
|
+
|
|
|
#define DIFROMREG(di, x) ((di) = ctx->fpr[x & ~(cop1_64bit(xcp) == 0)])
|
|
|
#define DITOREG(di, x) (ctx->fpr[x & ~(cop1_64bit(xcp) == 0)] = (di))
|
|
|
|
|
@@ -1055,6 +1059,25 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
|
|
|
break;
|
|
|
#endif
|
|
|
|
|
|
+ case mfhc_op:
|
|
|
+ if (!cpu_has_mips_r2)
|
|
|
+ goto sigill;
|
|
|
+
|
|
|
+ /* copregister rd -> gpr[rt] */
|
|
|
+ if (MIPSInst_RT(ir) != 0) {
|
|
|
+ SIFROMHREG(xcp->regs[MIPSInst_RT(ir)],
|
|
|
+ MIPSInst_RD(ir));
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case mthc_op:
|
|
|
+ if (!cpu_has_mips_r2)
|
|
|
+ goto sigill;
|
|
|
+
|
|
|
+ /* copregister rd <- gpr[rt] */
|
|
|
+ SITOHREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
|
|
|
+ break;
|
|
|
+
|
|
|
case mfc_op:
|
|
|
/* copregister rd -> gpr[rt] */
|
|
|
if (MIPSInst_RT(ir) != 0) {
|
|
@@ -1263,6 +1286,7 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
|
|
|
#endif
|
|
|
|
|
|
default:
|
|
|
+sigill:
|
|
|
return SIGILL;
|
|
|
}
|
|
|
|