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);
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));
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 */
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));
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;
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 */
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 */
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)));
+
+ /* 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)));
- 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()));
-
- 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 */
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 */
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 */
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),
- 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(mkexpr(t17),
+ mkU64(0x0ULL),
+ binop(Iop_And64,
+ binop(Iop_Shr64,
+ mkexpr(t0),
+ unop(Iop_32to8,
+ binop(Iop_Sub32,
+ 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(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)));
- assign(t8, IRExpr_ITE(binop(Iop_CmpNE32,
- unop(Iop_64HIto32,
- mkexpr(t6)),
- mkU32(0xffffffff)),
- mkexpr(t4),
- getDSPControl()));
+ 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(t6)),
- mkU32(0x0)),
- mkexpr(t8),
+ mkexpr(t14),
+ mkU32(0)),
+ binop(Iop_Or32,
+ getDSPControl(),
+ mkU32(0x00800000)),
getDSPControl()));
- assign(t9, IRExpr_ITE(binop(Iop_CmpEQ32,
- binop(Iop_And32,
- unop(Iop_64HIto32,
- mkexpr(t6)),
+
+ 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)),
- mkU32(0x0)),
- mkU32(0x7fffffff),
- mkU32(0x80000000)));
- assign(t7, 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(t9),
- unop(Iop_64to32,
- mkexpr(t6))),
- unop(Iop_64to32, mkexpr(t6))));
- putIReg(rt, IRExpr_ITE(binop(Iop_CmpEQ32,
- binop(Iop_And32,
- getIReg(rs),
- mkU32(0x1f)),
- mkU32(0x0)),
- unop(Iop_64to32, mkexpr(t0)),
- mkexpr(t7)));
+ unop(Iop_64to32, mkexpr(t9))));
break;
}
case 0xA: { /* EXTPDP */
t5 = newTemp(Ity_I32);
t6 = newTemp(Ity_I64);
t7 = newTemp(Ity_I32);
- t8 = newTemp(Ity_I32);
t9 = newTemp(Ity_I32);
- t10 = newTemp(Ity_I1);
assign(t0, getAcc(ac));
assign(t2, binop(Iop_Or32,
getDSPControl(), mkU32(0x00800000)));
- assign(t9, binop(Iop_Shl32,
- binop(Iop_And32,
- unop(Iop_64to32,
- mkexpr(t1)),
- mkU32(0x00008000)),
- mkU8(16)));
+ assign(t9, binop(Iop_And32,
+ unop(Iop_64to32,
+ mkexpr(t1)),
+ mkU32(0x80000000)));
putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
mkexpr(t9),
binop(Iop_And32,
assign(t3, binop(Iop_Sub64,
mkexpr(t1),
mkU64(0x0000000000007fffULL)));
- assign(t4, binop(Iop_Or32,
- unop(Iop_1Uto32,
- binop(Iop_CmpNE32,
- mkU32(0),
- binop(Iop_And32,
- unop(Iop_64HIto32,
- mkexpr(t3)),
- mkU32(0x7fffffff)))),
- unop(Iop_1Uto32,
- binop(Iop_CmpNE32,
- mkU32(0),
- binop(Iop_And32,
+ assign(t4, binop(Iop_And32,
+ binop(Iop_Or32,
+ unop(Iop_1Sto32,
+ binop(Iop_CmpNE32,
+ mkU32(0),
+ binop(Iop_And32,
+ unop(Iop_64HIto32,
+ mkexpr(t3)),
+ mkU32(0x7fffffff)))),
+ unop(Iop_1Sto32,
+ binop(Iop_CmpNE32,
+ mkU32(0),
unop(Iop_64to32,
- mkexpr(t3)),
- mkU32(0xffffffff))))));
-
- assign(t5, IRExpr_ITE(unop(Iop_32to1,
- binop(Iop_Shr32,
- binop(Iop_And32,
- unop(Iop_64HIto32,
- mkexpr(t3)),
- mkU32(0x80000000)),
- mkU8(31))),
- unop(Iop_64to32, mkexpr(t1)),
- IRExpr_ITE(binop(Iop_CmpNE32,
- mkexpr(t4),
- mkU32(0x0)),
- mkU32(0x7fff),
- unop(Iop_64to32,
- mkexpr(t1)))));
-
- assign(t10, unop(Iop_32to1,
- binop(Iop_Shr32,
- binop(Iop_And32,
- unop(Iop_64HIto32,
- mkexpr(t3)),
- mkU32(0x80000000)),
- mkU8(31))));
- putDSPControl(IRExpr_ITE(mkexpr(t10),
- getDSPControl(),
- IRExpr_ITE(binop(Iop_CmpNE32,
- mkexpr(t4),
- mkU32(0x0)),
- binop(Iop_Or32,
- getDSPControl(),
- mkU32(0x00800000)),
- getDSPControl())));
-
+ mkexpr(t3))))),
+ unop(Iop_1Sto32,
+ binop(Iop_CmpEQ32,
+ binop(Iop_And32,
+ unop(Iop_64HIto32,
+ mkexpr(t3)),
+ mkU32(0x80000000)),
+ mkU32(0)))));
+ putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
+ mkU32(0),
+ mkexpr(t4)),
+ binop(Iop_Or32,
+ getDSPControl(),
+ mkU32(0x00800000)),
+ getDSPControl()));
/* Check if t1<0xffffffffffff8000 (0xffffffffffff8000-t1)>0
- 1. subtract t1 from 0x7fff
+ 1. subtract t1 from 0xffffffffffff8000
2. if the resulting number is positive (sign bit = 0)
and any of the other bits is 1, the value is > 0 */
assign(t6, binop(Iop_Sub64,
mkU64(0xffffffffffff8000ULL),
mkexpr(t1)));
-
- assign(t7, binop(Iop_Or32,
- unop(Iop_1Uto32,
- binop(Iop_CmpNE32,
- mkU32(0),
- binop(Iop_And32,
- unop(Iop_64HIto32,
- mkexpr(t6)),
- mkU32(0x7fffffff)))),
- unop(Iop_1Uto32,
- binop(Iop_CmpNE32,
- mkU32(0),
- binop(Iop_And32,
- unop(Iop_64to32,
- mkexpr(t6)),
- mkU32(0xffffffff))))));
-
- assign(t8, IRExpr_ITE(unop(Iop_32to1,
- binop(Iop_Shr32,
- binop(Iop_And32,
- unop(Iop_64HIto32,
- mkexpr(t6)),
- mkU32(0x80000000)),
- mkU8(31))),
- unop(Iop_64to32, mkexpr(t1)),
- IRExpr_ITE(binop(Iop_CmpNE32,
- mkexpr(t7),
- mkU32(0x0)),
- mkU32(0xffff8000),
- unop(Iop_64to32,
- mkexpr(t1)))));
- putDSPControl(IRExpr_ITE(unop(Iop_32to1,
- binop(Iop_Shr32,
- binop(Iop_And32,
- unop(Iop_64HIto32,
- mkexpr(t6)),
- mkU32(0x80000000)),
- mkU8(31))),
- getDSPControl(),
- IRExpr_ITE(binop(Iop_CmpNE32,
- mkexpr(t7),
- mkU32(0x0)),
- binop(Iop_Or32,
- getDSPControl(),
- mkU32(0x00800000)),
- getDSPControl())));
-
- /* If the shifted value is positive, it can only be >0x7fff
- and the final result is the value stored in t5,
- otherwise, the final result is in t8. */
- putIReg(rt, IRExpr_ITE(unop(Iop_32to1,
- binop(Iop_Shr32,
+ assign(t7, binop(Iop_And32,
+ binop(Iop_Or32,
+ unop(Iop_1Sto32,
+ binop(Iop_CmpNE32,
+ mkU32(0),
binop(Iop_And32,
unop(Iop_64HIto32,
- mkexpr(t1)),
+ mkexpr(t6)),
+ mkU32(0x7fffffff)))),
+ unop(Iop_1Sto32,
+ binop(Iop_CmpNE32,
+ mkU32(0),
+ unop(Iop_64to32,
+ mkexpr(t6))))),
+ unop(Iop_1Sto32,
+ binop(Iop_CmpEQ32,
+ binop(Iop_And32,
+ unop(Iop_64HIto32,
+ mkexpr(t6)),
mkU32(0x80000000)),
- mkU8(31))),
- mkexpr(t8),
- mkexpr(t5)));
+ mkU32(0)))));
+ putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
+ mkU32(0),
+ mkexpr(t7)),
+ binop(Iop_Or32,
+ getDSPControl(),
+ mkU32(0x00800000)),
+ getDSPControl()));
+ putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32,
+ mkU32(0),
+ mkexpr(t4)),
+ mkU32(0x00007fff),
+ IRExpr_ITE(binop(Iop_CmpNE32,
+ mkU32(0),
+ mkexpr(t7)),
+ mkU32(0xffff8000),
+ unop(Iop_64to32,
+ mkexpr(t1)))));
break;
}
case 0xF: { /* EXTRV_S.H */
t5 = newTemp(Ity_I32);
t6 = newTemp(Ity_I64);
t7 = newTemp(Ity_I32);
- t8 = newTemp(Ity_I32);
t9 = newTemp(Ity_I32);
- t10 = newTemp(Ity_I32);
- t11 = newTemp(Ity_I32);
assign(t0, getAcc(ac));
assign(t2, binop(Iop_Or32,
getDSPControl(), mkU32(0x00800000)));
- assign(t9, binop(Iop_Shl32,
- binop(Iop_And32,
- unop(Iop_64to32,
- mkexpr(t1)),
- mkU32(0x00008000)),
- mkU8(16)));
+ assign(t9, binop(Iop_And32,
+ unop(Iop_64to32,
+ mkexpr(t1)),
+ mkU32(0x80000000)));
putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
mkexpr(t9),
binop(Iop_And32,
/* Check if t1 > 0x7fff ((t1 - 0x7fff) > 0)
1. subtract 0x7fff from t1
2. if the resulting number is positive (sign bit = 0)
- and any of the other bits is 1, the value is > 0 */
+ and any of the other bits is 1, the value is > 0. */
assign(t3, binop(Iop_Sub64,
mkexpr(t1),
mkU64(0x0000000000007fffULL)));
- assign(t4, binop(Iop_Or32,
- unop(Iop_1Uto32,
- binop(Iop_CmpNE32,
- mkU32(0),
- binop(Iop_And32,
- unop(Iop_64HIto32,
- mkexpr(t3)),
- mkU32(0x7fffffff)))),
- unop(Iop_1Uto32,
- binop(Iop_CmpNE32,
- mkU32(0),
- binop(Iop_And32,
+ assign(t4, binop(Iop_And32,
+ binop(Iop_Or32,
+ unop(Iop_1Sto32,
+ binop(Iop_CmpNE32,
+ mkU32(0),
+ binop(Iop_And32,
+ unop(Iop_64HIto32,
+ mkexpr(t3)),
+ mkU32(0x7fffffff)))),
+ unop(Iop_1Sto32,
+ binop(Iop_CmpNE32,
+ mkU32(0),
unop(Iop_64to32,
- mkexpr(t3)),
- mkU32(0xffffffff))))));
-
- assign(t5, IRExpr_ITE(unop(Iop_32to1,
- binop(Iop_Shr32,
- binop(Iop_And32,
- unop(Iop_64HIto32,
- mkexpr(t3)),
- mkU32(0x80000000)),
- mkU8(31))),
- unop(Iop_64to32, mkexpr(t1)),
- IRExpr_ITE(binop(Iop_CmpNE32,
- mkexpr(t4),
- mkU32(0x0)),
- mkU32(0x7fff),
- unop(Iop_64to32,
- mkexpr(t1)))));
-
- assign(t10, binop(Iop_Shr32,
- binop(Iop_And32,
- unop(Iop_64HIto32,
- mkexpr(t3)),
- mkU32(0x80000000)),
- mkU8(31)));
- assign(t11, IRExpr_ITE(binop(Iop_CmpNE32,
- mkexpr(t4),
- mkU32(0x0)),
- binop(Iop_Or32,
- getDSPControl(),
- mkU32(0x00800000)),
- getDSPControl()));
- putDSPControl(IRExpr_ITE(unop(Iop_32to1,
- mkexpr(t10)),
- getDSPControl(),
- mkexpr(t11)));
-
- /* Check if t1<0xffffffffffff8000
- 1. subtract t1 from 0x7fff
- 2. if the resulting number is positive (sign bit == 0)
+ mkexpr(t3))))),
+ unop(Iop_1Sto32,
+ binop(Iop_CmpEQ32,
+ binop(Iop_And32,
+ unop(Iop_64HIto32,
+ mkexpr(t3)),
+ mkU32(0x80000000)),
+ mkU32(0)))));
+ putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
+ mkU32(0),
+ mkexpr(t4)),
+ binop(Iop_Or32,
+ getDSPControl(),
+ mkU32(0x00800000)),
+ getDSPControl()));
+ /* Check if t1<0xffffffffffff8000 (0xffffffffffff8000-t1)>0
+ 1. subtract t1 from 0xffffffffffff8000
+ 2. if the resulting number is positive (sign bit = 0)
and any of the other bits is 1, the value is > 0 */
assign(t6, binop(Iop_Sub64,
- mkU64(0xffffffffffff8000ULL),
- mkexpr(t1)));
-
- assign(t7, binop(Iop_Or32,
- unop(Iop_1Uto32,
- binop(Iop_CmpNE32,
- mkU32(0),
- binop(Iop_And32,
- unop(Iop_64HIto32,
- mkexpr(t6)),
- mkU32(0x7fffffff)))),
- unop(Iop_1Uto32,
- binop(Iop_CmpNE32,
- mkU32(0),
- binop(Iop_And32,
- unop(Iop_64to32,
- mkexpr(t6)),
- mkU32(0xffffffff))))));
-
- assign(t8, IRExpr_ITE(unop(Iop_32to1,
- binop(Iop_Shr32,
- binop(Iop_And32,
- unop(Iop_64HIto32,
- mkexpr(t6)),
- mkU32(0x80000000)),
- mkU8(31))),
- unop(Iop_64to32, mkexpr(t1)),
- IRExpr_ITE(binop(Iop_CmpNE32,
- mkexpr(t7),
- mkU32(0x0)),
- mkU32(0xffff8000),
- unop(Iop_64to32,
- mkexpr(t1)))));
- putDSPControl(IRExpr_ITE(unop(Iop_32to1,
- binop(Iop_Shr32,
- binop(Iop_And32,
- unop(Iop_64HIto32,
- mkexpr(t6)),
- mkU32(0x80000000)
- ),
- mkU8(31))),
- getDSPControl(),
- IRExpr_ITE(binop(Iop_CmpNE32,
- mkexpr(t7),
- mkU32(0x0)),
- binop(Iop_Or32,
- getDSPControl(),
- mkU32(0x00800000)
- ),
- getDSPControl())));
-
- /* If the shifted value is positive, it can only be >0x7fff
- and the final result is the value stored in t5,
- otherwise, the final result is in t8. */
- putIReg(rt, IRExpr_ITE(unop(Iop_32to1,
- binop(Iop_Shr32,
+ mkU64(0xffffffffffff8000ULL),
+ mkexpr(t1)));
+ assign(t7, binop(Iop_And32,
+ binop(Iop_Or32,
+ unop(Iop_1Sto32,
+ binop(Iop_CmpNE32,
+ mkU32(0),
binop(Iop_And32,
unop(Iop_64HIto32,
- mkexpr(t1)),
+ mkexpr(t6)),
+ mkU32(0x7fffffff)))),
+ unop(Iop_1Sto32,
+ binop(Iop_CmpNE32,
+ mkU32(0),
+ unop(Iop_64to32,
+ mkexpr(t6))))),
+ unop(Iop_1Sto32,
+ binop(Iop_CmpEQ32,
+ binop(Iop_And32,
+ unop(Iop_64HIto32,
+ mkexpr(t6)),
mkU32(0x80000000)),
- mkU8(31))),
- mkexpr(t8),
- mkexpr(t5)));
+ mkU32(0)))));
+ putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
+ mkU32(0),
+ mkexpr(t7)),
+ binop(Iop_Or32,
+ getDSPControl(),
+ mkU32(0x00800000)),
+ getDSPControl()));
+ putIReg(rt, IRExpr_ITE(binop(Iop_CmpNE32,
+ mkU32(0),
+ mkexpr(t4)),
+ mkU32(0x00007fff),
+ IRExpr_ITE(binop(Iop_CmpNE32,
+ mkU32(0),
+ mkexpr(t7)),
+ mkU32(0xffff8000),
+ unop(Iop_64to32,
+ mkexpr(t1)))));
break;
}
case 0x12: { /* RDDSP*/
DIP("shilov ac%d, r%d", ac, rs);
vassert(!mode64);
t0 = newTemp(Ity_I64);
- t1 = newTemp(Ity_I64);
- t2 = newTemp(Ity_I32);
- t3 = newTemp(Ity_I1);
+ t1 = newTemp(Ity_I32);
+ t2 = newTemp(Ity_I1);
+ t3 = newTemp(Ity_I64);
t4 = newTemp(Ity_I64);
- t5 = newTemp(Ity_I64);
assign(t0, getAcc(ac));
- assign(t2, binop(Iop_And32, getIReg(rs), mkU32(0x3f)));
- assign(t3, binop(Iop_CmpEQ32, mkexpr(t2), mkU32(0x20)));
-
- assign(t4, binop(Iop_Shl64,
+ assign(t1, binop(Iop_And32, getIReg(rs), mkU32(0x3f)));
+ assign(t2, binop(Iop_CmpEQ32, mkexpr(t1), mkU32(0x20)));
+ assign(t3, binop(Iop_Shl64,
mkexpr(t0),
unop(Iop_32to8,
binop(Iop_Add32,
unop(Iop_Not32,
- mkexpr(t2)),
+ mkexpr(t1)),
mkU32(0x1)))));
- assign(t5, binop(Iop_Shr64,
+ assign(t4, binop(Iop_Shr64,
mkexpr(t0),
unop(Iop_32to8,
- mkexpr(t2))));
- putAcc(ac, IRExpr_ITE(mkexpr(t3),
- binop(Iop_32HLto64,
- unop(Iop_64to32, mkexpr(t0)),
- mkU32(0x0)),
- IRExpr_ITE(binop(Iop_CmpEQ32,
- binop(Iop_And32,
- mkexpr(t2),
- mkU32(0x20)),
- mkU32(0x20)),
- mkexpr(t4),
- mkexpr(t5))));
+ mkexpr(t1))));
+
+ putAcc(ac,
+ IRExpr_ITE(mkexpr(t2),
+ binop(Iop_32HLto64,
+ unop(Iop_64to32, mkexpr(t0)),
+ mkU32(0x0)),
+ IRExpr_ITE(binop(Iop_CmpEQ32,
+ binop(Iop_And32,
+ mkexpr(t1),
+ mkU32(0x20)),
+ mkU32(0x20)),
+ mkexpr(t3),
+ mkexpr(t4))));
break;
}
case 0x1F: { /* MTHLIP */
t0 = newTemp(Ity_I32);
t1 = newTemp(Ity_I1);
t2 = newTemp(Ity_I1);
- t3 = newTemp(Ity_I1);
- t4 = newTemp(Ity_I32);
- t5 = newTemp(Ity_I32);
- t6 = newTemp(Ity_I1);
+ t3 = newTemp(Ity_I32);
+ t4 = newTemp(Ity_I1);
+ t5 = newTemp(Ity_I1);
+ t6 = newTemp(Ity_I32);
t7 = newTemp(Ity_I1);
t8 = newTemp(Ity_I1);
- t9 = newTemp(Ity_I32);
- t10 = newTemp(Ity_I32);
- t11 = newTemp(Ity_I1);
- t12 = newTemp(Ity_I1);
- t13 = newTemp(Ity_I1);
- t14 = newTemp(Ity_I32);
- t15 = newTemp(Ity_I32);
- t16 = newTemp(Ity_I1);
- t17 = newTemp(Ity_I1);
- t18 = newTemp(Ity_I32);
+ t9 = newTemp(Ity_I1);
+ t10 = newTemp(Ity_I1);
if (0 == rs) {
putIReg(rd, getIReg(rt));
} else {
- /* Shift bits 7..0. */
+ /* Shift bits 7..0 and 23..16. */
assign(t0, binop(Iop_Shl32,
- unop(Iop_8Uto32,
- unop(Iop_32to8, getIReg(rt))),
- unop(Iop_32to8,
- binop(Iop_And32,
- mkU32(rs),
- mkU32(0x7)))));
- /* Check if discard isn't 0x0 and 0xffffffff. */
+ binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0x00ff00ff)),
+ mkU8(rs)));
assign(t1, binop(Iop_CmpNE32,
- unop(Iop_8Uto32,
- unop(Iop_16HIto8,
- unop(Iop_32to16,
- mkexpr(t0)))),
- mkU32(0x00000000)));
+ binop(Iop_And32,
+ mkexpr(t0),
+ mkU32(0xff000000)),
+ mkU32(0x00000000)));
assign(t2, binop(Iop_CmpNE32,
- unop(Iop_8Uto32,
- unop(Iop_16HIto8,
- unop(Iop_32to16,
- mkexpr(t0)))),
- mkU32(0x000000ff)));
- assign(t4, binop(Iop_Or32,
- getDSPControl(), mkU32(0x400000)));
- putDSPControl(IRExpr_ITE(mkexpr(t1),
- IRExpr_ITE(mkexpr(t2),
- mkexpr(t4),
- getDSPControl()),
- getDSPControl()));
-
- /* Shift bits 15..8. */
- assign(t5, binop(Iop_Shl32,
- unop(Iop_8Uto32,
- unop(Iop_16HIto8,
- unop(Iop_32to16,
- getIReg(rt)))),
- unop(Iop_32to8,
- binop(Iop_And32,
- mkU32(rs),
- mkU32(0x7)))));
- /* Check if discard isn't 0x0 and 0xffffffff. */
- assign(t6, binop(Iop_CmpNE32,
- unop(Iop_8Uto32,
- unop(Iop_16HIto8,
- unop(Iop_32to16,
- mkexpr(t5)))),
- mkU32(0x00000000)));
+ binop(Iop_And32,
+ mkexpr(t0),
+ mkU32(0xff000000)),
+ mkU32(0xff000000)));
assign(t7, binop(Iop_CmpNE32,
- unop(Iop_8Uto32,
- unop(Iop_16HIto8,
- unop(Iop_32to16,
- mkexpr(t5)))),
- mkU32(0x000000ff)));
- assign(t9, binop(Iop_Or32,
- getDSPControl(),
- mkU32(0x400000)));
- putDSPControl(IRExpr_ITE(mkexpr(t6),
- IRExpr_ITE(mkexpr(t7),
- mkexpr(t9),
- getDSPControl()),
- getDSPControl()));
+ binop(Iop_And32,
+ mkexpr(t0),
+ mkU32(0x0000ff00)),
+ mkU32(0x00000000)));
+ assign(t8, binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ mkexpr(t0),
+ mkU32(0x0000ff00)),
+ mkU32(0x000ff00)));
+ /* Shift bits 15..8 and 31..24. */
+ assign(t3, binop(Iop_Shl32,
+ binop(Iop_Shr32,
+ binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0xff00ff00)),
+ mkU8(8)),
+ mkU8(rs)));
+ assign(t4, binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ mkexpr(t3),
+ mkU32(0xff000000)),
+ mkU32(0x00000000)));
+ assign(t5, binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ mkexpr(t3),
+ mkU32(0xff000000)),
+ mkU32(0xff000000)));
+ assign(t9, binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ mkexpr(t3),
+ mkU32(0x0000ff00)),
+ mkU32(0x00000000)));
+ assign(t10, binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ mkexpr(t3),
+ mkU32(0x0000ff00)),
+ mkU32(0x0000ff00)));
- /* Shift bits 23..16. */
- assign(t10, binop(Iop_Shl32,
- unop(Iop_8Uto32,
- unop(Iop_16to8,
- unop(Iop_32HIto16,
- getIReg(rt)))),
- unop(Iop_32to8,
+ assign(t6, binop(Iop_Or32,
+ binop(Iop_Or32,
binop(Iop_And32,
- mkU32(rs),
- mkU32(0x7)))));
- /* Check if discard isn't 0x0 and 0xffffffff. */
- assign(t11, binop(Iop_CmpNE32,
- unop(Iop_8Uto32,
- unop(Iop_16HIto8,
- unop(Iop_32to16,
- mkexpr(t10)))),
- mkU32(0x00000000)));
- assign(t12, binop(Iop_CmpNE32,
- unop(Iop_8Uto32,
- unop(Iop_16HIto8,
- unop(Iop_32to16,
- mkexpr(t10)))),
- mkU32(0x000000ff)));
-
- assign(t14, binop(Iop_Or32,
- getDSPControl(),
- mkU32(0x400000)));
- putDSPControl(IRExpr_ITE(mkexpr(t11),
- IRExpr_ITE(mkexpr(t12),
- mkexpr(t14),
- getDSPControl()),
- getDSPControl()));
-
- /* Shift bits 31..24. */
- assign(t15, binop(Iop_Shl32,
- unop(Iop_8Uto32,
- unop(Iop_16HIto8,
- unop(Iop_32HIto16,
- getIReg(rt)))),
- unop(Iop_32to8,
+ unop(Iop_1Uto32,
+ mkexpr(t1)),
+ unop(Iop_1Uto32,
+ mkexpr(t2))),
binop(Iop_And32,
- mkU32(rs),
- mkU32(0x7)))));
- /* Check if discard isn't 0x0 and 0xffffffff. */
- assign(t16, binop(Iop_CmpNE32,
- unop(Iop_8Uto32,
- unop(Iop_16HIto8,
- unop(Iop_32to16,
- mkexpr(t15)))),
- mkU32(0x00000000)));
- assign(t17, binop(Iop_CmpNE32,
- unop(Iop_8Uto32,
- unop(Iop_16HIto8,
- unop(Iop_32to16,
- mkexpr(t15)))),
- mkU32(0x000000ff)));
-
- assign(t18, binop(Iop_Or32,
- getDSPControl(),
- mkU32(0x400000)));
- putDSPControl(IRExpr_ITE(mkexpr(t16),
- IRExpr_ITE(mkexpr(t17),
- mkexpr(t18),
- getDSPControl()),
- getDSPControl()));
+ unop(Iop_1Uto32,
+ mkexpr(t7)),
+ unop(Iop_1Uto32,
+ mkexpr(t8)))),
+ binop(Iop_Or32,
+ binop(Iop_And32,
+ unop(Iop_1Uto32,
+ mkexpr(t4)),
+ unop(Iop_1Uto32,
+ mkexpr(t5))),
+ binop(Iop_And32,
+ unop(Iop_1Uto32,
+ mkexpr(t9)),
+ unop(Iop_1Uto32,
+ mkexpr(t10))))));
- putIReg(rd, binop(Iop_16HLto32,
- binop(Iop_8HLto16,
- unop(Iop_32to8, mkexpr(t15)),
- unop(Iop_32to8, mkexpr(t10))),
- binop(Iop_8HLto16,
- unop(Iop_32to8, mkexpr(t5)),
- unop(Iop_32to8, mkexpr(t0)))));
+ putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
+ mkexpr(t6),
+ mkU32(0x0)),
+ binop(Iop_Or32,
+ getDSPControl(),
+ mkU32(0x400000)),
+ getDSPControl()));
+ putIReg(rd, binop(Iop_Or32,
+ binop(Iop_Shl32,
+ binop(Iop_And32,
+ mkexpr(t3),
+ mkU32(0x00ff00ff)),
+ mkU8(8)),
+ binop(Iop_And32,
+ mkexpr(t0),
+ mkU32(0x00ff00ff))));
}
break;
}
t0 = newTemp(Ity_I32);
t1 = newTemp(Ity_I1);
t2 = newTemp(Ity_I1);
- t3 = newTemp(Ity_I1);
- t4 = newTemp(Ity_I32);
- t5 = newTemp(Ity_I32);
- t6 = newTemp(Ity_I1);
+ t3 = newTemp(Ity_I32);
+ t4 = newTemp(Ity_I1);
+ t5 = newTemp(Ity_I1);
+ t6 = newTemp(Ity_I32);
t7 = newTemp(Ity_I1);
t8 = newTemp(Ity_I1);
- t9 = newTemp(Ity_I32);
- t10 = newTemp(Ity_I32);
- t11 = newTemp(Ity_I1);
- t12 = newTemp(Ity_I1);
- t13 = newTemp(Ity_I1);
- t14 = newTemp(Ity_I32);
- t15 = newTemp(Ity_I32);
- t16 = newTemp(Ity_I1);
- t17 = newTemp(Ity_I1);
- t18 = newTemp(Ity_I32);
+ t9 = newTemp(Ity_I1);
+ t10 = newTemp(Ity_I1);
+ t11 = newTemp(Ity_I8);
- /* Shift bits 7..0. */
+ assign(t11, unop(Iop_32to8,
+ binop(Iop_And32,
+ getIReg(rs),
+ mkU32(0x7))));
+ /* Shift bits 7..0 and 23..16. */
assign(t0, binop(Iop_Shl32,
- unop(Iop_8Uto32,
- unop(Iop_32to8, getIReg(rt))),
- unop(Iop_32to8,
- binop(Iop_And32,
- getIReg(rs),
- mkU32(0x7)))));
- /* Check if discard isn't 0x0 and 0xffffffff. */
+ binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0x00ff00ff)),
+ mkexpr(t11)));
assign(t1, binop(Iop_CmpNE32,
- unop(Iop_8Uto32,
- unop(Iop_16HIto8,
- unop(Iop_32to16, mkexpr(t0)))),
- mkU32(0x00000000)));
+ binop(Iop_And32,
+ mkexpr(t0),
+ mkU32(0xff000000)),
+ mkU32(0x00000000)));
assign(t2, binop(Iop_CmpNE32,
- unop(Iop_8Uto32,
- unop(Iop_16HIto8,
- unop(Iop_32to16, mkexpr(t0)))),
- mkU32(0x000000ff)));
-
- assign(t4, binop(Iop_Or32,
- getDSPControl(),
- mkU32(0x400000)));
- putDSPControl(IRExpr_ITE(mkexpr(t1),
- IRExpr_ITE(mkexpr(t2),
- mkexpr(t4),
- getDSPControl()),
- getDSPControl()));
-
- /* Shift bits 15..8. */
- assign(t5, binop(Iop_Shl32,
- unop(Iop_8Uto32,
- unop(Iop_16HIto8,
- unop(Iop_32to16, getIReg(rt)))),
- unop(Iop_32to8,
- binop(Iop_And32,
- getIReg(rs),
- mkU32(0x7)))));
- /* Check if discard isn't 0x0 and 0xffffffff. */
- assign(t6, binop(Iop_CmpNE32,
- unop(Iop_8Uto32,
- unop(Iop_16HIto8,
- unop(Iop_32to16, mkexpr(t5)))),
- mkU32(0x00000000)));
+ binop(Iop_And32,
+ mkexpr(t0),
+ mkU32(0xff000000)),
+ mkU32(0xff000000)));
assign(t7, binop(Iop_CmpNE32,
- unop(Iop_8Uto32,
- unop(Iop_16HIto8,
- unop(Iop_32to16, mkexpr(t5)))),
- mkU32(0x000000ff)));
-
- assign(t9, binop(Iop_Or32,
- getDSPControl(),
- mkU32(0x400000)));
- putDSPControl(IRExpr_ITE(mkexpr(t6),
- IRExpr_ITE(mkexpr(t7),
- mkexpr(t9),
- getDSPControl()),
- getDSPControl()));
-
- /* Shift bits 23..16. */
- assign(t10, binop(Iop_Shl32,
- unop(Iop_8Uto32,
- unop(Iop_16to8,
- unop(Iop_32HIto16,
- getIReg(rt)))),
- unop(Iop_32to8,
+ binop(Iop_And32,
+ mkexpr(t0),
+ mkU32(0x0000ff00)),
+ mkU32(0x00000000)));
+ assign(t8, binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ mkexpr(t0),
+ mkU32(0x0000ff00)),
+ mkU32(0x000ff00)));
+ /* Shift bits 15..8 and 31..24. */
+ assign(t3, binop(Iop_Shl32,
+ binop(Iop_Shr32,
binop(Iop_And32,
- getIReg(rs),
- mkU32(0x7)))));
- /* Check if discard isn't 0x0 and 0xffffffff. */
- assign(t11, binop(Iop_CmpNE32,
- unop(Iop_8Uto32,
- unop(Iop_16HIto8,
- unop(Iop_32to16,
- mkexpr(t10)))),
- mkU32(0x00000000)));
- assign(t12, binop(Iop_CmpNE32,
- unop(Iop_8Uto32,
- unop(Iop_16HIto8,
- unop(Iop_32to16,
- mkexpr(t10)))),
- mkU32(0x000000ff)));
-
- assign(t14, binop(Iop_Or32,
- getDSPControl(),
- mkU32(0x400000)));
- putDSPControl(IRExpr_ITE(mkexpr(t11),
- IRExpr_ITE(mkexpr(t12),
- mkexpr(t14),
- getDSPControl()),
- getDSPControl()));
-
- /* Shift bits 31..24. */
- assign(t15, binop(Iop_Shl32,
- unop(Iop_8Uto32,
- unop(Iop_16HIto8,
- unop(Iop_32HIto16,
- getIReg(rt)))),
- unop(Iop_32to8,
+ getIReg(rt),
+ mkU32(0xff00ff00)),
+ mkU8(8)),
+ mkexpr(t11)));
+ assign(t4, binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ mkexpr(t3),
+ mkU32(0xff000000)),
+ mkU32(0x00000000)));
+ assign(t5, binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ mkexpr(t3),
+ mkU32(0xff000000)),
+ mkU32(0xff000000)));
+ assign(t9, binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ mkexpr(t3),
+ mkU32(0x0000ff00)),
+ mkU32(0x00000000)));
+ assign(t10, binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ mkexpr(t3),
+ mkU32(0x0000ff00)),
+ mkU32(0x0000ff00)));
+
+ assign(t6, binop(Iop_Or32,
+ binop(Iop_Or32,
binop(Iop_And32,
- getIReg(rs),
- mkU32(0x7)))));
- /* Check if discard isn't 0x0 and 0xffffffff. */
- assign(t16, binop(Iop_CmpNE32,
- unop(Iop_8Uto32,
- unop(Iop_16HIto8,
- unop(Iop_32to16,
- mkexpr(t15)))),
- mkU32(0x00000000)));
- assign(t17, binop(Iop_CmpNE32,
- unop(Iop_8Uto32,
- unop(Iop_16HIto8,
- unop(Iop_32to16,
- mkexpr(t15)))),
- mkU32(0x000000ff)));
-
- assign(t18, binop(Iop_Or32,
- getDSPControl(),
- mkU32(0x400000)));
- putDSPControl(IRExpr_ITE(mkexpr(t16),
- IRExpr_ITE(mkexpr(t17),
- mkexpr(t18),
- getDSPControl()),
- getDSPControl()));
+ unop(Iop_1Uto32,
+ mkexpr(t1)),
+ unop(Iop_1Uto32,
+ mkexpr(t2))),
+ binop(Iop_And32,
+ unop(Iop_1Uto32,
+ mkexpr(t7)),
+ unop(Iop_1Uto32,
+ mkexpr(t8)))),
+ binop(Iop_Or32,
+ binop(Iop_And32,
+ unop(Iop_1Uto32,
+ mkexpr(t4)),
+ unop(Iop_1Uto32,
+ mkexpr(t5))),
+ binop(Iop_And32,
+ unop(Iop_1Uto32,
+ mkexpr(t9)),
+ unop(Iop_1Uto32,
+ mkexpr(t10))))));
+ putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
+ mkexpr(t6),
+ mkU32(0x0)),
+ binop(Iop_Or32,
+ getDSPControl(),
+ mkU32(0x400000)),
+ getDSPControl()));
putIReg(rd, IRExpr_ITE(binop(Iop_CmpEQ32,
- binop(Iop_And32,
- getIReg(rs),
- mkU32(0x7)),
- mkU32(0x0)),
+ unop(Iop_8Uto32, mkexpr(t11)),
+ mkU32(0)),
getIReg(rt),
- binop(Iop_16HLto32,
- binop(Iop_8HLto16,
- unop(Iop_32to8,
- mkexpr(t15)),
- unop(Iop_32to8,
- mkexpr(t10))),
- binop(Iop_8HLto16,
- unop(Iop_32to8,
- mkexpr(t5)),
- unop(Iop_32to8,
- mkexpr(t0))))));
+ binop(Iop_Or32,
+ binop(Iop_Shl32,
+ binop(Iop_And32,
+ mkexpr(t3),
+ mkU32(0xff00ff)),
+ mkU8(8)),
+ binop(Iop_And32,
+ mkexpr(t0),
+ mkU32(0x00ff00ff)))));
break;
}
case 0x1: { /* SHRLV.QB */
t1 = newTemp(Ity_I32);
t2 = newTemp(Ity_I32);
t3 = newTemp(Ity_I32);
- t4 = newTemp(Ity_I1);
+ t4 = newTemp(Ity_I32);
+ t5 = newTemp(Ity_I32);
+ t6 = newTemp(Ity_I32);
+ t7 = newTemp(Ity_I32);
if (0 == rs) {
putIReg(rd, getIReg(rt));
unop(Iop_32to16, getIReg(rt))),
mkU8(rs)));
- assign(t2, IRExpr_ITE(binop(Iop_CmpNE32,
- unop(Iop_16Sto32,
- unop(Iop_32HIto16,
- mkexpr(t0))),
- mkU32(0xffffffff)),
- binop(Iop_Or32,
- getDSPControl(),
- mkU32(0x400000)),
- getDSPControl()));
- putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
- unop(Iop_16Sto32,
- unop(Iop_32HIto16,
- mkexpr(t0))),
- mkU32(0x00000000)),
- mkexpr(t2),
+ assign(t1, unop(Iop_1Uto32,
+ binop(Iop_CmpNE32,
+ binop(Iop_Sar32,
+ mkexpr(t0),
+ mkU8(16)),
+ mkU32(0))));
+ assign(t2, unop(Iop_1Uto32,
+ binop(Iop_CmpNE32,
+ binop(Iop_Sar32,
+ mkexpr(t0),
+ mkU8(16)),
+ mkU32(0xffffffff))));
+ assign(t3, binop(Iop_And32,
+ mkexpr(t1),
+ mkexpr(t2)));
+ putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
+ mkexpr(t3),
+ mkU32(0x1)),
+ binop(Iop_Or32,
+ getDSPControl(),
+ mkU32(0x400000)),
getDSPControl()));
putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
binop(Iop_And32,
getDSPControl(),
mkU32(0x400000))));
/* Shift higher 16 bits. */
- assign(t1, binop(Iop_Shl32,
+ assign(t4, binop(Iop_Shl32,
unop(Iop_16Sto32,
unop(Iop_32HIto16, getIReg(rt))),
mkU8(rs)));
- assign(t3, IRExpr_ITE(binop(Iop_CmpNE32,
- unop(Iop_16Sto32,
- unop(Iop_32HIto16,
- mkexpr(t1))),
- mkU32(0xffffffff)),
- binop(Iop_Or32,
- getDSPControl(),
- mkU32(0x400000)),
- getDSPControl()));
- putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
- unop(Iop_16Sto32,
- unop(Iop_32HIto16,
- mkexpr(t1))),
- mkU32(0x00000000)),
- mkexpr(t3),
- getDSPControl()));
- assign(t4, binop(Iop_CmpEQ32,
- binop(Iop_Shr32,
- binop(Iop_And32,
- getIReg(rt),
- mkU32(0x80000000)),
- mkU8(31)),
- binop(Iop_Shr32,
- binop(Iop_And32,
- mkexpr(t1),
- mkU32(0x00008000)),
- mkU8(15))));
- putDSPControl(IRExpr_ITE(mkexpr(t4),
+ assign(t5, unop(Iop_1Uto32,
+ binop(Iop_CmpNE32,
+ binop(Iop_Sar32,
+ mkexpr(t4),
+ mkU8(16)),
+ mkU32(0))));
+ assign(t6, unop(Iop_1Uto32,
+ binop(Iop_CmpNE32,
+ binop(Iop_Sar32,
+ mkexpr(t4),
+ mkU8(16)),
+ mkU32(0xffffffff))));
+ assign(t7, binop(Iop_And32,
+ mkexpr(t5),
+ mkexpr(t6)));
+ putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
+ mkexpr(t7),
+ mkU32(0x1)),
+ binop(Iop_Or32,
+ getDSPControl(),
+ mkU32(0x400000)),
+ getDSPControl()));
+ putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
+ mkexpr(t7),
+ mkU32(0x1)),
+ binop(Iop_Or32,
+ getDSPControl(),
+ mkU32(0x400000)),
+ getDSPControl()));
+ putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
+ binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0x80000000)),
+ binop(Iop_Shl32,
+ binop(Iop_And32,
+ mkexpr(t4),
+ mkU32(0x00008000)),
+ mkU8(16))
+ ),
getDSPControl(),
binop(Iop_Or32,
getDSPControl(),
mkU32(0x400000))));
-
putIReg(rd, binop(Iop_16HLto32,
- unop(Iop_32to16, mkexpr(t1)),
+ unop(Iop_32to16, mkexpr(t4)),
unop(Iop_32to16, mkexpr(t0))));
}
break;
DIP("shll_s.ph r%d, r%d, %d", rd, rt, rs);
vassert(!mode64);
t0 = newTemp(Ity_I32);
- t1 = newTemp(Ity_I16);
- t2 = newTemp(Ity_I16);
- t3 = newTemp(Ity_I16);
+ t1 = newTemp(Ity_I32);
+ t2 = newTemp(Ity_I32);
+ t3 = newTemp(Ity_I32);
t4 = newTemp(Ity_I32);
- t5 = newTemp(Ity_I16);
- t6 = newTemp(Ity_I16);
- t7 = newTemp(Ity_I16);
+ t5 = newTemp(Ity_I32);
+ t6 = newTemp(Ity_I32);
+ t7 = newTemp(Ity_I32);
t8 = newTemp(Ity_I32);
t9 = newTemp(Ity_I32);
- t10 = newTemp(Ity_I1);
- t11 = newTemp(Ity_I16);
- t12 = newTemp(Ity_I16);
+ t10 = newTemp(Ity_I32);
+ t11 = newTemp(Ity_I32);
+ t12 = newTemp(Ity_I32);
+ t13 = newTemp(Ity_I32);
+ t14 = newTemp(Ity_I32);
if (0 == rs) {
putIReg(rd, getIReg(rt));
unop(Iop_32to16, getIReg(rt))),
mkU8(rs)));
- assign(t1, IRExpr_ITE(binop(Iop_CmpEQ32,
- binop(Iop_And32,
- getIReg(rt),
- mkU32(0x00008000)),
- mkU32(0x0)),
- mkU16(0x7fff),
- mkU16(0x8000)));
- assign(t2,
- IRExpr_ITE(binop(Iop_CmpEQ32,
- binop(Iop_Shr32,
- binop(Iop_And32,
- getIReg(rt),
- mkU32(0x00008000)),
- mkU8(15)),
- binop(Iop_Shr32,
- binop(Iop_And32,
- mkexpr(t0),
- mkU32(0x00008000)),
- mkU8(15))),
- unop(Iop_32to16, mkexpr(t0)),
- mkexpr(t1)));
- assign(t11, IRExpr_ITE(binop(Iop_CmpNE32,
- unop(Iop_16Sto32,
- unop(Iop_32HIto16,
- mkexpr(t0))),
- mkU32(0xffffffff)),
- mkexpr(t1),
- mkexpr(t2)));
- assign(t3,
- IRExpr_ITE(binop(Iop_CmpNE32,
- unop(Iop_16Sto32,
- unop(Iop_32HIto16,
- mkexpr(t0))),
- mkU32(0x00000000)),
- mkexpr(t11),
- mkexpr(t2)));
- assign(t8, IRExpr_ITE(binop(Iop_CmpNE32,
- unop(Iop_16Sto32,
- unop(Iop_32HIto16,
- mkexpr(t0))),
- mkU32(0xffffffff)),
- binop(Iop_Or32,
- getDSPControl(),
- mkU32(0x400000)),
- getDSPControl()));
- putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
- unop(Iop_16Sto32,
- unop(Iop_32HIto16,
- mkexpr(t0))),
- mkU32(0x00000000)),
- mkexpr(t8),
- getDSPControl()));
+ assign(t1, unop(Iop_1Uto32,
+ binop(Iop_CmpNE32,
+ binop(Iop_Sar32,
+ mkexpr(t0),
+ mkU8(16)),
+ mkU32(0))));
+ assign(t2, unop(Iop_1Uto32,
+ binop(Iop_CmpNE32,
+ binop(Iop_Sar32,
+ mkexpr(t0),
+ mkU8(16)),
+ mkU32(0xffffffff))));
+ assign(t3, binop(Iop_And32,
+ mkexpr(t1),
+ mkexpr(t2)));
+ putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
+ mkexpr(t3),
+ mkU32(0x1)),
+ binop(Iop_Or32,
+ getDSPControl(),
+ mkU32(0x400000)),
+ getDSPControl()));
putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
binop(Iop_And32,
getIReg(rt),
mkU32(0x00008000)),
binop(Iop_And32,
- mkexpr(t0),
- mkU32(0x00008000))),
+ mkexpr(t0),
+ mkU32(0x00008000))
+ ),
getDSPControl(),
binop(Iop_Or32,
getDSPControl(),
mkU32(0x400000))));
+ assign(t8,
+ IRExpr_ITE(binop(Iop_CmpEQ32,
+ mkexpr(t3),
+ mkU32(0x1)),
+ IRExpr_ITE(binop(Iop_CmpEQ32,
+ binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0x8000)),
+ mkU32(0)),
+ mkU32(0x00007fff),
+ mkU32(0x00008000)),
+ binop(Iop_And32,
+ mkexpr(t0),
+ mkU32(0x0000ffff))));
+ assign(t10,
+ IRExpr_ITE(binop(Iop_CmpEQ32,
+ binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0x00008000)),
+ binop(Iop_And32,
+ mkexpr(t0),
+ mkU32(0x00008000))),
+ mkexpr(t8),
+ IRExpr_ITE(binop(Iop_CmpEQ32,
+ binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0x8000)),
+ mkU32(0)),
+ mkU32(0x00007fff),
+ mkU32(0x00008000))));
/* Shift higher 16 bits. */
assign(t4, binop(Iop_Shl32,
unop(Iop_16Sto32,
unop(Iop_32HIto16, getIReg(rt))),
mkU8(rs)));
- assign(t5, IRExpr_ITE(binop(Iop_CmpEQ32,
- binop(Iop_And32,
- getIReg(rt),
- mkU32(0x80000000)),
- mkU32(0x0)),
- mkU16(0x7fff),
- mkU16(0x8000)));
- assign(t6,
- IRExpr_ITE(binop(Iop_CmpEQ32,
- binop(Iop_Shr32,
- binop(Iop_And32,
- getIReg(rt),
- mkU32(0x80000000)),
- mkU8(31)),
- binop(Iop_Shr32,
- binop(Iop_And32,
- mkexpr(t4),
- mkU32(0x00008000)),
- mkU8(15))),
- unop(Iop_32to16, mkexpr(t4)),
- mkexpr(t5)));
- assign(t12, IRExpr_ITE(binop(Iop_CmpNE32,
- unop(Iop_16Sto32,
- unop(Iop_32HIto16,
- mkexpr(t4))),
- mkU32(0xffffffff)),
- mkexpr(t5),
- mkexpr(t6)));
- assign(t7,
- IRExpr_ITE(binop(Iop_CmpNE32,
- unop(Iop_16Sto32,
- unop(Iop_32HIto16,
- mkexpr(t4))),
- mkU32(0x00000000)),
- mkexpr(t12),
- mkexpr(t6)));
- assign(t9, IRExpr_ITE(binop(Iop_CmpNE32,
- unop(Iop_16Sto32,
- unop(Iop_32HIto16,
- mkexpr(t4))),
- mkU32(0xffffffff)),
- binop(Iop_Or32,
- getDSPControl(),
- mkU32(0x400000)),
- getDSPControl()));
- putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
- unop(Iop_16Sto32,
- unop(Iop_32HIto16,
- mkexpr(t4))),
- mkU32(0x00000000)),
- mkexpr(t9),
+ assign(t5, unop(Iop_1Uto32,
+ binop(Iop_CmpNE32,
+ binop(Iop_Sar32,
+ mkexpr(t4),
+ mkU8(16)),
+ mkU32(0))));
+ assign(t6, unop(Iop_1Uto32,
+ binop(Iop_CmpNE32,
+ binop(Iop_Sar32,
+ mkexpr(t4),
+ mkU8(16)),
+ mkU32(0xffffffff))));
+ assign(t7, binop(Iop_And32,
+ mkexpr(t5),
+ mkexpr(t6)));
+ putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
+ mkexpr(t7),
+ mkU32(0x1)),
+ binop(Iop_Or32,
+ getDSPControl(),
+ mkU32(0x400000)),
getDSPControl()));
- assign(t10, binop(Iop_CmpEQ32,
- binop(Iop_Shr32,
- binop(Iop_And32,
- getIReg(rt),
- mkU32(0x80000000)),
- mkU8(31)),
- binop(Iop_Shr32,
- binop(Iop_And32,
- mkexpr(t4),
- mkU32(0x00008000)),
- mkU8(15))));
- putDSPControl(IRExpr_ITE(mkexpr(t10),
+ putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
+ mkexpr(t7),
+ mkU32(0x1)),
+ binop(Iop_Or32,
+ getDSPControl(),
+ mkU32(0x400000)),
+ getDSPControl()));
+ assign(t12, binop(Iop_Shl32,
+ binop(Iop_And32,
+ mkexpr(t4),
+ mkU32(0x8000)),
+ mkU8(16)));
+ putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
+ binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0x80000000)),
+ mkexpr(t12)),
getDSPControl(),
binop(Iop_Or32,
getDSPControl(),
mkU32(0x400000))));
-
- putIReg(rd, binop(Iop_16HLto32,
- mkexpr(t7), mkexpr(t3)));
+ assign(t13, IRExpr_ITE(binop(Iop_CmpEQ32,
+ binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0x80000000)),
+ mkU32(0)),
+ mkU32(0x7fff0000),
+ mkU32(0x80000000)));
+ assign(t9,
+ IRExpr_ITE(binop(Iop_CmpEQ32,
+ mkexpr(t7),
+ mkU32(0x1)),
+ mkexpr(t13),
+ binop(Iop_Shl32,
+ binop(Iop_And32,
+ mkexpr(t4),
+ mkU32(0x0000ffff)),
+ mkU8(16))));
+ assign(t14, IRExpr_ITE(binop(Iop_CmpEQ32,
+ binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0x80000000)),
+ mkU32(0)),
+ mkU32(0x7fff0000),
+ mkU32(0x80000000)));
+ assign(t11,
+ IRExpr_ITE(binop(Iop_CmpEQ32,
+ binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0x80000000)),
+ binop(Iop_Shl32,
+ binop(Iop_And32,
+ mkexpr(t4),
+ mkU32(0x00008000)),
+ mkU8(16))),
+ mkexpr(t9),
+ mkexpr(t14)));
+ putIReg(rd, binop(Iop_Or32,
+ mkexpr(t10),
+ mkexpr(t11)));
}
break;
}
t8 = newTemp(Ity_I64);
t9 = newTemp(Ity_I64);
t10 = newTemp(Ity_I32);
- t11 = newTemp(Ity_I32);
assign(t0, getAcc(ac));
- /* Calculate first cross dot product and saturate if
+ /* Calculate the first cross dot product and saturate if
needed. */
assign(t1, unop(Iop_32Sto64,
binop(Iop_Shl32,
unop(Iop_32to16, getIReg(rt))),
mkU32(0x00008000)));
- assign(t4,
- IRExpr_ITE(mkexpr(t2),
- IRExpr_ITE(mkexpr(t3),
- mkU64(0x000000007fffffffULL),
- mkexpr(t1)),
- mkexpr(t1)));
+ assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ unop(Iop_1Sto32,
+ mkexpr(t2)),
+ unop(Iop_1Sto32,
+ mkexpr(t3))),
+ mkU32(0)),
+ mkU64(0x000000007fffffffULL),
+ mkexpr(t1)));
- putDSPControl(IRExpr_ITE(mkexpr(t2),
- IRExpr_ITE(mkexpr(t3),
- binop(Iop_Or32,
- getDSPControl(),
- binop(Iop_Shl32,
- mkU32(0x1),
- mkU8(ac+16)
- )
- ),
- getDSPControl()),
+ putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ unop(Iop_1Sto32,
+ mkexpr(t2)),
+ unop(Iop_1Sto32,
+ mkexpr(t3))),
+ mkU32(0)),
+ binop(Iop_Or32,
+ getDSPControl(),
+ binop(Iop_Shl32,
+ mkU32(0x1),
+ mkU8(ac+16))),
getDSPControl()));
/* Calculate second cross dot product and saturate if
needed. */
unop(Iop_32HIto16, getIReg(rt))),
mkU32(0x00008000)));
- assign(t8,
- IRExpr_ITE(mkexpr(t6),
- IRExpr_ITE(mkexpr(t7),
- mkU64(0x000000007fffffffULL),
- mkexpr(t5)),
- mkexpr(t5)));
+ assign(t8, IRExpr_ITE(binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ unop(Iop_1Sto32,
+ mkexpr(t6)),
+ unop(Iop_1Sto32,
+ mkexpr(t7))),
+ mkU32(0)),
+ mkU64(0x000000007fffffffULL),
+ mkexpr(t5)));
- putDSPControl(IRExpr_ITE(mkexpr(t6),
- IRExpr_ITE(mkexpr(t7),
- binop(Iop_Or32,
- getDSPControl(),
- binop(Iop_Shl32,
- mkU32(0x1),
- mkU8(ac+16)
- )
- ),
- getDSPControl()),
+ putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ unop(Iop_1Sto32,
+ mkexpr(t6)),
+ unop(Iop_1Sto32,
+ mkexpr(t7))),
+ mkU32(0)),
+ binop(Iop_Or32,
+ getDSPControl(),
+ binop(Iop_Shl32,
+ mkU32(0x1),
+ mkU8(ac+16))),
getDSPControl()));
- /* Add intermediate products with value in the
+ /* Subtract intermediate products from value in the
accumulator. */
- assign(t9, binop(Iop_Add64,
- mkexpr(t0),
- binop(Iop_Add64, mkexpr(t8), mkexpr(t4))));
+ assign(t9,
+ binop(Iop_Add64,
+ mkexpr(t0),
+ binop(Iop_Add64, mkexpr(t8), mkexpr(t4))));
putAcc(ac,
IRExpr_ITE(binop(Iop_CmpEQ32,
mkU32(0xffffffff)),
mkU64(0xffffffff80000000ULL),
mkexpr(t9))));
- assign(t10, IRExpr_ITE(binop(Iop_CmpNE32,
- unop(Iop_64HIto32,
- binop(Iop_Shl64,
- mkexpr(t9),
- mkU8(1))),
- mkU32(0x0)),
- binop(Iop_Or32,
- getDSPControl(),
- binop(Iop_Shl32,
- mkU32(0x1),
- mkU8(ac+16))),
- getDSPControl()));
- assign(t11, IRExpr_ITE(binop(Iop_CmpNE32,
- unop(Iop_64HIto32,
- binop(Iop_Shl64,
- mkexpr(t9),
- mkU8(1))),
- mkU32(0xffffffff)),
- binop(Iop_Or32,
- getDSPControl(),
- binop(Iop_Shl32,
- mkU32(0x1),
- mkU8(ac+16))),
- getDSPControl()));
+ assign(t10, IRExpr_ITE(binop(Iop_CmpEQ32,
+ unop(Iop_64to32,
+ mkexpr(t9)),
+ unop(Iop_64to32,
+ getAcc(ac))),
+ getDSPControl(),
+ binop(Iop_Or32,
+ getDSPControl(),
+ binop(Iop_Shl32,
+ mkU32(0x1),
+ mkU8(ac+16)))));
putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
- binop(Iop_And32,
- unop(Iop_64HIto32,
- mkexpr(t9)),
- mkU32(0x80000000)),
- mkU32(0x0)),
+ unop(Iop_64HIto32,
+ mkexpr(t9)),
+ unop(Iop_64HIto32,
+ getAcc(ac))),
mkexpr(t10),
- mkexpr(t11)));
+ binop(Iop_Or32,
+ getDSPControl(),
+ binop(Iop_Shl32,
+ mkU32(0x1),
+ mkU8(ac+16)))));
break;
}
case 0x1B: { /* DPSQX_SA.W.PH */
t8 = newTemp(Ity_I64);
t9 = newTemp(Ity_I64);
t10 = newTemp(Ity_I32);
- t11 = newTemp(Ity_I32);
assign(t0, getAcc(ac));
- /* Calculate first cross dot product and saturate if
+ /* Calculate the first cross dot product and saturate if
needed. */
assign(t1, unop(Iop_32Sto64,
binop(Iop_Shl32,
unop(Iop_32to16, getIReg(rt))),
mkU32(0x00008000)));
- assign(t4,
- IRExpr_ITE(mkexpr(t2),
- IRExpr_ITE(mkexpr(t3),
- mkU64(0x000000007fffffffULL),
- mkexpr(t1)),
- mkexpr(t1)));
+ assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ unop(Iop_1Sto32,
+ mkexpr(t2)),
+ unop(Iop_1Sto32,
+ mkexpr(t3))),
+ mkU32(0)),
+ mkU64(0x000000007fffffffULL),
+ mkexpr(t1)));
- putDSPControl(IRExpr_ITE(mkexpr(t2),
- IRExpr_ITE(mkexpr(t3),
- binop(Iop_Or32,
- getDSPControl(),
- binop(Iop_Shl32,
- mkU32(0x1),
- mkU8(ac+16)
- )
- ),
- getDSPControl()),
+ putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ unop(Iop_1Sto32,
+ mkexpr(t2)),
+ unop(Iop_1Sto32,
+ mkexpr(t3))),
+ mkU32(0)),
+ binop(Iop_Or32,
+ getDSPControl(),
+ binop(Iop_Shl32,
+ mkU32(0x1),
+ mkU8(ac+16))),
getDSPControl()));
/* Calculate second cross dot product and saturate if
needed. */
intermediate product and write to DSPControl
register. */
assign(t6, binop(Iop_CmpEQ32,
- binop(Iop_And32,
- getIReg(rs),
- mkU32(0x0000ffff)),
+ unop(Iop_16Uto32,
+ unop(Iop_32to16, getIReg(rs))),
mkU32(0x00008000)));
assign(t7, binop(Iop_CmpEQ32,
- binop(Iop_And32,
- getIReg(rt),
- mkU32(0xffff0000)),
- mkU32(0x80000000)));
+ unop(Iop_16Uto32,
+ unop(Iop_32HIto16, getIReg(rt))),
+ mkU32(0x00008000)));
- assign(t8,
- IRExpr_ITE(mkexpr(t6),
- IRExpr_ITE(mkexpr(t7),
- mkU64(0x000000007fffffffULL),
- mkexpr(t5)),
- mkexpr(t5)));
+ assign(t8, IRExpr_ITE(binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ unop(Iop_1Sto32,
+ mkexpr(t6)),
+ unop(Iop_1Sto32,
+ mkexpr(t7))),
+ mkU32(0)),
+ mkU64(0x000000007fffffffULL),
+ mkexpr(t5)));
- putDSPControl(IRExpr_ITE(mkexpr(t6),
- IRExpr_ITE(mkexpr(t7),
- binop(Iop_Or32,
- getDSPControl(),
- binop(Iop_Shl32,
- mkU32(0x1),
- mkU8(ac+16))),
- getDSPControl()),
+ putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
+ binop(Iop_And32,
+ unop(Iop_1Sto32,
+ mkexpr(t6)),
+ unop(Iop_1Sto32,
+ mkexpr(t7))),
+ mkU32(0)),
+ binop(Iop_Or32,
+ getDSPControl(),
+ binop(Iop_Shl32,
+ mkU32(0x1),
+ mkU8(ac+16))),
getDSPControl()));
/* Subtract intermediate products from value in the
accumulator. */
mkU32(0xffffffff)),
mkU64(0xffffffff80000000ULL),
mkexpr(t9))));
- assign(t10, IRExpr_ITE(binop(Iop_CmpNE32,
- unop(Iop_64HIto32,
- binop(Iop_Shl64,
- mkexpr(t9),
- mkU8(1))),
- mkU32(0x0)),
- binop(Iop_Or32,
- getDSPControl(),
- binop(Iop_Shl32,
- mkU32(0x1),
- mkU8(ac+16))),
- getDSPControl()));
- assign(t11, IRExpr_ITE(binop(Iop_CmpNE32,
- unop(Iop_64HIto32,
- binop(Iop_Shl64,
- mkexpr(t9),
- mkU8(1))),
- mkU32(0xffffffff)),
- binop(Iop_Or32,
- getDSPControl(),
- binop(Iop_Shl32,
- mkU32(0x1),
- mkU8(ac+16))),
- getDSPControl()));
+ assign(t10, IRExpr_ITE(binop(Iop_CmpEQ32,
+ unop(Iop_64to32,
+ mkexpr(t9)),
+ unop(Iop_64to32,
+ getAcc(ac))),
+ getDSPControl(),
+ binop(Iop_Or32,
+ getDSPControl(),
+ binop(Iop_Shl32,
+ mkU32(0x1),
+ mkU8(ac+16)))));
putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
- binop(Iop_And32,
- unop(Iop_64HIto32,
- mkexpr(t9)),
- mkU32(0x80000000)),
- mkU32(0x0)),
+ unop(Iop_64HIto32,
+ mkexpr(t9)),
+ unop(Iop_64HIto32,
+ getAcc(ac))),
mkexpr(t10),
- mkexpr(t11)));
+ binop(Iop_Or32,
+ getDSPControl(),
+ binop(Iop_Shl32,
+ mkU32(0x1),
+ mkU8(ac+16)))));
break;
}
default:
static MIPSRH *iselWordExpr_RH5u_wrk(ISelEnv * env, IRExpr * e);
static MIPSRH *iselWordExpr_RH5u(ISelEnv * env, IRExpr * e);
-/* In 64-bit mode ONLY */
+/* Compute an I8 into a reg-or-6-bit-unsigned-immediate, the latter being an immediate in
+ the range 1 .. 63 inclusive. Used for doing shift amounts. */
static MIPSRH *iselWordExpr_RH6u_wrk(ISelEnv * env, IRExpr * e);
static MIPSRH *iselWordExpr_RH6u(ISelEnv * env, IRExpr * e);
if ((ty == Ity_I8 || ty == Ity_I16 ||
ty == Ity_I32 || ((ty == Ity_I64))) &&
typeOfIRExpr(env->type_env, e->Iex.ITE.cond) == Ity_I1) {
+ HReg r_dst = iselWordExpr_R(env, e->Iex.ITE.iffalse);
+ HReg r1 = iselWordExpr_R(env, e->Iex.ITE.iftrue);
+ HReg r_cond = iselWordExpr_R(env, e->Iex.ITE.cond);
/*
- * r_dst = cond && r1
- * cond = not(cond)
- * tmp = cond && r0
- * r_dst = tmp + r_dst
+ * r_dst = r0
+ * movn r_dst, r1, r_cond
*/
- HReg r0 = iselWordExpr_R(env, e->Iex.ITE.iffalse);
- HReg r1 = iselWordExpr_R(env, e->Iex.ITE.iftrue);
- HReg r_cond_1 = iselWordExpr_R(env, e->Iex.ITE.cond);
- HReg r_cond = newVRegI(env);
- HReg mask = newVRegI(env);
- HReg r_dst = newVRegI(env);
- HReg r_tmp = newVRegI(env);
- HReg r_tmp1 = newVRegI(env);
- HReg r_cond_neg = newVRegI(env);
- /* r_cond = 0 - r_cond_1 */
- addInstr(env, MIPSInstr_LI(mask, 0x0));
- addInstr(env, MIPSInstr_Alu(Malu_SUB, r_cond,
- mask, MIPSRH_Reg(r_cond_1)));
-
- addInstr(env, MIPSInstr_Alu(Malu_AND, r_tmp, r_cond, MIPSRH_Reg(r1)));
- addInstr(env, MIPSInstr_Alu(Malu_NOR, r_cond_neg, r_cond,
- MIPSRH_Reg(r_cond)));
- addInstr(env, MIPSInstr_Alu(Malu_AND, r_tmp1, r_cond_neg,
- MIPSRH_Reg(r0)));
- addInstr(env, MIPSInstr_Alu(Malu_ADD, r_dst, r_tmp,
- MIPSRH_Reg(r_tmp1)));
-
+ addInstr(env, MIPSInstr_MoveCond(MMoveCond_movn, r_dst, r1, r_cond));
return r_dst;
}
break;
static MIPSRH *iselWordExpr_RH6u ( ISelEnv * env, IRExpr * e )
{
MIPSRH *ri;
- vassert(env->mode64);
ri = iselWordExpr_RH6u_wrk(env, e);
/* sanity checks ... */
switch (ri->tag) {
/* Check if borrow is nedded. */
addInstr(env, MIPSInstr_Cmp(False, size32, borrow, xLo, yLo, cc));
- addInstr(env, MIPSInstr_Alu(Malu_ADD, yHi, yHi, MIPSRH_Reg(borrow)));
+ addInstr(env, MIPSInstr_Alu(Malu_ADD, yHi, yHi,
+ MIPSRH_Reg(borrow)));
addInstr(env, MIPSInstr_Alu(Malu_SUB, tHi, xHi, MIPSRH_Reg(yHi)));
*rHi = tHi;
}
case Iop_Shr64: {
- HReg xLo, xHi;
- HReg tLo = newVRegI(env);
- HReg tLo1 = newVRegI(env);
- HReg tHi = newVRegI(env);
- HReg tmp = newVRegI(env);
- HReg tmp2 = newVRegI(env);
- HReg tmp3 = newVRegI(env);
- HReg mask = newVRegI(env);
- HReg tMask = newVRegI(env);
- HReg discard = newVRegI(env);
- HReg discard1 = newVRegI(env);
+#if defined (_MIPSEL)
+ /* 64-bit logical shift right based on what gcc generates:
+ <shift>:
+ nor v0, zero, a2
+ sll a3, a1, 0x1
+ sllv a3, a3, v0
+ srlv v0, a0, a2
+ srlv v1, a1, a2
+ andi a0, a2, 0x20
+ or v0, a3, v0
+ movn v0, v1, a0
+ jr ra
+ movn v1, zero, a0
+ */
+ HReg a0, a1;
+ HReg a0tmp = newVRegI(env);
+ HReg a2 = newVRegI(env);
+ HReg a3 = newVRegI(env);
+ HReg v0 = newVRegI(env);
+ HReg v1 = newVRegI(env);
+ HReg zero = newVRegI(env);
+ MIPSRH *sa = NULL;
- /* We assume any literal values are on the second operand. */
- iselInt64Expr(&xHi, &xLo, env, e->Iex.Binop.arg1);
- MIPSRH *ri_srcR = NULL;
- MIPSRH *ri_srcR_sub = NULL;
-
- ri_srcR = iselWordExpr_RH5u(env, e->Iex.Binop.arg2);
- ri_srcR_sub = iselWordExpr_RH(env, True /*signed */ ,
- e->Iex.Binop.arg2);
-
- /* Steps:
- 1. Take shift-amount (arg2) least significant bits from upper
- half of 64bit input value (arg1)
- 2. Shift upper half
- 3. Shift lower half
- 4. Put discarded bits (those from step 1) to most significant
- bit positions of lower half */
-
- /* Mask for extraction of bits that will be discarded. */
- addInstr(env, MIPSInstr_LI(tmp, 0xffffffff));
- addInstr(env, MIPSInstr_Shft(Mshft_SLL, True /*32bit shift */,
- tMask, tmp, ri_srcR));
- addInstr(env, MIPSInstr_Alu(Malu_NOR, mask,
- tMask, MIPSRH_Reg(tMask)));
-
- /* Extraction of bits that will be discarded. */
- addInstr(env, MIPSInstr_Alu(Malu_AND, discard, xHi,
- MIPSRH_Reg(mask)));
- /* Position discarded bits to most significant bit positions. */
- addInstr(env, MIPSInstr_LI(tmp3, 32));
- addInstr(env, MIPSInstr_Alu(Malu_SUB, tmp2,
- tmp3, ri_srcR_sub));
- addInstr(env, MIPSInstr_Shft(Mshft_SLL, True /*32bit shift */,
- discard1, discard, MIPSRH_Reg(tmp2)));
-
- addInstr(env, MIPSInstr_Shft(Mshft_SRL, True /*32bit shift */,
- tHi, xHi, ri_srcR));
- addInstr(env, MIPSInstr_Shft(Mshft_SRL, True /*32bit shift */,
- tLo1, xLo, ri_srcR));
-
- addInstr(env, MIPSInstr_Alu(Malu_OR, tLo,
- tLo1, MIPSRH_Reg(discard1)));
- *rHi = tHi;
- *rLo = tLo;
+ iselInt64Expr(&a1, &a0, env, e->Iex.Binop.arg1);
+ sa = iselWordExpr_RH6u(env, e->Iex.Binop.arg2);
+
+ if (sa->tag == Mrh_Imm) {
+ addInstr(env, MIPSInstr_LI(a2, sa->Mrh.Imm.imm16));
+ }
+ else {
+ addInstr(env, MIPSInstr_Alu(Malu_AND, a2, sa->Mrh.Reg.reg,
+ MIPSRH_Imm(False, 0x3f)));
+ }
+
+ addInstr(env, MIPSInstr_LI(zero, 0x00000000));
+ /* nor v0, zero, a2 */
+ addInstr(env, MIPSInstr_Alu(Malu_NOR, v0, zero, MIPSRH_Reg(a2)));
+ /* sll a3, a1, 0x1 */
+ addInstr(env, MIPSInstr_Shft(Mshft_SLL, True /* 32bit shift */,
+ a3, a1, MIPSRH_Imm(False, 0x1)));
+ /* sllv a3, a3, v0 */
+ addInstr(env, MIPSInstr_Shft(Mshft_SLL, True /* 32bit shift */,
+ a3, a3, MIPSRH_Reg(v0)));
+ /* srlv v0, a0, a2 */
+ addInstr(env, MIPSInstr_Shft(Mshft_SRL, True /* 32bit shift */,
+ v0, a0, MIPSRH_Reg(a2)));
+ /* srlv v1, a1, a2 */
+ addInstr(env, MIPSInstr_Shft(Mshft_SRL, True /* 32bit shift */,
+ v1, a1, MIPSRH_Reg(a2)));
+ /* andi a0, a2, 0x20 */
+ addInstr(env, MIPSInstr_Alu(Malu_AND, a0tmp, a2,
+ MIPSRH_Imm(False, 0x20)));
+ /* or v0, a3, v0 */
+ addInstr(env, MIPSInstr_Alu(Malu_OR, v0, a3, MIPSRH_Reg(v0)));
+
+ /* movn v0, v1, a0 */
+ addInstr(env, MIPSInstr_MoveCond(MMoveCond_movn, v0, v1, a0tmp));
+ /* movn v1, zero, a0 */
+ addInstr(env, MIPSInstr_MoveCond(MMoveCond_movn, v1, zero, a0tmp));
+
+ *rHi = v1;
+ *rLo = v0;
return;
+#elif defined (_MIPSEB)
+ /* 64-bit logical shift right based on what gcc generates:
+ <shift>:
+ nor v0, zero, a2
+ sll a3, a0, 0x1
+ sllv a3, a3, v0
+ srlv v1, a1, a2
+ andi v0, a2, 0x20
+ or v1, a3, v1
+ srlv a2, a0, a2
+ movn v1, a2, v0
+ movn a2, zero, v0
+ jr ra
+ move v0, a2
+ */
+ HReg a0, a1;
+ HReg a2 = newVRegI(env);
+ HReg a2tmp = newVRegI(env);
+ HReg a3 = newVRegI(env);
+ HReg v0 = newVRegI(env);
+ HReg v1 = newVRegI(env);
+ HReg zero = newVRegI(env);
+ MIPSRH *sa = NULL;
+
+ iselInt64Expr(&a0, &a1, env, e->Iex.Binop.arg1);
+ sa = iselWordExpr_RH6u(env, e->Iex.Binop.arg2);
+
+ if (sa->tag == Mrh_Imm) {
+ addInstr(env, MIPSInstr_LI(a2, sa->Mrh.Imm.imm16));
+ }
+ else {
+ addInstr(env, MIPSInstr_Alu(Malu_AND, a2, sa->Mrh.Reg.reg,
+ MIPSRH_Imm(False, 0x3f)));
+ }
+
+ addInstr(env, MIPSInstr_LI(zero, 0x00000000));
+ /* nor v0, zero, a2 */
+ addInstr(env, MIPSInstr_Alu(Malu_NOR, v0, zero, MIPSRH_Reg(a2)));
+ /* sll a3, a0, 0x1 */
+ addInstr(env, MIPSInstr_Shft(Mshft_SLL, True /* 32bit shift */,
+ a3, a0, MIPSRH_Imm(False, 0x1)));
+ /* sllv a3, a3, v0 */
+ addInstr(env, MIPSInstr_Shft(Mshft_SLL, True /* 32bit shift */,
+ a3, a3, MIPSRH_Reg(v0)));
+ /* srlv v1, a1, a2 */
+ addInstr(env, MIPSInstr_Shft(Mshft_SRL, True /* 32bit shift */,
+ v1, a1, MIPSRH_Reg(a2)));
+ /* andi v0, a2, 0x20 */
+ addInstr(env, MIPSInstr_Alu(Malu_AND, v0, a2,
+ MIPSRH_Imm(False, 0x20)));
+ /* or v1, a3, v1 */
+ addInstr(env, MIPSInstr_Alu(Malu_OR, v1, a3, MIPSRH_Reg(v1)));
+ /* srlv a2, a0, a2 */
+ addInstr(env, MIPSInstr_Shft(Mshft_SRL, True /* 32bit shift */,
+ a2tmp, a0, MIPSRH_Reg(a2)));
+
+ /* movn v1, a2, v0 */
+ addInstr(env, MIPSInstr_MoveCond(MMoveCond_movn, v1, a2tmp, v0));
+ /* movn a2, zero, v0 */
+ addInstr(env, MIPSInstr_MoveCond(MMoveCond_movn, a2tmp, zero, v0));
+ /* move v0, a2 */
+ addInstr(env, mk_iMOVds_RR(v0, a2tmp));
+
+ *rHi = v0;
+ *rLo = v1;
+ return;
+#endif
}
+
case Iop_Shl64: {
- HReg xLo, xHi;
- HReg tLo = newVRegI(env);
- HReg tHi1 = newVRegI(env);
- HReg tHi = newVRegI(env);
- HReg tmp = newVRegI(env);
- HReg tmp2 = newVRegI(env);
- HReg tmp3 = newVRegI(env);
- HReg mask = newVRegI(env);
- HReg tMask = newVRegI(env);
- HReg discard = newVRegI(env);
- HReg discard1 = newVRegI(env);
+ /* 64-bit shift left based on what gcc generates:
+ <shift>:
+ nor v0,zero,a2
+ srl a3,a0,0x1
+ srlv a3,a3,v0
+ sllv v1,a1,a2
+ andi v0,a2,0x20
+ or v1,a3,v1
+ sllv a2,a0,a2
+ movn v1,a2,v0
+ movn a2,zero,v0
+ jr ra
+ move v0,a2
+ */
+ HReg a0, a1;
+ HReg a2 = newVRegI(env);
+ HReg a3 = newVRegI(env);
+ HReg v0 = newVRegI(env);
+ HReg v1 = newVRegI(env);
+ HReg zero = newVRegI(env);
+ MIPSRH *sa = NULL;
- /* We assume any literal values are on the second operand. */
- iselInt64Expr(&xHi, &xLo, env, e->Iex.Binop.arg1);
- MIPSRH *ri_srcR = NULL;
- MIPSRH *ri_srcR_sub = NULL;
-
- ri_srcR = iselWordExpr_RH5u(env, e->Iex.Binop.arg2);
- ri_srcR_sub = iselWordExpr_RH(env, True /*signed */ ,
- e->Iex.Binop.arg2);
-
- /* Steps:
- 1. Take shift-amount (arg2) most significant bits from lower
- half of 64bit input value (arg1)
- 2. Shift lower half
- 3. Shift upper half
- 4. Put discarded bits (those from step 1) to least significant
- bit positions of upper half */
-
- /* Mask for extraction of bits that will be discarded. */
- addInstr(env, MIPSInstr_LI(tmp, 0xffffffff));
- addInstr(env, MIPSInstr_Shft(Mshft_SRL, True /*32bit shift */,
- tMask, tmp, ri_srcR));
- addInstr(env, MIPSInstr_Alu(Malu_NOR, mask,
- tMask, MIPSRH_Reg(tMask)));
-
- /* Extraction of bits that will be discarded. */
- addInstr(env, MIPSInstr_Alu(Malu_AND, discard, xLo,
- MIPSRH_Reg(mask)));
- /* Position discarded bits to least significant bit positions. */
- addInstr(env, MIPSInstr_LI(tmp3, 32));
- addInstr(env, MIPSInstr_Alu(Malu_SUB, tmp2,
- tmp3, ri_srcR_sub));
- addInstr(env, MIPSInstr_Shft(Mshft_SRL, True /*32bit shift */,
- discard1, discard, MIPSRH_Reg(tmp2)));
-
- addInstr(env, MIPSInstr_Shft(Mshft_SLL, True /*32bit shift */,
- tHi1, xHi, ri_srcR));
- addInstr(env, MIPSInstr_Shft(Mshft_SLL, True /*32bit shift */,
- tLo, xLo, ri_srcR));
-
- addInstr(env, MIPSInstr_Alu(Malu_OR, tHi,
- tHi1, MIPSRH_Reg(discard1)));
- *rHi = tHi;
- *rLo = tLo;
+ iselInt64Expr(&a1, &a0, env, e->Iex.Binop.arg1);
+ sa = iselWordExpr_RH6u(env, e->Iex.Binop.arg2);
+
+ if (sa->tag == Mrh_Imm) {
+ addInstr(env, MIPSInstr_LI(a2, sa->Mrh.Imm.imm16));
+ }
+ else {
+ addInstr(env, MIPSInstr_Alu(Malu_AND, a2, sa->Mrh.Reg.reg,
+ MIPSRH_Imm(False, 0x3f)));
+ }
+
+ addInstr(env, MIPSInstr_LI(zero, 0x00000000));
+ /* nor v0, zero, a2 */
+ addInstr(env, MIPSInstr_Alu(Malu_NOR, v0, zero, MIPSRH_Reg(a2)));
+ /* srl a3, a0, 0x1 */
+ addInstr(env, MIPSInstr_Shft(Mshft_SRL, True /* 32bit shift */,
+ a3, a0, MIPSRH_Imm(False, 0x1)));
+ /* srlv a3, a3, v0 */
+ addInstr(env, MIPSInstr_Shft(Mshft_SRL, True /* 32bit shift */,
+ a3, a3, MIPSRH_Reg(v0)));
+ /* sllv v1, a1, a2 */
+ addInstr(env, MIPSInstr_Shft(Mshft_SLL, True /* 32bit shift */,
+ v1, a1, MIPSRH_Reg(a2)));
+ /* andi v0, a2, 0x20 */
+ addInstr(env, MIPSInstr_Alu(Malu_AND, v0, a2,
+ MIPSRH_Imm(False, 0x20)));
+ /* or v1, a3, v1 */
+ addInstr(env, MIPSInstr_Alu(Malu_OR, v1, a3, MIPSRH_Reg(v1)));
+ /* sllv a2, a0, a2 */
+ addInstr(env, MIPSInstr_Shft(Mshft_SLL, True /* 32bit shift */,
+ a2, a0, MIPSRH_Reg(a2)));
+
+ /* movn v1, a2, v0 */
+ addInstr(env, MIPSInstr_MoveCond(MMoveCond_movn, v1, a2, v0));
+ /* movn a2, zero, v0 */
+ addInstr(env, MIPSInstr_MoveCond(MMoveCond_movn, a2, zero, v0));
+ addInstr(env, mk_iMOVds_RR(v0, a2));
+
+ *rHi = v1;
+ *rLo = v0;
return;
}
+
case Iop_Sar64: {
- HReg xLo, xHi;
- HReg tLo = newVRegI(env);
- HReg tLo1 = newVRegI(env);
- HReg tHi = newVRegI(env);
- HReg tmp = newVRegI(env);
- HReg tmp2 = newVRegI(env);
- HReg tmp3 = newVRegI(env);
- HReg mask = newVRegI(env);
- HReg tMask = newVRegI(env);
- HReg discard = newVRegI(env);
- HReg discard1 = newVRegI(env);
+ /* 64-bit arithmetic shift right based on what gcc generates:
+ <shift>:
+ nor v0, zero, a2
+ sll a3, a1, 0x1
+ sllv a3, a3, v0
+ srlv v0, a0, a2
+ srav v1, a1, a2
+ andi a0, a2, 0x20
+ sra a1, a1, 0x1f
+ or v0, a3, v0
+ movn v0, v1, a0
+ jr ra
+ movn v1, a1, a0
+ */
+ HReg a0, a1;
+ HReg a0tmp = newVRegI(env);
+ HReg a1tmp = newVRegI(env);
+ HReg a2 = newVRegI(env);
+ HReg a3 = newVRegI(env);
+ HReg v0 = newVRegI(env);
+ HReg v1 = newVRegI(env);
+ HReg zero = newVRegI(env);
+ MIPSRH *sa = NULL;
- /* We assume any literal values are on the second operand. */
- iselInt64Expr(&xHi, &xLo, env, e->Iex.Binop.arg1);
- MIPSRH *ri_srcR = NULL;
- MIPSRH *ri_srcR_sub = NULL;
-
- ri_srcR = iselWordExpr_RH5u(env, e->Iex.Binop.arg2);
- ri_srcR_sub = iselWordExpr_RH(env, True /*signed */ ,
- e->Iex.Binop.arg2);
-
- /* Steps:
- 1. Take shift-amount (arg2) least significant bits from upper
- half of 64bit input value (arg1)
- 2. Shift upper half
- 3. Shift lower half
- 4. Put discarded bits (those from step 1) to most significant
- bit positions of lower half */
-
- /* Mask for extraction of bits that will be discarded. */
- addInstr(env, MIPSInstr_LI(tmp, 0xffffffff));
- addInstr(env, MIPSInstr_Shft(Mshft_SLL, True /*32bit shift */,
- tMask, tmp, ri_srcR));
- addInstr(env, MIPSInstr_Alu(Malu_NOR, mask,
- tMask, MIPSRH_Reg(tMask)));
-
- /* Extraction of bits that will be discarded. */
- addInstr(env, MIPSInstr_Alu(Malu_AND, discard, xHi,
- MIPSRH_Reg(mask)));
- /* Position discarded bits to most significant bit positions. */
- addInstr(env, MIPSInstr_LI(tmp3, 32));
- addInstr(env, MIPSInstr_Alu(Malu_SUB, tmp2,
- tmp3, ri_srcR_sub));
- addInstr(env, MIPSInstr_Shft(Mshft_SLL, True /*32bit shift */,
- discard1, discard, MIPSRH_Reg(tmp2)));
-
- addInstr(env, MIPSInstr_Shft(Mshft_SRA, True /*32bit shift */,
- tHi, xHi, ri_srcR));
- addInstr(env, MIPSInstr_Shft(Mshft_SRL, True /*32bit shift */,
- tLo1, xLo, ri_srcR));
-
- addInstr(env, MIPSInstr_Alu(Malu_OR, tLo,
- tLo1, MIPSRH_Reg(discard1)));
- *rHi = tHi;
- *rLo = tLo;
+ iselInt64Expr(&a1, &a0, env, e->Iex.Binop.arg1);
+ sa = iselWordExpr_RH6u(env, e->Iex.Binop.arg2);
+
+ if (sa->tag == Mrh_Imm) {
+ addInstr(env, MIPSInstr_LI(a2, sa->Mrh.Imm.imm16));
+ }
+ else {
+ addInstr(env, MIPSInstr_Alu(Malu_AND, a2, sa->Mrh.Reg.reg,
+ MIPSRH_Imm(False, 0x3f)));
+ }
+
+ addInstr(env, MIPSInstr_LI(zero, 0x00000000));
+ /* nor v0, zero, a2 */
+ addInstr(env, MIPSInstr_Alu(Malu_NOR, v0, zero, MIPSRH_Reg(a2)));
+ /* sll a3, a1, 0x1 */
+ addInstr(env, MIPSInstr_Shft(Mshft_SLL, True /* 32bit shift */,
+ a3, a1, MIPSRH_Imm(False, 0x1)));
+ /* sllv a3, a3, v0 */
+ addInstr(env, MIPSInstr_Shft(Mshft_SLL, True /* 32bit shift */,
+ a3, a3, MIPSRH_Reg(v0)));
+ /* srlv v0, a0, a2 */
+ addInstr(env, MIPSInstr_Shft(Mshft_SRL, True /* 32bit shift */,
+ v0, a0, MIPSRH_Reg(a2)));
+ /* srav v1, a1, a2 */
+ addInstr(env, MIPSInstr_Shft(Mshft_SRA, True /* 32bit shift */,
+ v1, a1, MIPSRH_Reg(a2)));
+ /* andi a0, a2, 0x20 */
+ addInstr(env, MIPSInstr_Alu(Malu_AND, a0tmp, a2,
+ MIPSRH_Imm(False, 0x20)));
+ /* sra a1, a1, 0x1f */
+ addInstr(env, MIPSInstr_Shft(Mshft_SRA, True /* 32bit shift */,
+ a1tmp, a1, MIPSRH_Imm(False, 0x1f)));
+ /* or v0, a3, v0 */
+ addInstr(env, MIPSInstr_Alu(Malu_OR, v0, a3, MIPSRH_Reg(v0)));
+
+ /* movn v0, v1, a0 */
+ addInstr(env, MIPSInstr_MoveCond(MMoveCond_movn, v0, v1, a0tmp));
+ /* movn v1, a1, a0 */
+ addInstr(env, MIPSInstr_MoveCond(MMoveCond_movn, v1, a1tmp, a0tmp));
+
+ *rHi = v1;
+ *rLo = v0;
return;
}
addInstr(env, MIPSInstr_Shft(Mshft_SLL, True, tmp, src,
MIPSRH_Imm(False, 31)));
- addInstr(env, MIPSInstr_Shft(Mshft_SRA, True, tmp, src,
+ addInstr(env, MIPSInstr_Shft(Mshft_SRA, True, tmp, tmp,
MIPSRH_Imm(False, 31)));
addInstr(env, mk_iMOVds_RR(tHi, tmp));
}
case Iop_Left64: {
- HReg yLo, yHi, borrow;
+ HReg yHi, yLo;
HReg tHi = newVRegI(env);
HReg tLo = newVRegI(env);
+ HReg tmp = newVRegI(env);
+ HReg tmp1 = newVRegI(env);
+ HReg tmp2 = newVRegI(env);
HReg zero = newVRegI(env);
- Bool size32 = True;
MIPSCondCode cc = MIPScc_LO;
- borrow = newVRegI(env);
-
/* yHi:yLo = arg */
iselInt64Expr(&yHi, &yLo, env, e->Iex.Unop.arg);
/* zero = 0 */
addInstr(env, MIPSInstr_LI(zero, 0x00000000));
- /* tLo = 0 - yLo */
- addInstr(env, MIPSInstr_Alu(Malu_SUB, tLo, zero, MIPSRH_Reg(yLo)));
-
- /* Check if borrow is needed. */
- addInstr(env, MIPSInstr_Cmp(False, size32, borrow, zero, yLo, cc));
+ /* tmp2:tmp1 = 0 - (yHi:yLo)*/
+ addInstr(env, MIPSInstr_Alu(Malu_SUB, tmp2, zero, MIPSRH_Reg(yLo)));
+ addInstr(env, MIPSInstr_Cmp(False, True, tmp1, zero, tmp2, cc));
+ addInstr(env, MIPSInstr_Alu(Malu_SUB, tmp, zero, MIPSRH_Reg(yHi)));
+ addInstr(env, MIPSInstr_Alu(Malu_SUB, tmp1, tmp, MIPSRH_Reg(tmp1)));
- /* tHi = 0 - (yHi + borrow) */
- addInstr(env, MIPSInstr_Alu(Malu_ADD,
- yHi, yHi, MIPSRH_Reg(borrow)));
- addInstr(env, MIPSInstr_Alu(Malu_SUB, tHi, zero, MIPSRH_Reg(yHi)));
- /* So now we have tHi:tLo = -arg. To finish off, or 'arg'
+ /* So now we have tmp2:tmp1 = -arg. To finish off, or 'arg'
back in, so as to give the final result
tHi:tLo = arg | -arg. */
- addInstr(env, MIPSInstr_Alu(Malu_OR, tHi, tHi, MIPSRH_Reg(yHi)));
- addInstr(env, MIPSInstr_Alu(Malu_OR, tLo, tLo, MIPSRH_Reg(yLo)));
+ addInstr(env, MIPSInstr_Alu(Malu_OR, tHi, yHi, MIPSRH_Reg(tmp1)));
+ addInstr(env, MIPSInstr_Alu(Malu_OR, tLo, yLo, MIPSRH_Reg(tmp2)));
*rHi = tHi;
*rLo = tLo;
return;