|
From: <sv...@va...> - 2016-02-22 16:17:07
|
Author: petarj
Date: Mon Feb 22 16:16:59 2016
New Revision: 3211
Log:
mips: allow execution of mfhc1 and mthc1 for fp32 mode
MTHC1 and MFHC1 should be allowed for any MIPS32R2 compatible core, not only
for cores with FPU unit in fp64 mode.
Modified:
trunk/priv/guest_mips_toIR.c
Modified: trunk/priv/guest_mips_toIR.c
==============================================================================
--- trunk/priv/guest_mips_toIR.c (original)
+++ trunk/priv/guest_mips_toIR.c Mon Feb 22 16:16:59 2016
@@ -12228,28 +12228,39 @@
case 0x11: { /* COP1 */
if (fmt == 0x3 && fd == 0 && function == 0) { /* MFHC1 */
DIP("mfhc1 r%u, f%u", rt, fs);
- if (fp_mode64) {
- t0 = newTemp(Ity_I64);
- t1 = newTemp(Ity_I32);
- assign(t0, unop(Iop_ReinterpF64asI64, getDReg(fs)));
- assign(t1, unop(Iop_64HIto32, mkexpr(t0)));
- putIReg(rt, mkWidenFrom32(ty, mkexpr(t1), True));
- } else {
- ILLEGAL_INSTRUCTON;
+ if (VEX_MIPS_CPU_HAS_MIPS32R2(archinfo->hwcaps)) {
+ if (fp_mode64) {
+ t0 = newTemp(Ity_I64);
+ t1 = newTemp(Ity_I32);
+ assign(t0, unop(Iop_ReinterpF64asI64, getDReg(fs)));
+ assign(t1, unop(Iop_64HIto32, mkexpr(t0)));
+ putIReg(rt, mkWidenFrom32(ty, mkexpr(t1), True));
+ break;
+ } else if ((fs & 1) == 0) {
+ putIReg(rt, mkWidenFrom32(ty, unop(Iop_ReinterpF32asI32,
+ getFReg(fs | 1)), True));
+ break;
+ }
}
+ ILLEGAL_INSTRUCTON;
break;
} else if (fmt == 0x7 && fd == 0 && function == 0) { /* MTHC1 */
DIP("mthc1 r%u, f%u", rt, fs);
- if (fp_mode64) {
- t0 = newTemp(Ity_I64);
- assign(t0, binop(Iop_32HLto64, getIReg(rt),
- unop(Iop_ReinterpF32asI32,
- getLoFromF64(Ity_F64 /* 32FPR mode. */,
- getDReg(fs)))));
- putDReg(fs, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
- } else {
- ILLEGAL_INSTRUCTON;
+ if (VEX_MIPS_CPU_HAS_MIPS32R2(archinfo->hwcaps)) {
+ if (fp_mode64) {
+ t0 = newTemp(Ity_I64);
+ assign(t0, binop(Iop_32HLto64, mkNarrowTo32(ty, getIReg(rt)),
+ unop(Iop_ReinterpF32asI32,
+ getLoFromF64(Ity_F64, getDReg(fs)))));
+ putDReg(fs, unop(Iop_ReinterpI64asF64, mkexpr(t0)));
+ break;
+ } else if ((fs & 1) == 0) {
+ putFReg(fs | 1, unop(Iop_ReinterpI32asF32,
+ mkNarrowTo32(ty, getIReg(rt))));
+ break;
+ }
}
+ ILLEGAL_INSTRUCTON;
break;
} else if (fmt == 0x8) { /* BC */
/* FcConditionalCode(bc1_cc) */
|