|
From: <sv...@va...> - 2013-10-23 14:05:31
|
Author: dejanj
Date: Wed Oct 23 14:05:15 2013
New Revision: 2796
Log:
mips32: Fix problem with some mips32 dsp instructions.
This patch includes VEX optimizations for mips32 and
fixes for some mips32 dsp instructions.
Modified:
trunk/priv/guest_mips_toIR.c
trunk/priv/host_mips_defs.c
trunk/priv/host_mips_isel.c
Modified: trunk/priv/guest_mips_toIR.c
==============================================================================
--- trunk/priv/guest_mips_toIR.c (original)
+++ trunk/priv/guest_mips_toIR.c Wed Oct 23 14:05:15 2013
@@ -2123,7 +2123,7 @@
UInt size;
assign(tmpRs, getIReg(regRs));
- switch(opc2) {
+ switch(opc2) {
case 0x03: { /* DMUL rd, rs, rt */
DIP("dmul r%d, r%d, r%d", regRd, regRs, regRt);
IRType t0 = newTemp(Ity_I128);
@@ -2132,7 +2132,7 @@
break;
}
case 0x32: /* 5. CINS rd, rs, p, lenm1 */
- DIP("cins r%u, r%u, %d, %d\n", regRt, regRs, p, lenM1);
+ DIP("cins r%u, r%u, %d, %d\n", regRt, regRs, p, lenM1);
assign ( tmp , binop(Iop_Shl64, mkexpr(tmpRs), mkU8(64-( lenM1+1 ))));
assign ( tmpRt, binop(Iop_Shr64, mkexpr( tmp ), mkU8(64-(p+lenM1+1))));
putIReg( regRt, mkexpr(tmpRt));
@@ -2146,7 +2146,7 @@
break;
case 0x3A: /* 3. EXTS rt, rs, p len */
- DIP("exts r%u, r%u, %d, %d\n", regRt, regRs, p, lenM1);
+ DIP("exts r%u, r%u, %d, %d\n", regRt, regRs, p, lenM1);
size = lenM1 + 1; /* lenm1+1 */
UChar lsAmt = 64 - (p + size); /* p+lenm1+1 */
UChar rsAmt = 64 - size; /* lenm1+1 */
@@ -2156,7 +2156,7 @@
break;
case 0x3B: /* 4. EXTS32 rt, rs, p len */
- DIP("exts32 r%u, r%u, %d, %d\n", regRt, regRs, p, lenM1);
+ DIP("exts32 r%u, r%u, %d, %d\n", regRt, regRs, p, lenM1);
assign ( tmp , binop(Iop_Shl64, mkexpr(tmpRs), mkU8(32-(p+lenM1+1))));
assign ( tmpRt, binop(Iop_Sar64, mkexpr(tmp) , mkU8(64-(lenM1+1))) );
putIReg( regRt, mkexpr(tmpRt));
@@ -2223,7 +2223,7 @@
static UInt disDSPInstr_MIPS_WRK ( UInt cins )
{
IRTemp t0, t1 = 0, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14,
- t15, t16, t17, t18;
+ t15, t16, t17;
UInt opcode, rs, rt, rd, sa, function, ac, ac_mfhilo, rddsp_mask,
wrdsp_mask, dsp_imm, shift;
@@ -2875,40 +2875,123 @@
t0 = newTemp(Ity_I64);
t1 = newTemp(Ity_I64);
t2 = newTemp(Ity_I32);
- t3 = newTemp(Ity_I32);
- t4 = newTemp(Ity_I32);
+ t3 = newTemp(Ity_I1);
+ t4 = newTemp(Ity_I1);
+ t5 = newTemp(Ity_I1);
+ t6 = newTemp(Ity_I1);
+ t7 = newTemp(Ity_I32);
+ t8 = newTemp(Ity_I64);
+ t9 = newTemp(Ity_I64);
+ t10 = newTemp(Ity_I1);
+ t11 = newTemp(Ity_I1);
+ t12 = newTemp(Ity_I1);
+ t13 = newTemp(Ity_I1);
+ t14 = newTemp(Ity_I32);
assign(t0, getAcc(ac));
- assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs)));
- putIReg(rt, unop(Iop_64to32, mkexpr(t1)));
+ if (0 == rs) {
+ assign(t1, mkexpr(t0));
+ } else {
+ assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs)));
+ }
+ /* Check if bits 63..31 of the result in t1 aren't 0. */
+ assign(t3, binop(Iop_CmpNE32,
+ unop(Iop_64HIto32,
+ mkexpr(t1)),
+ mkU32(0)));
+ assign(t4, binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ unop(Iop_64to32,
+ mkexpr(t1)),
+ mkU32(0x80000000)),
+ mkU32(0)));
+ /* Check if bits 63..31 of the result in t1 aren't
+ 0x1ffffffff. */
+ assign(t5, binop(Iop_CmpNE32,
+ unop(Iop_64HIto32,
+ mkexpr(t1)),
+ mkU32(0xffffffff)));
+ assign(t6, binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ unop(Iop_64to32,
+ mkexpr(t1)),
+ mkU32(0x80000000)),
+ mkU32(0x80000000)));
+ /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
+ control register. */
+ assign(t7, binop(Iop_And32,
+ binop(Iop_Or32,
+ unop(Iop_1Sto32, mkexpr(t3)),
+ unop(Iop_1Sto32, mkexpr(t4))),
+ binop(Iop_Or32,
+ unop(Iop_1Sto32, mkexpr(t5)),
+ unop(Iop_1Sto32, mkexpr(t6)))));
+ putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
+ mkexpr(t7),
+ mkU32(0)),
+ binop(Iop_Or32,
+ getDSPControl(),
+ mkU32(0x00800000)),
+ getDSPControl()));
- assign(t2, binop(Iop_Or32,
- getDSPControl(), mkU32(0x00800000)));
+ /* If the last discarded bit is 1, there would be carry
+ when rounding, otherwise there wouldn't. We use that
+ fact and just add the value of the last discarded bit
+ to the least sifgnificant bit of the shifted value
+ from acc. */
+ if (0 == rs) {
+ assign(t8, mkU64(0x0ULL));
+ } else {
+ assign(t8, binop(Iop_And64,
+ binop(Iop_Shr64,
+ mkexpr(t0),
+ mkU8(rs-1)),
+ mkU64(0x1ULL)));
+ }
+ assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
- /* Check if signOut == signIn */
- assign(t3, IRExpr_ITE(binop(Iop_CmpEQ32,
- binop(Iop_And32,
- unop(Iop_64HIto32,
- mkexpr(t0)),
- mkU32(0x80000000)),
- binop(Iop_And32,
- getIReg(rt),
- mkU32(0x80000000))),
- getDSPControl(),
- mkexpr(t2)));
+ /* Repeat previous steps for the rounded value. */
+ assign(t10, binop(Iop_CmpNE32,
+ unop(Iop_64HIto32,
+ mkexpr(t9)),
+ mkU32(0)));
+ assign(t11, binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ unop(Iop_64to32,
+ mkexpr(t9)),
+ mkU32(0x80000000)),
+ mkU32(0)));
- assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
- unop(Iop_64HIto32,
- mkexpr(t1)),
- mkU32(0x0)),
- IRExpr_ITE(binop(Iop_CmpNE32,
- unop(Iop_64HIto32,
- mkexpr(t1)),
- mkU32(0xffffffff)),
- mkexpr(t2),
- mkexpr(t3)),
- mkexpr(t3)));
- putDSPControl(mkexpr(t4));
+ assign(t12, binop(Iop_CmpNE32,
+ unop(Iop_64HIto32,
+ mkexpr(t9)),
+ mkU32(0xffffffff)));
+ assign(t13, binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ unop(Iop_64to32,
+ mkexpr(t9)),
+ mkU32(0x80000000)),
+ mkU32(0x80000000)));
+
+ assign(t14, binop(Iop_And32,
+ binop(Iop_Or32,
+ unop(Iop_1Sto32, mkexpr(t10)),
+ unop(Iop_1Sto32, mkexpr(t11))),
+ binop(Iop_Or32,
+ unop(Iop_1Sto32, mkexpr(t12)),
+ unop(Iop_1Sto32, mkexpr(t13)))));
+ putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
+ mkexpr(t14),
+ mkU32(0)),
+ binop(Iop_Or32,
+ getDSPControl(),
+ mkU32(0x00800000)),
+ getDSPControl()));
+ if (0 == rs) {
+ putIReg(rt, unop(Iop_64to32, mkexpr(t0)));
+ } else {
+ putIReg(rt, unop(Iop_64to32, mkexpr(t1)));
+ }
break;
}
case 0x1: { /* EXTRV.W */
@@ -2917,43 +3000,133 @@
t0 = newTemp(Ity_I64);
t1 = newTemp(Ity_I64);
t2 = newTemp(Ity_I32);
- t3 = newTemp(Ity_I32);
+ t3 = newTemp(Ity_I1);
t4 = newTemp(Ity_I1);
+ t5 = newTemp(Ity_I1);
+ t6 = newTemp(Ity_I1);
+ t7 = newTemp(Ity_I32);
+ t8 = newTemp(Ity_I64);
+ t9 = newTemp(Ity_I64);
+ t10 = newTemp(Ity_I1);
+ t11 = newTemp(Ity_I1);
+ t12 = newTemp(Ity_I1);
+ t13 = newTemp(Ity_I1);
+ t14 = newTemp(Ity_I32);
+ t15 = newTemp(Ity_I8);
+ assign(t15, unop(Iop_32to8,
+ binop(Iop_And32,
+ getIReg(rs),
+ mkU32(0x1f))));
assign(t0, getAcc(ac));
- assign(t1, binop(Iop_Sar64,
- mkexpr(t0),
- unop(Iop_32to8,
- binop(Iop_And32,
- getIReg(rs),
- mkU32(0x1f)))));
- putIReg(rt, unop(Iop_64to32, mkexpr(t1)));
-
- assign(t2, binop(Iop_Or32,
- getDSPControl(), mkU32(0x00800000)));
+ assign(t1, binop(Iop_Sar64, mkexpr(t0), mkexpr(t15)));
+ putIReg(rt, IRExpr_ITE(binop(Iop_CmpEQ32,
+ unop(Iop_8Uto32,
+ mkexpr(t15)),
+ mkU32(0)),
+ unop(Iop_64to32, mkexpr(t0)),
+ unop(Iop_64to32, mkexpr(t1))));
- /* Check if signOut == signIn */
- assign(t3, IRExpr_ITE(binop(Iop_CmpEQ32,
- binop(Iop_And32,
- unop(Iop_64HIto32,
- mkexpr(t0)),
- mkU32(0x80000000)),
- binop(Iop_And32,
- getIReg(rt),
- mkU32(0x80000000))),
- getDSPControl(),
- mkexpr(t2)));
+ /* Check if bits 63..31 of the result in t1 aren't 0. */
+ assign(t3, binop(Iop_CmpNE32,
+ unop(Iop_64HIto32,
+ mkexpr(t1)),
+ mkU32(0)));
assign(t4, binop(Iop_CmpNE32,
- unop(Iop_64HIto32, mkexpr(t1)),
+ binop(Iop_And32,
+ unop(Iop_64to32,
+ mkexpr(t1)),
+ mkU32(0x80000000)),
+ mkU32(0)));
+ /* Check if bits 63..31 of the result in t1 aren't
+ 0x1ffffffff. */
+ assign(t5, binop(Iop_CmpNE32,
+ unop(Iop_64HIto32,
+ mkexpr(t1)),
+ mkU32(0xffffffff)));
+ assign(t6, binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ unop(Iop_64to32,
+ mkexpr(t1)),
+ mkU32(0x80000000)),
+ mkU32(0x80000000)));
+ /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
+ control register. */
+ assign(t7, binop(Iop_And32,
+ binop(Iop_Or32,
+ unop(Iop_1Sto32, mkexpr(t3)),
+ unop(Iop_1Sto32, mkexpr(t4))),
+ binop(Iop_Or32,
+ unop(Iop_1Sto32, mkexpr(t5)),
+ unop(Iop_1Sto32, mkexpr(t6)))));
+ putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
+ mkexpr(t7),
+ mkU32(0)),
+ binop(Iop_Or32,
+ getDSPControl(),
+ mkU32(0x00800000)),
+ getDSPControl()));
+
+ /* If the last discarded bit is 1, there would be carry
+ when rounding, otherwise there wouldn't. We use that
+ fact and just add the value of the last discarded bit
+ to the least sifgnificant bit of the shifted value
+ from acc. */
+ assign(t8,
+ IRExpr_ITE(binop(Iop_CmpEQ32,
+ unop(Iop_8Uto32,
+ mkexpr(t15)),
+ mkU32(0)),
+ mkU64(0x0ULL),
+ binop(Iop_And64,
+ binop(Iop_Shr64,
+ mkexpr(t0),
+ unop(Iop_32to8,
+ binop(Iop_Sub32,
+ unop(Iop_8Uto32,
+ mkexpr(t15)),
+ mkU32(1)))),
+ mkU64(0x1ULL))));
+
+ assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
+
+ /* Repeat previous steps for the rounded value. */
+ assign(t10, binop(Iop_CmpNE32,
+ unop(Iop_64HIto32,
+ mkexpr(t9)),
+ mkU32(0)));
+ assign(t11, binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ unop(Iop_64to32,
+ mkexpr(t9)),
+ mkU32(0x80000000)),
+ mkU32(0)));
+
+ assign(t12, binop(Iop_CmpNE32,
+ unop(Iop_64HIto32,
+ mkexpr(t9)),
mkU32(0xffffffff)));
+ assign(t13, binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ unop(Iop_64to32,
+ mkexpr(t9)),
+ mkU32(0x80000000)),
+ mkU32(0x80000000)));
+
+ assign(t14, binop(Iop_And32,
+ binop(Iop_Or32,
+ unop(Iop_1Sto32, mkexpr(t10)),
+ unop(Iop_1Sto32, mkexpr(t11))),
+ binop(Iop_Or32,
+ unop(Iop_1Sto32, mkexpr(t12)),
+ unop(Iop_1Sto32, mkexpr(t13)))));
putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
- unop(Iop_64HIto32,
- mkexpr(t1)),
- mkU32(0x0)),
- IRExpr_ITE(mkexpr(t4),
- mkexpr(t2),
- mkexpr(t3)),
- mkexpr(t3)));
+ mkexpr(t14),
+ mkU32(0)),
+ binop(Iop_Or32,
+ getDSPControl(),
+ mkU32(0x00800000)),
+ getDSPControl()));
break;
}
case 0x2: { /* EXTP */
@@ -3140,61 +3313,131 @@
t0 = newTemp(Ity_I64);
t1 = newTemp(Ity_I64);
t2 = newTemp(Ity_I32);
- t4 = newTemp(Ity_I32);
- t5 = newTemp(Ity_I64);
- t6 = newTemp(Ity_I64);
+ t3 = newTemp(Ity_I1);
+ t4 = newTemp(Ity_I1);
+ t5 = newTemp(Ity_I1);
+ t6 = newTemp(Ity_I1);
+ t7 = newTemp(Ity_I32);
+ t8 = newTemp(Ity_I64);
+ t9 = newTemp(Ity_I64);
+ t10 = newTemp(Ity_I1);
+ t11 = newTemp(Ity_I1);
+ t12 = newTemp(Ity_I1);
+ t13 = newTemp(Ity_I1);
+ t14 = newTemp(Ity_I32);
+ t15 = newTemp(Ity_I64);
+ t16 = newTemp(Ity_I1);
assign(t0, getAcc(ac));
- if (0 == rs) {
- putIReg(rt, unop(Iop_64to32, mkexpr(t0)));
- } else {
- assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs)));
+ assign(t16, binop(Iop_CmpEQ32,
+ mkU32(rs),
+ mkU32(0)));
+ assign(t1, IRExpr_ITE(mkexpr(t16),
+ mkexpr(t0),
+ binop(Iop_Sar64,
+ mkexpr(t0),
+ mkU8(rs))));
+ /* If the last discarded bit is 1, there would be carry
+ when rounding, otherwise there wouldn't. We use that
+ fact and just add the value of the last discarded bit
+ to the least significant bit of the shifted value
+ from acc. */
+ assign(t15, binop(Iop_Shr64,
+ mkexpr(t0),
+ unop(Iop_32to8,
+ binop(Iop_Sub32,
+ binop(Iop_And32,
+ mkU32(rs),
+ mkU32(0x1f)),
+ mkU32(1)))));
- assign(t2, binop(Iop_Or32,
- getDSPControl(), mkU32(0x800000)));
+ assign(t8,
+ IRExpr_ITE(mkexpr(t16),
+ mkU64(0x0ULL),
+ binop(Iop_And64,
+ mkexpr(t15),
+ mkU64(0x0000000000000001ULL))));
+ assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
+ putIReg(rt, unop(Iop_64to32, mkexpr(t9)));
- putDSPControl(IRExpr_ITE(
- binop(Iop_CmpNE32,
- unop(Iop_64HIto32, mkexpr(t1)),
- mkU32(0x0)),
- IRExpr_ITE(binop(Iop_CmpNE32,
- unop(Iop_64HIto32,
- mkexpr(t1)),
- mkU32(0xffffffff)),
- mkexpr(t2),
- getDSPControl()),
- getDSPControl()));
+ /* Check if bits 63..31 of the result in t1 aren't 0. */
+ assign(t3, binop(Iop_CmpNE32,
+ unop(Iop_64HIto32,
+ mkexpr(t1)),
+ mkU32(0)));
+ assign(t4, binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ unop(Iop_64to32,
+ mkexpr(t1)),
+ mkU32(0x80000000)),
+ mkU32(0)));
- assign(t4, binop(Iop_Or32,
- getDSPControl(), mkU32(0x800000)));
- /* If the last discarded bit is 1, there would be carry
- when rounding, otherwise there wouldn't. We use that
- fact and just add the value of the last discarded bit
- to the least sifgnificant bit of the shifted value
- from acc. */
- assign(t5, binop(Iop_Shr64,
- binop(Iop_And64,
- mkexpr(t0),
- binop(Iop_Shl64,
- mkU64(0x1ULL),
- mkU8(rs-1))),
- mkU8(rs-1)));
+ /* Check if bits 63..31 of the result in t1 aren't
+ 0x1ffffffff. */
+ assign(t5, binop(Iop_CmpNE32,
+ unop(Iop_64HIto32,
+ mkexpr(t1)),
+ mkU32(0xffffffff)));
+ assign(t6, binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ unop(Iop_64to32,
+ mkexpr(t1)),
+ mkU32(0x80000000)),
+ mkU32(0x80000000)));
+ /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
+ control register. */
+ assign(t7, binop(Iop_And32,
+ binop(Iop_Or32,
+ unop(Iop_1Sto32, mkexpr(t3)),
+ unop(Iop_1Sto32, mkexpr(t4))),
+ binop(Iop_Or32,
+ unop(Iop_1Sto32, mkexpr(t5)),
+ unop(Iop_1Sto32, mkexpr(t6)))));
+ putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
+ mkexpr(t7),
+ mkU32(0)),
+ binop(Iop_Or32,
+ getDSPControl(),
+ mkU32(0x00800000)),
+ getDSPControl()));
- assign(t6, binop(Iop_Add64, mkexpr(t1), mkexpr(t5)));
+ /* Repeat previous steps for the rounded value. */
+ assign(t10, binop(Iop_CmpNE32,
+ unop(Iop_64HIto32,
+ mkexpr(t9)),
+ mkU32(0)));
+ assign(t11, binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ unop(Iop_64to32,
+ mkexpr(t9)),
+ mkU32(0x80000000)),
+ mkU32(0)));
- putDSPControl(IRExpr_ITE(
- binop(Iop_CmpNE32,
- unop(Iop_64HIto32, mkexpr(t6)),
- mkU32(0x0)),
- IRExpr_ITE(binop(Iop_CmpNE32,
- unop(Iop_64HIto32,
- mkexpr(t6)),
- mkU32(0xffffffff)),
- mkexpr(t4),
- getDSPControl()),
- getDSPControl()));
- putIReg(rt, unop(Iop_64to32, mkexpr(t6)));
- }
+ assign(t12, binop(Iop_CmpNE32,
+ unop(Iop_64HIto32,
+ mkexpr(t9)),
+ mkU32(0xffffffff)));
+ assign(t13, binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ unop(Iop_64to32,
+ mkexpr(t9)),
+ mkU32(0x80000000)),
+ mkU32(0x80000000)));
+
+ assign(t14, binop(Iop_And32,
+ binop(Iop_Or32,
+ unop(Iop_1Sto32, mkexpr(t10)),
+ unop(Iop_1Sto32, mkexpr(t11))),
+ binop(Iop_Or32,
+ unop(Iop_1Sto32, mkexpr(t12)),
+ unop(Iop_1Sto32, mkexpr(t13)))));
+ putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
+ mkexpr(t14),
+ mkU32(0)),
+ binop(Iop_Or32,
+ getDSPControl(),
+ mkU32(0x00800000)),
+ getDSPControl()));
break;
}
case 0x5: { /* EXTRV_R.W */
@@ -3203,79 +3446,129 @@
t0 = newTemp(Ity_I64);
t1 = newTemp(Ity_I64);
t2 = newTemp(Ity_I32);
- t4 = newTemp(Ity_I32);
- t5 = newTemp(Ity_I64);
- t6 = newTemp(Ity_I64);
-
- assign(t0, getAcc(ac));
-
- assign(t1, binop(Iop_Sar64,
- mkexpr(t0),
- unop(Iop_32to8,
- binop(Iop_And32,
- getIReg(rs),
- mkU32(0x1f)))));
+ t3 = newTemp(Ity_I1);
+ t4 = newTemp(Ity_I1);
+ t5 = newTemp(Ity_I1);
+ t6 = newTemp(Ity_I1);
+ t7 = newTemp(Ity_I32);
+ t8 = newTemp(Ity_I64);
+ t9 = newTemp(Ity_I64);
+ t10 = newTemp(Ity_I1);
+ t11 = newTemp(Ity_I1);
+ t12 = newTemp(Ity_I1);
+ t13 = newTemp(Ity_I1);
+ t14 = newTemp(Ity_I32);
+ t15 = newTemp(Ity_I8);
- assign(t2, binop(Iop_Or32,
- getDSPControl(), mkU32(0x00800000)));
+ assign(t15, unop(Iop_32to8,
+ binop(Iop_And32,
+ getIReg(rs),
+ mkU32(0x1f))));
+ assign(t0, getAcc(ac));
+ assign(t1, binop(Iop_Sar64, mkexpr(t0), mkexpr(t15)));
- putDSPControl(IRExpr_ITE(
- binop(Iop_CmpNE32,
- unop(Iop_64HIto32, mkexpr(t1)),
- mkU32(0x0)),
- IRExpr_ITE(binop(Iop_CmpNE32,
- unop(Iop_64HIto32,
- mkexpr(t1)),
- mkU32(0xffffffff)),
- mkexpr(t2),
- getDSPControl()),
- getDSPControl()));
+ /* Check if bits 63..31 of the result in t1 aren't 0. */
+ assign(t3, binop(Iop_CmpNE32,
+ unop(Iop_64HIto32,
+ mkexpr(t1)),
+ mkU32(0)));
+ assign(t4, binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ unop(Iop_64to32,
+ mkexpr(t1)),
+ mkU32(0x80000000)),
+ mkU32(0)));
+ /* Check if bits 63..31 of the result in t1 aren't
+ 0x1ffffffff. */
+ assign(t5, binop(Iop_CmpNE32,
+ unop(Iop_64HIto32,
+ mkexpr(t1)),
+ mkU32(0xffffffff)));
+ assign(t6, binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ unop(Iop_64to32,
+ mkexpr(t1)),
+ mkU32(0x80000000)),
+ mkU32(0x80000000)));
+ /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
+ control register. */
+ assign(t7, binop(Iop_And32,
+ binop(Iop_Or32,
+ unop(Iop_1Sto32, mkexpr(t3)),
+ unop(Iop_1Sto32, mkexpr(t4))),
+ binop(Iop_Or32,
+ unop(Iop_1Sto32, mkexpr(t5)),
+ unop(Iop_1Sto32, mkexpr(t6)))));
+ putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
+ mkexpr(t7),
+ mkU32(0)),
+ binop(Iop_Or32,
+ getDSPControl(),
+ mkU32(0x00800000)),
+ getDSPControl()));
- assign(t4, binop(Iop_Or32,
- getDSPControl(), mkU32(0x00800000)));
/* If the last discarded bit is 1, there would be carry
when rounding, otherwise there wouldn't. We use that
- fact and just add the value of the last discarded bit to
- the least sifgnificant bit of the shifted value from
- acc. */
- assign(t5, binop(Iop_Shr64,
- binop(Iop_And64,
- mkexpr(t0),
- binop(Iop_Shl64,
- mkU64(0x1ULL),
- unop(Iop_32to8,
- binop(Iop_Sub32,
- binop(Iop_And32,
- getIReg(rs),
- mkU32(0x1f)),
- mkU32(0x1))))),
- unop(Iop_32to8,
- binop(Iop_Sub32,
- binop(Iop_And32,
- getIReg(rs),
- mkU32(0x1f)),
- mkU32(0x1)))));
+ fact and just add the value of the last discarded bit
+ to the least sifgnificant bit of the shifted value
+ from acc. */
+ assign(t8,
+ IRExpr_ITE(binop(Iop_CmpEQ32,
+ unop(Iop_8Uto32,
+ mkexpr(t15)),
+ mkU32(0)),
+ mkU64(0x0ULL),
+ binop(Iop_And64,
+ binop(Iop_Shr64,
+ mkexpr(t0),
+ unop(Iop_32to8,
+ binop(Iop_Sub32,
+ unop(Iop_8Uto32,
+ mkexpr(t15)),
+ mkU32(1)))),
+ mkU64(0x1ULL))));
+
+ assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
+ /* Put rounded value in destination register. */
+ putIReg(rt, unop(Iop_64to32, mkexpr(t9)));
+
+ /* Repeat previous steps for the rounded value. */
+ assign(t10, binop(Iop_CmpNE32,
+ unop(Iop_64HIto32,
+ mkexpr(t9)),
+ mkU32(0)));
+ assign(t11, binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ unop(Iop_64to32,
+ mkexpr(t9)),
+ mkU32(0x80000000)),
+ mkU32(0)));
- assign(t6, binop(Iop_Add64, mkexpr(t1), mkexpr(t5)));
+ assign(t12, binop(Iop_CmpNE32,
+ unop(Iop_64HIto32,
+ mkexpr(t9)),
+ mkU32(0xffffffff)));
+ assign(t13, binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ unop(Iop_64to32,
+ mkexpr(t9)),
+ mkU32(0x80000000)),
+ mkU32(0x80000000)));
- putDSPControl(IRExpr_ITE(
- binop(Iop_CmpNE32,
- unop(Iop_64HIto32, mkexpr(t6)),
- mkU32(0x0)),
- IRExpr_ITE(binop(Iop_CmpNE32,
- unop(Iop_64HIto32,
- mkexpr(t6)),
- mkU32(0xffffffff)),
- mkexpr(t4),
- getDSPControl()),
- getDSPControl()));
- putIReg(rt, IRExpr_ITE(binop(Iop_CmpEQ32,
- binop(Iop_And32,
- getIReg(rs),
- mkU32(0x1f)),
- mkU32(0x0)),
- unop(Iop_64to32, mkexpr(t0)),
- unop(Iop_64to32, mkexpr(t6))));
+ assign(t14, binop(Iop_And32,
+ binop(Iop_Or32,
+ unop(Iop_1Sto32, mkexpr(t10)),
+ unop(Iop_1Sto32, mkexpr(t11))),
+ binop(Iop_Or32,
+ unop(Iop_1Sto32, mkexpr(t12)),
+ unop(Iop_1Sto32, mkexpr(t13)))));
+ putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
+ mkexpr(t14),
+ mkU32(0)),
+ binop(Iop_Or32,
+ getDSPControl(),
+ mkU32(0x00800000)),
+ getDSPControl()));
break;
}
case 0x6: { /* EXTR_RS.W */
@@ -3283,81 +3576,136 @@
vassert(!mode64);
t0 = newTemp(Ity_I64);
t1 = newTemp(Ity_I64);
- t2 = newTemp(Ity_I64);
- t3 = newTemp(Ity_I32);
- t4 = newTemp(Ity_I32);
- t5 = newTemp(Ity_I32);
- t6 = newTemp(Ity_I32);
+ t2 = newTemp(Ity_I32);
+ t3 = newTemp(Ity_I1);
+ t4 = newTemp(Ity_I1);
+ t5 = newTemp(Ity_I1);
+ t6 = newTemp(Ity_I1);
+ t7 = newTemp(Ity_I32);
+ t8 = newTemp(Ity_I64);
+ t9 = newTemp(Ity_I64);
+ t10 = newTemp(Ity_I1);
+ t11 = newTemp(Ity_I1);
+ t12 = newTemp(Ity_I1);
+ t13 = newTemp(Ity_I1);
+ t14 = newTemp(Ity_I32);
+ t16 = newTemp(Ity_I32);
- if (0 != rs) {
- assign(t0, getAcc(ac));
+ assign(t0, getAcc(ac));
+ if (0 == rs) {
+ assign(t1, mkexpr(t0));
+ } else {
assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs)));
- putDSPControl(IRExpr_ITE(
- binop(Iop_CmpNE32,
- unop(Iop_64HIto32, mkexpr(t1)),
- mkU32(0x0)),
- IRExpr_ITE(binop(Iop_CmpNE32,
- unop(Iop_64HIto32,
- mkexpr(t1)),
- mkU32(0xffffffff)),
- binop(Iop_Or32,
- getDSPControl(),
- mkU32(0x00800000)),
- getDSPControl()),
- getDSPControl()));
- /* If the last discarded bit is 1, there would be carry
- when rounding, otherwise there wouldn't. We use that
- fact and just add the value of the last discarded bit
- to the least sifgnificant bit of the shifted value
- from acc. */
- assign(t2, binop(Iop_Add64,
- mkexpr(t1),
- binop(Iop_Shr64,
- binop(Iop_And64,
- mkexpr(t0),
- binop(Iop_Shl64,
- mkU64(0x1ULL),
- unop(Iop_32to8,
- mkU32(rs-1)))),
- unop(Iop_32to8, mkU32(rs-1)))));
- assign(t6, IRExpr_ITE(binop(Iop_CmpNE32,
- unop(Iop_64HIto32,
- mkexpr(t2)),
- mkU32(0xffffffff)),
+ }
+
+ /* Check if bits 63..31 of the result in t1 aren't 0. */
+ assign(t3, binop(Iop_CmpNE32,
+ unop(Iop_64HIto32,
+ mkexpr(t1)),
+ mkU32(0)));
+ assign(t4, binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ unop(Iop_64to32,
+ mkexpr(t1)),
+ mkU32(0x80000000)),
+ mkU32(0)));
+ /* Check if bits 63..31 of the result in t1 aren't
+ 0x1ffffffff. */
+ assign(t5, binop(Iop_CmpNE32,
+ unop(Iop_64HIto32,
+ mkexpr(t1)),
+ mkU32(0xffffffff)));
+ assign(t6, binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ unop(Iop_64to32,
+ mkexpr(t1)),
+ mkU32(0x80000000)),
+ mkU32(0x80000000)));
+ /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
+ control register. */
+ assign(t7, binop(Iop_And32,
+ binop(Iop_Or32,
+ unop(Iop_1Sto32, mkexpr(t3)),
+ unop(Iop_1Sto32, mkexpr(t4))),
+ binop(Iop_Or32,
+ unop(Iop_1Sto32, mkexpr(t5)),
+ unop(Iop_1Sto32, mkexpr(t6)))));
+ putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
+ mkexpr(t7),
+ mkU32(0)),
binop(Iop_Or32,
getDSPControl(),
mkU32(0x00800000)),
getDSPControl()));
- putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
- unop(Iop_64HIto32,
- mkexpr(t2)),
- mkU32(0x0)),
- mkexpr(t6),
- getDSPControl()));
- assign(t3, IRExpr_ITE(binop(Iop_CmpEQ32,
- binop(Iop_And32,
- unop(Iop_64HIto32,
- mkexpr(t2)),
- mkU32(0x80000000)),
- mkU32(0x0)),
- mkU32(0x7fffffff),
- mkU32(0x80000000)));
- assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
- unop(Iop_64HIto32,
- mkexpr(t2)),
- mkU32(0xffffffff)),
- mkexpr(t3),
- unop(Iop_64to32, mkexpr(t2))));
- assign(t5, IRExpr_ITE(binop(Iop_CmpNE32,
- unop(Iop_64HIto32,
- mkexpr(t2)),
- mkU32(0x0)),
- mkexpr(t4),
- unop(Iop_64to32, mkexpr(t2))));
- putIReg(rt, mkexpr(t5));
+
+ /* If the last discarded bit is 1, there would be carry
+ when rounding, otherwise there wouldn't. We use that
+ fact and just add the value of the last discarded bit
+ to the least sifgnificant bit of the shifted value
+ from acc. */
+ if (0 == rs) {
+ assign(t8, mkU64(0x0ULL));
} else {
- putIReg(rt, unop(Iop_64to32, getAcc(ac)));
+ assign(t8, binop(Iop_And64,
+ binop(Iop_Shr64,
+ mkexpr(t0),
+ mkU8(rs-1)),
+ mkU64(0x1ULL)));
}
+
+ assign(t9, binop(Iop_Add64, mkexpr(t1), mkexpr(t8)));
+
+ /* Repeat previous steps for the rounded value. */
+ assign(t10, binop(Iop_CmpNE32,
+ unop(Iop_64HIto32,
+ mkexpr(t9)),
+ mkU32(0)));
+ assign(t11, binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ unop(Iop_64to32,
+ mkexpr(t9)),
+ mkU32(0x80000000)),
+ mkU32(0)));
+
+ assign(t12, binop(Iop_CmpNE32,
+ unop(Iop_64HIto32,
+ mkexpr(t9)),
+ mkU32(0xffffffff)));
+ assign(t13, binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ unop(Iop_64to32,
+ mkexpr(t9)),
+ mkU32(0x80000000)),
+ mkU32(0x80000000)));
+
+ assign(t14, binop(Iop_And32,
+ binop(Iop_Or32,
+ unop(Iop_1Sto32, mkexpr(t10)),
+ unop(Iop_1Sto32, mkexpr(t11))),
+ binop(Iop_Or32,
+ unop(Iop_1Sto32, mkexpr(t12)),
+ unop(Iop_1Sto32, mkexpr(t13)))));
+ putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
+ mkexpr(t14),
+ mkU32(0)),
+ binop(Iop_Or32,
+ getDSPControl(),
+ mkU32(0x00800000)),
+ getDSPControl()));
+
+ assign(t16, binop(Iop_And32,
+ unop(Iop_64HIto32,
+ mkexpr(t9)),
+ mkU32(0x80000000)));
+ putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32,
+ mkexpr(t14),
+ mkU32(0)),
+ IRExpr_ITE(binop(Iop_CmpEQ32,
+ mkexpr(t16),
+ mkU32(0)),
+ mkU32(0x7fffffff),
+ mkU32(0x80000000)),
+ unop(Iop_64to32, mkexpr(t9))));
break;
}
case 0x7: { /* EXTRV_RS.W */
@@ -3366,104 +3714,146 @@
t0 = newTemp(Ity_I64);
t1 = newTemp(Ity_I64);
t2 = newTemp(Ity_I32);
- t4 = newTemp(Ity_I32);
- t5 = newTemp(Ity_I64);
- t6 = newTemp(Ity_I64);
+ t3 = newTemp(Ity_I1);
+ t4 = newTemp(Ity_I1);
+ t5 = newTemp(Ity_I1);
+ t6 = newTemp(Ity_I1);
t7 = newTemp(Ity_I32);
- t8 = newTemp(Ity_I32);
- t9 = newTemp(Ity_I32);
- t10 = newTemp(Ity_I32);
+ t8 = newTemp(Ity_I64);
+ t9 = newTemp(Ity_I64);
+ t10 = newTemp(Ity_I1);
+ t11 = newTemp(Ity_I1);
+ t12 = newTemp(Ity_I1);
+ t13 = newTemp(Ity_I1);
+ t14 = newTemp(Ity_I32);
+ t15 = newTemp(Ity_I32);
+ t16 = newTemp(Ity_I32);
+ t17 = newTemp(Ity_I1);
+ assign(t15, binop(Iop_And32,
+ getIReg(rs),
+ mkU32(0x1f)));
+ assign(t17, binop(Iop_CmpEQ32,
+ mkexpr(t15),
+ mkU32(0)));
assign(t0, getAcc(ac));
+ assign(t1, IRExpr_ITE(mkexpr(t17),
+ mkexpr(t0),
+ binop(Iop_Sar64,
+ mkexpr(t0),
+ unop(Iop_32to8,
+ mkexpr(t15)))));
- assign(t1, binop(Iop_Sar64,
- mkexpr(t0),
- unop(Iop_32to8, binop(Iop_And32,
- getIReg(rs),
- mkU32(0x1f)))));
-
- assign(t2, binop(Iop_Or32,
- getDSPControl(), mkU32(0x00800000)));
-
- assign(t10, IRExpr_ITE(binop(Iop_CmpNE32,
- unop(Iop_64HIto32,
- mkexpr(t1)),
- mkU32(0x0)),
- IRExpr_ITE(binop(Iop_CmpNE32,
- unop(Iop_64HIto32,
- mkexpr(t1)),
- mkU32(0xffffffff)),
- mkexpr(t2),
- getDSPControl()),
- getDSPControl()));
-
- putDSPControl(mkexpr(t10));
+ /* Check if bits 63..31 of the result in t1 aren't 0. */
+ assign(t3, binop(Iop_CmpNE32,
+ unop(Iop_64HIto32,
+ mkexpr(t1)),
+ mkU32(0)));
+ assign(t4, binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ unop(Iop_64to32,
+ mkexpr(t1)),
+ mkU32(0x80000000)),
+ mkU32(0)));
+ /* Check if bits 63..31 of the result in t1 aren't
+ 0x1ffffffff. */
+ assign(t5, binop(Iop_CmpNE32,
+ unop(Iop_64HIto32,
+ mkexpr(t1)),
+ mkU32(0xffffffff)));
+ assign(t6, binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ unop(Iop_64to32,
+ mkexpr(t1)),
+ mkU32(0x80000000)),
+ mkU32(0x80000000)));
+ /* If bits 63..31 aren't 0 nor 0x1ffffffff, set DSP
+ control register. */
+ assign(t7, binop(Iop_And32,
+ binop(Iop_Or32,
+ unop(Iop_1Sto32, mkexpr(t3)),
+ unop(Iop_1Sto32, mkexpr(t4))),
+ binop(Iop_Or32,
+ unop(Iop_1Sto32, mkexpr(t5)),
+ unop(Iop_1Sto32, mkexpr(t6)))));
+ putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
+ mkexpr(t7),
+ mkU32(0)),
+ binop(Iop_Or32,
+ getDSPControl(),
+ mkU32(0x00800000)),
+ getDSPControl()));
- assign(t4, binop(Iop_Or32,
- getDSPControl(), mkU32(0x00800000)));
/* If the last discarded bit is 1, there would be carry
when rounding, otherwise there wouldn't. We use that
- fact and just add the value of the last discarded bit to
- the least sifgnificant bit of the shifted value from
- acc. */
- assign(t5, binop(Iop_Shr64,
- binop(Iop_And64,
- mkexpr(t0),
- binop(Iop_Shl64,
- mkU64(0x1ULL),
- unop(Iop_32to8,
- binop(Iop_Sub32,
- binop(Iop_And32,
- getIReg(rs),
- ...
[truncated message content] |