/* Generate a new temporary of the given type. */
static IRTemp newTemp ( IRType ty )
{
+ vassert(isPlausibleType(ty));
return newIRTemp( irbb->tyenv, ty );
}
if (shifts == 0)
return mkexpr(eflags);
else
- return binop(Iop_Shr32, mkexpr(eflags), mkU32(shifts));
+ return binop(Iop_Shr32, mkexpr(eflags), mkU8(shifts));
}
binop(Iop_Add32,
getIReg(4,base_r),
binop(Iop_Shl32, getIReg(4,index_r),
- mkU32(scale)))));
+ mkU8(scale)))));
}
if (index_r != R_ESP && base_r == R_EBP) {
disAMode_copy2tmp(
handleSegOverride(sorb,
binop(Iop_Add32,
- binop(Iop_Shl32, getIReg(4,index_r), mkU32(scale)),
+ binop(Iop_Shl32, getIReg(4,index_r), mkU8(scale)),
mkU32(d))));
}
binop(Iop_Add32,
getIReg(4,base_r),
binop(Iop_Shl32,
- getIReg(4,index_r), mkU32(scale))),
+ getIReg(4,index_r), mkU8(scale))),
mkU32(d))));
}
vassert(0);
binop(Iop_Add32,
getIReg(4,base_r),
binop(Iop_Shl32,
- getIReg(4,index_r), mkU32(scale))),
+ getIReg(4,index_r), mkU8(scale))),
mkU32(d))));
}
vassert(0);
}
-/* Group 2 extended opcodes. */
+/* Group 2 extended opcodes. shift_expr must be an 8-bit typed
+ expression. */
+
static
UInt dis_Grp2 ( UChar sorb,
UInt delta, UChar modrm,
- Int am_sz, Int d_sz, Int sz, IRExpr* shift_expr )
+ Int am_sz, Int d_sz, Int sz, IRExpr* shift_expr,
+ Char* shift_expr_txt )
{
/* delta on entry points at the modrm byte. */
- UChar dis_buf[50];
- Int len;
- IROp op8;
- IRType ty = szToITy(sz);
- IRTemp dst0 = newTemp(ty);
- IRTemp dst1 = newTemp(ty);
- IRTemp addr = INVALID_IRTEMP;
- Bool isShift;
-
- // IRTemp dst1 = newTemp(ty);
- // IRTemp src = newTemp(ty);
- // IRTemp dst0 = newTemp(ty);
+ UChar dis_buf[50];
+ Int len;
+ IROp op8;
+ Bool isShift;
+ IRType ty = szToITy(sz);
+ IRTemp dst0 = newTemp(ty);
+ IRTemp dst1 = newTemp(ty);
+ IRTemp addr = INVALID_IRTEMP;
vassert(sz == 1 || sz == 2 || sz == 4);
if (isShift) {
IRTemp subshift = newTemp(ty);
- IRTemp shift_amt = newTemp(ty);
+ IRTemp shift_amt = newTemp(Ity_I8);
IRTemp guard = newTemp(Ity_Bit);
switch (gregOfRM(modrm)) {
}
/* shift_amt = shift_expr & mask */
- assign(shift_amt, binop(mkSizedOp(ty,Iop_And8),
- shift_expr, mkU(ty,8*sz-1)));
+ assign(shift_amt, binop(Iop_And8,
+ shift_expr, mkU8(8*sz-1)));
/* dst1 = dst0 `shift` shift_amt */
assign(dst1, binop(mkSizedOp(ty,op8),
mkexpr(dst0), mkexpr(shift_amt)));
assign(subshift,
binop(mkSizedOp(ty,op8),
mkexpr(dst0),
- binop(mkSizedOp(ty,Iop_Sub8),
- mkexpr(shift_amt), mkU(ty,1))));
+ binop(Iop_And8,
+ binop(Iop_Sub8,
+ mkexpr(shift_amt), mkU8(1)),
+ mkU8(8*sz-1))));
/* guard = (shift_amt != 0) */
- assign(guard, binop(mkSizedOp(ty,Iop_CmpNE8),
- mkexpr(shift_amt), mkU(ty,0)));
+ assign(guard, binop(Iop_CmpNE8,
+ mkexpr(shift_amt), mkU8(0)));
/* Build the flags thunk. */
setFlags_DSTus_DST1(op8, subshift, dst1, ty, guard);
if (print_codegen) {
vex_printf("%s%c ",
nameGrp2(gregOfRM(modrm)), nameISize(sz) );
- ppIRExpr(shift_expr);
+ if (shift_expr_txt)
+ vex_printf("%s", shift_expr_txt);
+ else
+ ppIRExpr(shift_expr);
vex_printf(", %s\n", nameIReg(sz,eregOfRM(modrm)));
}
} else {
if (print_codegen) {
vex_printf("%s%c ",
nameGrp2(gregOfRM(modrm)), nameISize(sz) );
- ppIRExpr(shift_expr);
+ if (shift_expr_txt)
+ vex_printf("%s", shift_expr_txt);
+ else
+ ppIRExpr(shift_expr);
vex_printf(", %s\n", dis_buf);
}
}
if (sz == 4 || sz == 2) {
assign( t_inc,
binop(Iop_Shl32, IRExpr_Get( OFFB_DFLAG, Ity_I32 ),
- mkU32(sz/2) ) );
+ mkU8(sz/2) ) );
} else {
assign( t_inc,
IRExpr_Get( OFFB_DFLAG, Ity_I32 ) );
assign( td, getIReg(4, R_EDI) );
//uInstr2(cb, STORE, sz, TempReg, ta, TempReg, td);
- storeLE( mkexpr(ta), mkexpr(td) );
+ storeLE( mkexpr(td), mkexpr(ta) );
//uInstr2(cb, ADD, 4, TempReg, t_inc, TempReg, td);
//uInstr2(cb, PUT, 4, TempReg, td, ArchReg, R_EDI);
void dis_CMPS ( Int sz, IRTemp t_inc )
{
IRType ty = szToITy(sz);
- IRTemp tdv = newTemp(sz); /* (EDI) */
- IRTemp tsv = newTemp(sz); /* (ESI) */
+ IRTemp tdv = newTemp(ty); /* (EDI) */
+ IRTemp tsv = newTemp(ty); /* (ESI) */
IRTemp td = newTemp(Ity_I32); /* EDI */
IRTemp ts = newTemp(Ity_I32); /* ESI */
UChar rm = getIByte(delta0);
IRType ty = szToITy(size);
//IRTemp ta = INVALID_IRTEMP;
- IRTemp te = newTemp(size);
- IRTemp tg = newTemp(size);
+ IRTemp te = newTemp(ty);
+ IRTemp tg = newTemp(ty);
if (epartIsReg(rm)) {
vassert(signed_multiply);
Int len;
UChar dis_buf[50];
- IRType ty = szToITy(sz);
- IRTemp gsrc = newTemp(ty);
- IRTemp esrc = newTemp(ty);
- IRTemp addr = INVALID_IRTEMP;
- IRTemp tmpSH = newTemp(Ity_I8);
- IRTemp guard = newTemp(Ity_I32);
- IRTemp tmpL = INVALID_IRTEMP;
- IRTemp tmpRes = INVALID_IRTEMP;
+ IRType ty = szToITy(sz);
+ IRTemp gsrc = newTemp(ty);
+ IRTemp esrc = newTemp(ty);
+ IRTemp addr = INVALID_IRTEMP;
+ IRTemp tmpSH = newTemp(Ity_I8);
+ IRTemp guard = newTemp(Ity_Bit);
+ IRTemp tmpL = INVALID_IRTEMP;
+ IRTemp tmpRes = INVALID_IRTEMP;
IRTemp tmpSubSh = INVALID_IRTEMP;
IROp mkpair;
IROp getres;
putIReg(sz, R_EDX,
binop(mkSizedOp(ty,Iop_Sar8),
getIReg(sz, R_EAX),
- mkU(ty,sz == 2 ? 15 : 31)) );
+ mkU8(sz == 2 ? 15 : 31)) );
DIP(sz == 2 ? "cwdq\n" : "cdqq\n");
break;
d_sz = 1;
d32 = getSDisp8(delta + am_sz);
sz = 1;
- delta = dis_Grp2 ( sorb, delta, modrm, am_sz, d_sz, sz, mkU32(d32) );
+ delta = dis_Grp2 ( sorb, delta, modrm, am_sz, d_sz, sz,
+ mkU8(d32 & 0xFF), NULL );
break;
case 0xC1: /* Grp2 Ib,Ev */
am_sz = lengthAMode(delta);
d_sz = 1;
d32 = getSDisp8(delta + am_sz);
- delta = dis_Grp2 ( sorb, delta, modrm, am_sz, d_sz, sz, mkU32(d32) );
+ delta = dis_Grp2 ( sorb, delta, modrm, am_sz, d_sz, sz,
+ mkU8(d32 & 0xFF), NULL );
break;
//-- case 0xD0: /* Grp2 1,Eb */
am_sz = lengthAMode(delta);
d_sz = 0;
d32 = 1;
- delta = dis_Grp2 ( sorb, delta, modrm, am_sz, d_sz, sz, mkU32(d32) );
+ delta = dis_Grp2 ( sorb, delta, modrm, am_sz, d_sz, sz,
+ mkU8(d32), NULL );
break;
//-- case 0xD2: /* Grp2 CL,Eb */
am_sz = lengthAMode(delta);
d_sz = 0;
delta = dis_Grp2 ( sorb, delta, modrm, am_sz, d_sz, sz,
- getIReg(sz,R_ECX) );
+ getIReg(1,R_ECX), "%cl" );
break;
/* ------------------------ (Grp3 extensions) ---------- */
case Ity_I16: vex_printf( "I16"); break;
case Ity_I32: vex_printf( "I32"); break;
case Ity_I64: vex_printf( "I64"); break;
- default: vpanic("ppIRType");
+ default: vex_printf("ty = 0x%x\n", (Int)ty);
+ vpanic("ppIRType");
}
}
case Iop_CmpEQ64: case Iop_CmpNE64:
COMPARISON(Ity_I64);
+ case Iop_MullU32: case Iop_MullS32:
+ BINARY(Ity_I64,Ity_I32,Ity_I32);
+
+ case Iop_DivModU64to32:
+ BINARY(Ity_I64,Ity_I64,Ity_I32);
+
+ case Iop_64HIto32: case Iop_64LOto32:
+ UNARY(Ity_I32, Ity_I64);
+ case Iop_32HLto64:
+ BINARY(Ity_I64,Ity_I32,Ity_I32);
+
+ case Iop_1Uto8: UNARY(Ity_I8,Ity_Bit);
+ case Iop_32to1: UNARY(Ity_Bit,Ity_I32);
+ case Iop_8Uto32: UNARY(Ity_I32,Ity_I8);
+ case Iop_16Uto32: UNARY(Ity_I32,Ity_I16);
+
default:
ppIROp(op);
vpanic("typeOfPrimop");
}
}
+/* Is this any value actually in the enumeration 'IRType' ? */
+Bool isPlausibleType ( IRType ty )
+{
+ switch (ty) {
+ case Ity_INVALID: case Ity_Bit:
+ case Ity_I8: case Ity_I16: case Ity_I32: case Ity_I64:
+ return True;
+ default:
+ return False;
+ }
+}
+
/*---------------------------------------------------------------*/
/*--- Sanity checking ---*/
case Iex_Get:
case Iex_Tmp:
break;
- case Iex_Binop:
+ case Iex_Binop: {
+ IRType ttarg1, ttarg2;
tcExpr(bb,stmt, expr->Iex.Binop.arg1, gWordTy );
tcExpr(bb,stmt, expr->Iex.Binop.arg2, gWordTy );
typeOfPrimop(expr->Iex.Binop.op, &t_dst, &t_arg1, &t_arg2);
if (t_arg1 == Ity_INVALID || t_arg2 == Ity_INVALID)
sanityCheckFail(bb,stmt,"Iex.Binop: wrong arity op");
- if (t_arg1 != typeOfIRExpr(tyenv, expr->Iex.Binop.arg1)
- || t_arg2 != typeOfIRExpr(tyenv, expr->Iex.Binop.arg1))
- sanityCheckFail(bb,stmt,"Iex.Binop: arg tys don't match op tys");
+ ttarg1 = typeOfIRExpr(tyenv, expr->Iex.Binop.arg1);
+ ttarg2 = typeOfIRExpr(tyenv, expr->Iex.Binop.arg2);
+ if (t_arg1 != ttarg1 || t_arg2 != ttarg2) {
+ vex_printf(" op name: ");
+ ppIROp(expr->Iex.Binop.op);
+ vex_printf("\n");
+ vex_printf(" op type is (");
+ ppIRType(t_arg1);
+ vex_printf(",");
+ ppIRType(t_arg2);
+ vex_printf(") -> ");
+ ppIRType (t_dst);
+ vex_printf("\narg tys are (");
+ ppIRType(ttarg1);
+ vex_printf(",");
+ ppIRType(ttarg2);
+ vex_printf(")\n");
+ sanityCheckFail(bb,stmt,
+ "Iex.Binop: arg tys don't match op tys\n"
+ "... additional details precede BB printout\n");
+ }
break;
+ }
case Iex_Unop:
tcExpr(bb,stmt, expr->Iex.Unop.arg, gWordTy );
typeOfPrimop(expr->Iex.Binop.op, &t_dst, &t_arg1, &t_arg2);
tcExpr( bb, stmt, stmt->Ist.Tmp.expr, gWordTy );
if (lookupIRTypeEnv(tyenv, stmt->Ist.Tmp.tmp)
!= typeOfIRExpr(tyenv, stmt->Ist.Tmp.expr))
- sanityCheckFail(bb,stmt,"IRStmt.Put.TMp: tmp and expr do not match");
+ sanityCheckFail(bb,stmt,"IRStmt.Put.Tmp: tmp and expr do not match");
break;
case Ist_STle:
tcExpr( bb, stmt, stmt->Ist.STle.addr, gWordTy );
}
}
-
void sanityCheckIRBB ( IRBB* bb, IRType guest_word_size )
{
Int i;
vassert(guest_word_size == Ity_I32
|| guest_word_size == Ity_I64);
- for (i = 0; i < n_temps; i++)
- def_counts[i] = 0;
+ /* Ensure each temp has a plausible type. */
+ for (i = 0; i < n_temps; i++) {
+ IRType ty = lookupIRTypeEnv(bb->tyenv,(IRTemp)i);
+ if (!isPlausibleType(ty)) {
+ vex_printf("Temp t%d declared with implausible type 0x%x\n",
+ i, (UInt)ty);
+ sanityCheckFail(bb,NULL,"Temp declared with implausible type");
+ }
+ }
/* Count the defs of each temp. Only one def is allowed.
Also, check that each used temp has already been defd. */
+
+ for (i = 0; i < n_temps; i++)
+ def_counts[i] = 0;
+
for (stmt = bb->stmts; stmt; stmt=stmt->link) {
useBeforeDef_Stmt(bb,stmt,def_counts);
if (stmt->tag == Ist_Tmp) {