/* CC_SRC = undershifted %d after, CC_DST = %d afterwards */
stmt( IRStmt_Put( OFFB_CC_OP,
- IRExpr_Mux10( mkexpr(guard),
- mkU32(ccOp),
- IRExpr_Get(OFFB_CC_OP,Ity_I32))) );
+ IRExpr_Mux0X( mkexpr(guard),
+ IRExpr_Get(OFFB_CC_OP,Ity_I32),
+ mkU32(ccOp))) );
stmt( IRStmt_Put( OFFB_CC_SRC,
- IRExpr_Mux10( mkexpr(guard),
- widenUTo32(mkexpr(dstUS)),
- IRExpr_Get(OFFB_CC_SRC,Ity_I32))) );
+ IRExpr_Mux0X( mkexpr(guard),
+ IRExpr_Get(OFFB_CC_SRC,Ity_I32),
+ widenUTo32(mkexpr(dstUS)))) );
stmt( IRStmt_Put( OFFB_CC_DST,
- IRExpr_Mux10( mkexpr(guard),
- widenUTo32(mkexpr(dst1)),
- IRExpr_Get(OFFB_CC_DST,Ity_I32))) );
+ IRExpr_Mux0X( mkexpr(guard),
+ IRExpr_Get(OFFB_CC_DST,Ity_I32),
+ widenUTo32(mkexpr(dst1)))) );
}
IRTemp subshift = newTemp(ty);
IRTemp shift_amt = newTemp(Ity_I8);
- IRTemp guard = newTemp(Ity_Bit);
+ // IRTemp guard = newTemp(Ity_Bit);
switch (gregOfRM(modrm)) {
case 4: op8 = Iop_Shl8; break;
mkexpr(shift_amt), mkU8(1)),
mkU8(8*sz-1))));
/* guard = (shift_amt != 0) */
- assign(guard, binop(Iop_CmpNE8,
- mkexpr(shift_amt), mkU8(0)));
+ // assign(guard, binop(Iop_CmpNE8,
+ // mkexpr(shift_amt), mkU8(0)));
/* Build the flags thunk. */
- setFlags_DSTus_DST1(op8, subshift, dst1, ty, guard);
+ setFlags_DSTus_DST1(op8, subshift, dst1, ty, shift_amt);
} else {
/* Rotate */
vpanic("dis_Grp2: rotate");
IRTemp esrc = newTemp(ty);
IRTemp addr = INVALID_IRTEMP;
IRTemp tmpSH = newTemp(Ity_I8);
- IRTemp guard = newTemp(Ity_Bit);
+ // IRTemp guard = newTemp(Ity_Bit);
IRTemp tmpL = INVALID_IRTEMP;
IRTemp tmpRes = INVALID_IRTEMP;
IRTemp tmpSubSh = INVALID_IRTEMP;
binop(Iop_And8,
binop(Iop_Sub8, mkexpr(tmpSH), mkU8(1) ),
mask))) );
- assign( guard, binop(Iop_CmpNE8, mkexpr(tmpSH), mkU8(0)) );
+ //assign( guard, binop(Iop_CmpNE8, mkexpr(tmpSH), mkU8(0)) );
setFlags_DSTus_DST1 (
left_shift ? Iop_Shl8 : Iop_Sar8,
- tmpSubSh, tmpRes, ty, guard );
+ tmpSubSh, tmpRes, ty, tmpSH );
/* Put result back. */
/*---------------------------------------------------------*/
/* forwards ... */
-static X86RMI* iselIntExpr_RMI ( ISelEnv* env, IRExpr* e );
+static X86RMI* iselIntExpr_RMI ( ISelEnv* env, IRExpr* e );
+static X86RM* iselIntExpr_RM ( ISelEnv* env, IRExpr* e );
static X86AMode* iselIntExpr_AMode ( ISelEnv* env, IRExpr* e );
there, and modify the copy. The register allocator will do its
best to map both vregs to the same real register, so the copies
will often disappear later in the game.
+
+ This should handle expressions of 32, 16 and 8-bit type. All
+ results are returned in a 32-bit register. For 16- and 8-bit
+ expressions, the upper 16/24 bits are arbitrary, so you should
+ mask or sign extend partial values if necessary.
*/
static HReg iselIntExpr_R ( ISelEnv* env, IRExpr* e )
{
vassert(e);
IRType ty = typeOfIRExpr(env->type_env,e);
+ vassert(ty == Ity_I32 || Ity_I16 || Ity_I8);
switch (e->tag) {
case Iex_Tmp: {
- vassert(ty == Ity_I32);
return lookupIRTemp(env, e->Iex.Tmp.tmp);
}
case Iex_LDle: {
- X86AMode* amode = iselIntExpr_AMode ( env, e->Iex.LDle.addr );
HReg dst = newVRegI(env);
- vassert(ty == Ity_I32);
- addInstr(env, X86Instr_Alu32R(Xalu_MOV,
- X86RMI_Mem(amode), dst) );
- return dst;
+ X86AMode* amode = iselIntExpr_AMode ( env, e->Iex.LDle.addr );
+ if (ty == Ity_I32) {
+ addInstr(env, X86Instr_Alu32R(Xalu_MOV,
+ X86RMI_Mem(amode), dst) );
+ return dst;
+ }
+ if (ty == Ity_I16) {
+ addInstr(env, X86Instr_LoadEX(2,False,amode,dst));
+ return dst;
+ }
+ break;
}
case Iex_Binop: {
X86AluOp aluOp;
X86ShiftOp shOp;
- vassert(ty == Ity_I32);
+ /* Is it an addition or logical style op? */
switch (e->Iex.Binop.op) {
case Iop_Add32: aluOp = Xalu_ADD; break;
+
+ case Iop_Sub8: case Iop_Sub16:
case Iop_Sub32: aluOp = Xalu_SUB; break;
+
+ case Iop_And8:
case Iop_And32: aluOp = Xalu_AND; break;
case Iop_Or32: aluOp = Xalu_OR; break;
case Iop_Xor32: aluOp = Xalu_XOR; break;
addInstr(env, X86Instr_Alu32R(aluOp, rmi, dst));
return dst;
}
+ /* Perhaps a shift op? */
switch (e->Iex.Binop.op) {
case Iop_Shl32: shOp = Xsh_SHL; break;
case Iop_Shr32: shOp = Xsh_SHR; break;
break;
}
+ case Iex_Unop: {
+ switch (e->Iex.Unop.op) {
+ case Iop_8Uto32: {
+ HReg dst = newVRegI(env);
+ HReg src = iselIntExpr_R(env, e->Iex.Unop.arg);
+ addInstr(env, mk_MOV_RR(src,dst) );
+ addInstr(env, X86Instr_Alu32R(Xalu_AND,
+ X86RMI_Imm(0xFF), dst));
+ return dst;
+ }
+ default:
+ break;
+ }
+ break;
+ }
+
case Iex_Get: {
if (ty == Ity_I32) {
HReg dst = newVRegI(env);
dst));
return dst;
}
+ if (ty == Ity_I8) {
+ HReg dst = newVRegI(env);
+ addInstr(env, X86Instr_LoadEX(
+ 1,False,
+ X86AMode_IR(e->Iex.Get.offset,hregX86_EBP()),
+ dst));
+ return dst;
+ }
break;
}
vassert(ty == Ity_I32);
/* be very restrictive for now. Only 32-bit ints allowed
for args and return type. */
- if (e->Iex.CCall.retty != Ity_I32)
- break;
+ if (e->Iex.CCall.retty != Ity_I32)
+ break;
/* push args on the stack, right to left. */
- nargs = 0;
- while (e->Iex.CCall.args[nargs]) nargs++;
- for (i = nargs-1; i >= 0; i--) {
- arg = e->Iex.CCall.args[i];
- if (typeOfIRExpr(env->type_env,arg) != Ity_I32)
- goto irreducible;
- addInstr(env, X86Instr_Push(iselIntExpr_RMI(env, arg)));
- }
- target = 0x12345678; //FIND_HELPER(e->Iex.CCall.name);
- addInstr(env, X86Instr_Alu32R(
- Xalu_MOV,
- X86RMI_Imm(target),
- hregX86_EAX()));
- addInstr(env, X86Instr_Call(hregX86_EAX()));
- if (nargs > 0)
- addInstr(env, X86Instr_Alu32R(Xalu_ADD,
- X86RMI_Imm(4*nargs),
- hregX86_ESP()));
-
- return hregX86_EAX();
+ nargs = 0;
+ while (e->Iex.CCall.args[nargs]) nargs++;
+ for (i = nargs-1; i >= 0; i--) {
+ arg = e->Iex.CCall.args[i];
+ if (typeOfIRExpr(env->type_env,arg) != Ity_I32)
+ goto irreducible;
+ addInstr(env, X86Instr_Push(iselIntExpr_RMI(env, arg)));
+ }
+ target = 0x12345678; //FIND_HELPER(e->Iex.CCall.name);
+ addInstr(env, X86Instr_Alu32R(
+ Xalu_MOV,
+ X86RMI_Imm(target),
+ hregX86_EAX()));
+ addInstr(env, X86Instr_Call(hregX86_EAX()));
+ if (nargs > 0)
+ addInstr(env, X86Instr_Alu32R(Xalu_ADD,
+ X86RMI_Imm(4*nargs),
+ hregX86_ESP()));
+ return hregX86_EAX();
}
/* 32/16/8-bit literals */
case Iex_Const: {
- UInt u;
- vassert(ty == Ity_I32 || ty == Ity_I8);
- switch (e->Iex.Const.con->tag) {
- case Ico_U32: u = e->Iex.Const.con->Ico.U32; break;
- case Ico_U16: u = 0xFFFF & (e->Iex.Const.con->Ico.U16); break;
- case Ico_U8: u = 0xFF & (e->Iex.Const.con->Ico.U8); break;
- default: vpanic("iselIntExpr_R.Iex_Const(x86h)");
- }
- HReg r = newVRegI(env);
- addInstr(env, X86Instr_Alu32R(Xalu_MOV, X86RMI_Imm(u), r));
+ X86RMI* rmi = iselIntExpr_RMI ( env, e );
+ HReg r = newVRegI(env);
+ addInstr(env, X86Instr_Alu32R(Xalu_MOV, rmi, r));
return r;
}
+ case Iex_Mux0X: {
+ if (ty == Ity_I32
+ && typeOfIRExpr(env->type_env,e->Iex.Mux0X.cond) == Ity_I8) {
+ HReg rX = iselIntExpr_R(env, e->Iex.Mux0X.exprX);
+ X86RM* r0 = iselIntExpr_RM(env, e->Iex.Mux0X.expr0);
+ HReg dst = newVRegI(env);
+ addInstr(env, mk_MOV_RR(rX,dst));
+ HReg r8 = iselIntExpr_R(env, e->Iex.Mux0X.cond);
+ addInstr(env, X86Instr_Alu32R(Xalu_TEST,
+ X86RMI_Imm(0xFF), r8));
+ addInstr(env, X86Instr_CMovZ(r0,dst));
+ return dst;
+ }
+ break;
+ }
+
default:
break;
} /* switch (e->tag) */
/* Return an AMode which computes the value of the specified
expression, possibly also adding insns to the code list as a
- result.
+ result. The expression may only be a 32-bit one.
*/
static X86AMode* iselIntExpr_AMode ( ISelEnv* env, IRExpr* e )
{
vassert(e);
- vassert(typeOfIRExpr(env->type_env,e) == Ity_I32);
+ IRType ty = typeOfIRExpr(env->type_env,e);
+ vassert(ty == Ity_I32);
/* Add32(expr1, Shl32(expr2, imm)) */
if (e->tag == Iex_Binop
}
-/* Similarly, calculate an expression into an X86RMI operand. */
+/* Similarly, calculate an expression into an X86RMI operand. As with
+ iselIntExpr_R, the expression can have type 32, 16 or 8 bits. */
static X86RMI* iselIntExpr_RMI ( ISelEnv* env, IRExpr* e )
{
vassert(e);
- vassert(typeOfIRExpr(env->type_env,e) == Ity_I32);
+ IRType ty = typeOfIRExpr(env->type_env,e);
+ vassert(ty == Ity_I32 || ty == Ity_I16 || ty == Ity_I8);
/* special case: immediate */
- if (e->tag == Iex_Const
- && e->Iex.Const.con->tag == Ico_U32) {
- return X86RMI_Imm(e->Iex.Const.con->Ico.U32);
+ if (e->tag == Iex_Const) {
+ UInt u;
+ switch (e->Iex.Const.con->tag) {
+ case Ico_U32: u = e->Iex.Const.con->Ico.U32; break;
+ case Ico_U16: u = 0xFFFF & (e->Iex.Const.con->Ico.U16); break;
+ case Ico_U8: u = 0xFF & (e->Iex.Const.con->Ico.U8); break;
+ default: vpanic("iselIntExpr_RMI.Iex_Const(x86h)");
+ }
+ return X86RMI_Imm(u);
}
/* special case: 32-bit GET */
- if (e->tag == Iex_Get && e->Iex.Get.ty ==Ity_I32) {
+ if (e->tag == Iex_Get && ty == Ity_I32) {
return X86RMI_Mem(X86AMode_IR(e->Iex.Get.offset,
hregX86_EBP()));
}
}
-/* Calculate an expression into an X86RI operand. */
+/* Calculate an expression into an X86RI operand. As with
+ iselIntExpr_R, the expression can have type 32, 16 or 8 bits. */
static X86RI* iselIntExpr_RI ( ISelEnv* env, IRExpr* e )
{
vassert(e);
- vassert(typeOfIRExpr(env->type_env,e) == Ity_I32);
+ IRType ty = typeOfIRExpr(env->type_env,e);
+ vassert(ty == Ity_I32 || ty == Ity_I16 || ty == Ity_I8);
/* special case: immediate */
- if (e->tag == Iex_Const
- && e->Iex.Const.con->tag == Ico_U32) {
- return X86RI_Imm(e->Iex.Const.con->Ico.U32);
+ if (e->tag == Iex_Const) {
+ UInt u;
+ switch (e->Iex.Const.con->tag) {
+ case Ico_U32: u = e->Iex.Const.con->Ico.U32; break;
+ case Ico_U16: u = 0xFFFF & (e->Iex.Const.con->Ico.U16); break;
+ case Ico_U8: u = 0xFF & (e->Iex.Const.con->Ico.U8); break;
+ default: vpanic("iselIntExpr_RMI.Iex_Const(x86h)");
+ }
+ return X86RI_Imm(u);
}
/* default case: calculate into a register and return that */
}
+/* Similarly, calculate an expression into an X86RM operand. As with
+ iselIntExpr_R, the expression can have type 32, 16 or 8 bits. */
+
+static X86RM* iselIntExpr_RM ( ISelEnv* env, IRExpr* e )
+{
+ vassert(e);
+ IRType ty = typeOfIRExpr(env->type_env,e);
+ vassert(ty == Ity_I32 || ty == Ity_I16 || ty == Ity_I8);
+
+ /* special case: 32-bit GET */
+ if (e->tag == Iex_Get && ty == Ity_I32) {
+ return X86RM_Mem(X86AMode_IR(e->Iex.Get.offset,
+ hregX86_EBP()));
+ }
+
+ /* special case: load from memory */
+
+ /* default case: calculate into a register and return that */
+ {
+ HReg r = iselIntExpr_R ( env, e );
+ return X86RM_Reg(r);
+ }
+}
+
+
+
/*---------------------------------------------------------*/
/*--- ISEL: Statements ---*/
/*---------------------------------------------------------*/
case Ist_Tmp: {
IRTemp tmp = stmt->Ist.Tmp.tmp;
IRType ty = lookupIRTypeEnv(env->type_env, tmp);
- if (ty == Ity_I32) {
+ if (ty == Ity_I32 || ty == Ity_I16 || ty == Ity_I8) {
X86RMI* rmi = iselIntExpr_RMI(env, stmt->Ist.Tmp.expr);
HReg dst = lookupIRTemp(env, tmp);
addInstr(env, X86Instr_Alu32R(Xalu_MOV,rmi,dst));
switch (bb->tyenv->types[i]) {
case Ity_Bit:
case Ity_I8:
+ case Ity_I16:
case Ity_I32: hreg = mkHReg(i, HRcInt, True); break;
case Ity_I64: hreg = mkHReg(i, HRcInt, True);
hregHI = mkHReg(i, HRcInt, True); break;
void ppX86AluOp ( X86AluOp op ) {
Char* name;
switch (op) {
- case Xalu_MOV: name = "mov"; break;
- case Xalu_ADD: name = "add"; break;
- case Xalu_SUB: name = "sub"; break;
- case Xalu_ADC: name = "adc"; break;
- case Xalu_SBB: name = "sbb"; break;
- case Xalu_AND: name = "and"; break;
- case Xalu_OR: name = "or"; break;
- case Xalu_XOR: name = "xor"; break;
+ case Xalu_MOV: name = "mov"; break;
+ case Xalu_CMP: name = "cmp"; break;
+ case Xalu_TEST: name = "test"; break;
+ case Xalu_ADD: name = "add"; break;
+ case Xalu_SUB: name = "sub"; break;
+ case Xalu_ADC: name = "adc"; break;
+ case Xalu_SBB: name = "sbb"; break;
+ case Xalu_AND: name = "and"; break;
+ case Xalu_OR: name = "or"; break;
+ case Xalu_XOR: name = "xor"; break;
default: vpanic("ppX86AluOp");
}
vex_printf("%s", name);
return i;
}
+X86Instr* X86Instr_CMovZ ( X86RM* src, HReg dst ) {
+ X86Instr* i = LibVEX_Alloc(sizeof(X86Instr));
+ i->tag = Xin_CMovZ;
+ i->Xin.CMovZ.src = src;
+ i->Xin.CMovZ.dst = dst;
+ return i;
+}
+
+X86Instr* X86Instr_LoadEX ( UChar szSmall, Bool syned,
+ X86AMode* src, HReg dst ) {
+ X86Instr* i = LibVEX_Alloc(sizeof(X86Instr));
+ i->tag = Xin_LoadEX;
+ i->Xin.LoadEX.szSmall = szSmall;
+ i->Xin.LoadEX.syned = syned;
+ i->Xin.LoadEX.src = src;
+ i->Xin.LoadEX.dst = dst;
+ vassert(szSmall == 1 || szSmall == 2);
+ return i;
+}
+
+
void ppX86Instr ( X86Instr* i ) {
switch (i->tag) {
case Xin_Alu32R:
vex_printf(",%%eax ; ret");
}
return;
+ case Xin_CMovZ:
+ vex_printf("cmovz ");
+ ppX86RM(i->Xin.CMovZ.src);
+ vex_printf(",");
+ ppHRegX86(i->Xin.CMovZ.dst);
+ return;
+ case Xin_LoadEX:
+ vex_printf("mov%c%cl ",
+ i->Xin.LoadEX.syned ? 's' : 'z',
+ i->Xin.LoadEX.szSmall==1 ? 'b' : 'w');
+ ppX86AMode(i->Xin.LoadEX.src);
+ vex_printf(",");
+ ppHRegX86(i->Xin.LoadEX.dst);
+ return;
default:
vpanic("ppX86Instr");
}
switch (i->tag) {
case Xin_Alu32R:
addRegUsage_X86RMI(u, i->Xin.Alu32R.src);
- if (i->Xin.Alu32R.op == Xalu_MOV)
+ if (i->Xin.Alu32R.op == Xalu_MOV) {
addHRegUse(u, HRmWrite, i->Xin.Alu32R.dst);
- else
- addHRegUse(u, HRmModify, i->Xin.Alu32R.dst);
+ return;
+ }
+ if (i->Xin.Alu32R.op == Xalu_CMP
+ || i->Xin.Alu32R.op == Xalu_TEST) {
+ addHRegUse(u, HRmRead, i->Xin.Alu32R.dst);
+ return;
+ }
+ addHRegUse(u, HRmModify, i->Xin.Alu32R.dst);
return;
case Xin_Alu32M:
addRegUsage_X86RI(u, i->Xin.Alu32M.src);
enum {
Xalu_INVALID,
Xalu_MOV,
+ Xalu_CMP,
+ Xalu_TEST,
Xalu_ADD, Xalu_SUB, Xalu_ADC, Xalu_SBB,
Xalu_AND, Xalu_OR, Xalu_XOR
}
Xin_Sh32, /* 32-bit shift/rotate, dst=REG or MEM */
Xin_Push, /* push (32-bit?) value on stack */
Xin_Call, /* call to address in register */
- Xin_GotoNZ /* conditional/unconditional jmp to dst */
+ Xin_GotoNZ, /* conditional/unconditional jmp to dst */
+ Xin_CMovZ, /* conditional move when Z flag set */
+ Xin_LoadEX /* mov{s,z}{b,w}l from mem to reg */
}
X86InstrTag;
Bool onlyWhenNZ;
X86RI* dst;
} GotoNZ;
+ /* Mov src to dst (both 32-bit regs?) when the Z flag is
+ set. */
+ struct {
+ X86RM* src;
+ HReg dst;
+ } CMovZ;
+ /* Sign/Zero extending loads. Dst size is always 32 bits. */
+ struct {
+ UChar szSmall;
+ Bool syned;
+ X86AMode* src;
+ HReg dst;
+ } LoadEX;
} Xin;
}
X86Instr;
extern X86Instr* X86Instr_Push ( X86RMI* );
extern X86Instr* X86Instr_Call ( HReg );
extern X86Instr* X86Instr_GotoNZ ( Bool onlyWhenNZ, X86RI* dst );
+extern X86Instr* X86Instr_CMovZ ( X86RM* src, HReg dst );
+extern X86Instr* X86Instr_LoadEX ( UChar szSmall, Bool syned,
+ X86AMode* src, HReg dst );
+
extern void ppX86Instr ( X86Instr* );
vex_printf("):");
ppIRType(e->Iex.CCall.retty);
break;
- case Iex_Mux10:
- vex_printf("Mux10(");
- ppIRExpr(e->Iex.Mux10.cond);
+ case Iex_Mux0X:
+ vex_printf("Mux0X(");
+ ppIRExpr(e->Iex.Mux0X.cond);
vex_printf(",");
- ppIRExpr(e->Iex.Mux10.expr1);
+ ppIRExpr(e->Iex.Mux0X.expr0);
vex_printf(",");
- ppIRExpr(e->Iex.Mux10.expr0);
+ ppIRExpr(e->Iex.Mux0X.exprX);
vex_printf(")");
break;
default:
e->Iex.CCall.args = args;
return e;
}
-IRExpr* IRExpr_Mux10 ( IRExpr* cond, IRExpr* expr1, IRExpr* expr0 ) {
+IRExpr* IRExpr_Mux0X ( IRExpr* cond, IRExpr* expr0, IRExpr* exprX ) {
IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
- e->tag = Iex_Mux10;
- e->Iex.Mux10.cond = cond;
- e->Iex.Mux10.expr1 = expr1;
- e->Iex.Mux10.expr0 = expr0;
+ e->tag = Iex_Mux0X;
+ e->Iex.Mux0X.cond = cond;
+ e->Iex.Mux0X.expr0 = expr0;
+ e->Iex.Mux0X.exprX = exprX;
return e;
}
return t_dst;
case Iex_CCall:
return e->Iex.CCall.retty;
- case Iex_Mux10:
- return typeOfIRExpr(tyenv, e->Iex.Mux10.expr1);
+ case Iex_Mux0X:
+ return typeOfIRExpr(tyenv, e->Iex.Mux0X.expr0);
default:
ppIRExpr(e);
vpanic("typeOfIRExpr");
for (i = 0; expr->Iex.CCall.args[i]; i++)
useBeforeDef_Expr(bb,stmt,expr->Iex.CCall.args[i],def_counts);
break;
- case Iex_Mux10:
- useBeforeDef_Expr(bb,stmt,expr->Iex.Mux10.cond,def_counts);
- useBeforeDef_Expr(bb,stmt,expr->Iex.Mux10.expr1,def_counts);
- useBeforeDef_Expr(bb,stmt,expr->Iex.Mux10.expr0,def_counts);
+ case Iex_Mux0X:
+ useBeforeDef_Expr(bb,stmt,expr->Iex.Mux0X.cond,def_counts);
+ useBeforeDef_Expr(bb,stmt,expr->Iex.Mux0X.expr0,def_counts);
+ useBeforeDef_Expr(bb,stmt,expr->Iex.Mux0X.exprX,def_counts);
break;
default:
vpanic("useBeforeDef_Expr");
break;
case Iex_Const:
break;
- case Iex_Mux10:
- tcExpr(bb,stmt, expr->Iex.Mux10.cond, gWordTy);
- tcExpr(bb,stmt, expr->Iex.Mux10.expr1, gWordTy);
- tcExpr(bb,stmt, expr->Iex.Mux10.expr0, gWordTy);
- if (typeOfIRExpr(tyenv, expr->Iex.Mux10.cond) != Ity_Bit)
- sanityCheckFail(bb,stmt,"Iex.Mux10.cond: cond :: Ity_Bit");
- if (typeOfIRExpr(tyenv, expr->Iex.Mux10.expr1)
- != typeOfIRExpr(tyenv, expr->Iex.Mux10.expr0))
- sanityCheckFail(bb,stmt,"Iex.Mux10: expr1/expr0 mismatch");
+ case Iex_Mux0X:
+ tcExpr(bb,stmt, expr->Iex.Mux0X.cond, gWordTy);
+ tcExpr(bb,stmt, expr->Iex.Mux0X.expr0, gWordTy);
+ tcExpr(bb,stmt, expr->Iex.Mux0X.exprX, gWordTy);
+ if (typeOfIRExpr(tyenv, expr->Iex.Mux0X.cond) != Ity_I8)
+ sanityCheckFail(bb,stmt,"Iex.Mux0X.cond: cond :: Ity_I8");
+ if (typeOfIRExpr(tyenv, expr->Iex.Mux0X.expr0)
+ != typeOfIRExpr(tyenv, expr->Iex.Mux0X.exprX))
+ sanityCheckFail(bb,stmt,"Iex.Mux0X: expr0/exprX mismatch");
break;
default:
vpanic("tcExpr");
Iop_INVALID=0x13000,
Iop_Add8, Iop_Add16, Iop_Add32, Iop_Add64,
Iop_Sub8, Iop_Sub16, Iop_Sub32, Iop_Sub64,
-//Iop_Adc8, Iop_Adc16, Iop_Adc32, Iop_Adc64,
-//Iop_Sbb8, Iop_Sbb16, Iop_Sbb32, Iop_Sbb64,
/* Signless mul. MullS/MullU is elsewhere. */
Iop_Mul8, Iop_Mul16, Iop_Mul32, Iop_Mul64,
Iop_Or8, Iop_Or16, Iop_Or32, Iop_Or64,
*/
typedef
enum { Iex_Get, Iex_Tmp, Iex_Binop, Iex_Unop, Iex_LDle,
- Iex_Const, Iex_CCall, Iex_Mux10 }
+ Iex_Const, Iex_CCall, Iex_Mux0X }
IRExprTag;
typedef
} CCall;
struct {
struct _IRExpr* cond;
- struct _IRExpr* expr1;
struct _IRExpr* expr0;
- } Mux10;
+ struct _IRExpr* exprX;
+ } Mux0X;
} Iex;
}
IRExpr;
extern IRExpr* IRExpr_LDle ( IRType ty, IRExpr* addr );
extern IRExpr* IRExpr_Const ( IRConst* con );
extern IRExpr* IRExpr_CCall ( Char* name, IRType retty, IRExpr** args );
-extern IRExpr* IRExpr_Mux10 ( IRExpr* cond, IRExpr* expr1, IRExpr* expr0 );
+extern IRExpr* IRExpr_Mux0X ( IRExpr* cond, IRExpr* expr0, IRExpr* exprX );
extern void ppIRExpr ( IRExpr* );