/* --------- TERNARY OP --------- */
case Iex_Triop: {
+ IRTriop *triop = e->Iex.Triop.details;
/* C3210 flags following FPU partial remainder (fprem), both
IEEE compliant (PREM1) and non-IEEE compliant (PREM). */
- if (e->Iex.Triop.op == Iop_PRemC3210F64
- || e->Iex.Triop.op == Iop_PRem1C3210F64) {
+ if (triop->op == Iop_PRemC3210F64
+ || triop->op == Iop_PRem1C3210F64) {
AMD64AMode* m8_rsp = AMD64AMode_IR(-8, hregAMD64_RSP());
- HReg arg1 = iselDblExpr(env, e->Iex.Triop.arg2);
- HReg arg2 = iselDblExpr(env, e->Iex.Triop.arg3);
+ HReg arg1 = iselDblExpr(env, triop->arg2);
+ HReg arg2 = iselDblExpr(env, triop->arg3);
HReg dst = newVRegI(env);
addInstr(env, AMD64Instr_A87Free(2));
addInstr(env, AMD64Instr_SseLdSt(False/*store*/, 8, arg1, m8_rsp));
addInstr(env, AMD64Instr_A87PushPop(m8_rsp, True/*push*/, 8));
- switch (e->Iex.Triop.op) {
+ switch (triop->op) {
case Iop_PRemC3210F64:
addInstr(env, AMD64Instr_A87FpOp(Afp_PREM));
break;
}
if (e->tag == Iex_Triop) {
+ IRTriop *triop = e->Iex.Triop.details;
AMD64SseOp op = Asse_INVALID;
- switch (e->Iex.Triop.op) {
+ switch (triop->op) {
case Iop_AddF64: op = Asse_ADDF; break;
case Iop_SubF64: op = Asse_SUBF; break;
case Iop_MulF64: op = Asse_MULF; break;
}
if (op != Asse_INVALID) {
HReg dst = newVRegV(env);
- HReg argL = iselDblExpr(env, e->Iex.Triop.arg2);
- HReg argR = iselDblExpr(env, e->Iex.Triop.arg3);
+ HReg argL = iselDblExpr(env, triop->arg2);
+ HReg argR = iselDblExpr(env, triop->arg3);
addInstr(env, mk_vMOVsd_RR(argL, dst));
/* XXXROUNDINGFIXME */
/* set roundingmode here */
return dst;
}
+ IRTriop *triop = e->Iex.Triop.details;
if (e->tag == Iex_Triop
- && (e->Iex.Triop.op == Iop_ScaleF64
- || e->Iex.Triop.op == Iop_AtanF64
- || e->Iex.Triop.op == Iop_Yl2xF64
- || e->Iex.Triop.op == Iop_Yl2xp1F64
- || e->Iex.Triop.op == Iop_PRemF64
- || e->Iex.Triop.op == Iop_PRem1F64)
+ && (triop->op == Iop_ScaleF64
+ || triop->op == Iop_AtanF64
+ || triop->op == Iop_Yl2xF64
+ || triop->op == Iop_Yl2xp1F64
+ || triop->op == Iop_PRemF64
+ || triop->op == Iop_PRem1F64)
) {
AMD64AMode* m8_rsp = AMD64AMode_IR(-8, hregAMD64_RSP());
- HReg arg1 = iselDblExpr(env, e->Iex.Triop.arg2);
- HReg arg2 = iselDblExpr(env, e->Iex.Triop.arg3);
+ HReg arg1 = iselDblExpr(env, triop->arg2);
+ HReg arg2 = iselDblExpr(env, triop->arg3);
HReg dst = newVRegV(env);
- Bool arg2first = toBool(e->Iex.Triop.op == Iop_ScaleF64
- || e->Iex.Triop.op == Iop_PRemF64
- || e->Iex.Triop.op == Iop_PRem1F64);
+ Bool arg2first = toBool(triop->op == Iop_ScaleF64
+ || triop->op == Iop_PRemF64
+ || triop->op == Iop_PRem1F64);
addInstr(env, AMD64Instr_A87Free(2));
/* one arg -> top of x87 stack */
/* do it */
/* XXXROUNDINGFIXME */
/* set roundingmode here */
- switch (e->Iex.Triop.op) {
+ switch (triop->op) {
case Iop_ScaleF64:
addInstr(env, AMD64Instr_A87FpOp(Afp_SCALE));
break;
//zz /* --------- TERNARY OP --------- */
//zz case Iex_Triop: {
+//zz IRTriop *triop = e->Iex.Triop.details;
//zz /* C3210 flags following FPU partial remainder (fprem), both
//zz IEEE compliant (PREM1) and non-IEEE compliant (PREM). */
-//zz if (e->Iex.Triop.op == Iop_PRemC3210F64
-//zz || e->Iex.Triop.op == Iop_PRem1C3210F64) {
+//zz if (triop->op == Iop_PRemC3210F64
+//zz || triop->op == Iop_PRem1C3210F64) {
//zz HReg junk = newVRegF(env);
//zz HReg dst = newVRegI(env);
-//zz HReg srcL = iselDblExpr(env, e->Iex.Triop.arg2);
-//zz HReg srcR = iselDblExpr(env, e->Iex.Triop.arg3);
+//zz HReg srcL = iselDblExpr(env, triop->arg2);
+//zz HReg srcR = iselDblExpr(env, triop->arg3);
//zz /* XXXROUNDINGFIXME */
//zz /* set roundingmode here */
//zz addInstr(env, X86Instr_FpBinary(
} /* if (e->tag == Iex_Unop) */
if (e->tag == Iex_Triop) {
- switch (e->Iex.Triop.op) {
+ IRTriop *triop = e->Iex.Triop.details;
+
+ switch (triop->op) {
case Iop_Extract64: {
HReg res = newVRegD(env);
- HReg argL = iselNeon64Expr(env, e->Iex.Triop.arg1);
- HReg argR = iselNeon64Expr(env, e->Iex.Triop.arg2);
+ HReg argL = iselNeon64Expr(env, triop->arg1);
+ HReg argR = iselNeon64Expr(env, triop->arg2);
UInt imm4;
- if (e->Iex.Triop.arg3->tag != Iex_Const ||
- typeOfIRExpr(env->type_env, e->Iex.Triop.arg3) != Ity_I8) {
+ if (triop->arg3->tag != Iex_Const ||
+ typeOfIRExpr(env->type_env, triop->arg3) != Ity_I8) {
vpanic("ARM target supports Iop_Extract64 with constant "
"third argument less than 16 only\n");
}
- imm4 = e->Iex.Triop.arg3->Iex.Const.con->Ico.U8;
+ imm4 = triop->arg3->Iex.Const.con->Ico.U8;
if (imm4 >= 8) {
vpanic("ARM target supports Iop_Extract64 with constant "
"third argument less than 16 only\n");
case Iop_SetElem16x4:
case Iop_SetElem32x2: {
HReg res = newVRegD(env);
- HReg dreg = iselNeon64Expr(env, e->Iex.Triop.arg1);
- HReg arg = iselIntExpr_R(env, e->Iex.Triop.arg3);
+ HReg dreg = iselNeon64Expr(env, triop->arg1);
+ HReg arg = iselIntExpr_R(env, triop->arg3);
UInt index, size;
- if (e->Iex.Triop.arg2->tag != Iex_Const ||
- typeOfIRExpr(env->type_env, e->Iex.Triop.arg2) != Ity_I8) {
+ if (triop->arg2->tag != Iex_Const ||
+ typeOfIRExpr(env->type_env, triop->arg2) != Ity_I8) {
vpanic("ARM target supports SetElem with constant "
"second argument only\n");
}
- index = e->Iex.Triop.arg2->Iex.Const.con->Ico.U8;
- switch (e->Iex.Triop.op) {
+ index = triop->arg2->Iex.Const.con->Ico.U8;
+ switch (triop->op) {
case Iop_SetElem8x8: vassert(index < 8); size = 0; break;
case Iop_SetElem16x4: vassert(index < 4); size = 1; break;
case Iop_SetElem32x2: vassert(index < 2); size = 2; break;
}
if (e->tag == Iex_Triop) {
- switch (e->Iex.Triop.op) {
+ IRTriop *triop = e->Iex.Triop.details;
+
+ switch (triop->op) {
case Iop_ExtractV128: {
HReg res = newVRegV(env);
- HReg argL = iselNeonExpr(env, e->Iex.Triop.arg1);
- HReg argR = iselNeonExpr(env, e->Iex.Triop.arg2);
+ HReg argL = iselNeonExpr(env, triop->arg1);
+ HReg argR = iselNeonExpr(env, triop->arg2);
UInt imm4;
- if (e->Iex.Triop.arg3->tag != Iex_Const ||
- typeOfIRExpr(env->type_env, e->Iex.Triop.arg3) != Ity_I8) {
+ if (triop->arg3->tag != Iex_Const ||
+ typeOfIRExpr(env->type_env, triop->arg3) != Ity_I8) {
vpanic("ARM target supports Iop_ExtractV128 with constant "
"third argument less than 16 only\n");
}
- imm4 = e->Iex.Triop.arg3->Iex.Const.con->Ico.U8;
+ imm4 = triop->arg3->Iex.Const.con->Ico.U8;
if (imm4 >= 16) {
vpanic("ARM target supports Iop_ExtractV128 with constant "
"third argument less than 16 only\n");
}
if (e->tag == Iex_Triop) {
- switch (e->Iex.Triop.op) {
+ IRTriop *triop = e->Iex.Triop.details;
+
+ switch (triop->op) {
case Iop_DivF64:
case Iop_MulF64:
case Iop_AddF64:
case Iop_SubF64: {
ARMVfpOp op = 0; /*INVALID*/
- HReg argL = iselDblExpr(env, e->Iex.Triop.arg2);
- HReg argR = iselDblExpr(env, e->Iex.Triop.arg3);
+ HReg argL = iselDblExpr(env, triop->arg2);
+ HReg argR = iselDblExpr(env, triop->arg3);
HReg dst = newVRegD(env);
- switch (e->Iex.Triop.op) {
+ switch (triop->op) {
case Iop_DivF64: op = ARMvfp_DIV; break;
case Iop_MulF64: op = ARMvfp_MUL; break;
case Iop_AddF64: op = ARMvfp_ADD; break;
}
if (e->tag == Iex_Triop) {
- switch (e->Iex.Triop.op) {
+ IRTriop *triop = e->Iex.Triop.details;
+
+ switch (triop->op) {
case Iop_DivF32:
case Iop_MulF32:
case Iop_AddF32:
case Iop_SubF32: {
ARMVfpOp op = 0; /*INVALID*/
- HReg argL = iselFltExpr(env, e->Iex.Triop.arg2);
- HReg argR = iselFltExpr(env, e->Iex.Triop.arg3);
+ HReg argL = iselFltExpr(env, triop->arg2);
+ HReg argR = iselFltExpr(env, triop->arg3);
HReg dst = newVRegF(env);
- switch (e->Iex.Triop.op) {
+ switch (triop->op) {
case Iop_DivF32: op = ARMvfp_DIV; break;
case Iop_MulF32: op = ARMvfp_MUL; break;
case Iop_AddF32: op = ARMvfp_ADD; break;
}
if (e->tag == Iex_Triop) {
+ IRTriop *triop = e->Iex.Triop.details;
PPCFpOp fpop = Pfp_INVALID;
- switch (e->Iex.Triop.op) {
+ switch (triop->op) {
case Iop_AddF64: fpop = Pfp_ADDD; break;
case Iop_SubF64: fpop = Pfp_SUBD; break;
case Iop_MulF64: fpop = Pfp_MULD; break;
}
if (fpop != Pfp_INVALID) {
HReg r_dst = newVRegF(env);
- HReg r_srcL = iselDblExpr(env, e->Iex.Triop.arg2);
- HReg r_srcR = iselDblExpr(env, e->Iex.Triop.arg3);
- set_FPU_rounding_mode( env, e->Iex.Triop.arg1 );
+ HReg r_srcL = iselDblExpr(env, triop->arg2);
+ HReg r_srcR = iselDblExpr(env, triop->arg3);
+ set_FPU_rounding_mode( env, triop->arg1 );
addInstr(env, PPCInstr_FpBinary(fpop, r_dst, r_srcL, r_srcR));
return r_dst;
}
- switch (e->Iex.Triop.op) {
+ switch (triop->op) {
case Iop_QuantizeD64: fpop = Pfp_DQUA; break;
case Iop_SignificanceRoundD64: fpop = Pfp_RRDTR; break;
default: break;
}
if (fpop != Pfp_INVALID) {
HReg r_dst = newVRegF(env);
- HReg r_srcL = iselDblExpr(env, e->Iex.Triop.arg2);
- HReg r_srcR = iselDblExpr(env, e->Iex.Triop.arg3);
- PPCRI* rmc = iselWordExpr_RI(env, e->Iex.Triop.arg1);
+ HReg r_srcL = iselDblExpr(env, triop->arg2);
+ HReg r_srcR = iselDblExpr(env, triop->arg3);
+ PPCRI* rmc = iselWordExpr_RI(env, triop->arg1);
// will set TE and RMC when issuing instruction
addInstr(env, PPCInstr_DfpQuantize(fpop, r_dst, r_srcL, r_srcR, rmc));
}
if (e->tag == Iex_Triop) {
+ IRTriop *triop = e->Iex.Triop.details;
PPCFpOp fpop = Pfp_INVALID;
- switch (e->Iex.Triop.op) {
+ switch (triop->op) {
case Iop_AddD64:
fpop = Pfp_DFPADD;
break;
}
if (fpop != Pfp_INVALID) {
HReg r_dst = newVRegF( env );
- HReg r_srcL = iselDfp64Expr( env, e->Iex.Triop.arg2 );
- HReg r_srcR = iselDfp64Expr( env, e->Iex.Triop.arg3 );
+ HReg r_srcL = iselDfp64Expr( env, triop->arg2 );
+ HReg r_srcR = iselDfp64Expr( env, triop->arg3 );
- set_FPU_DFP_rounding_mode( env, e->Iex.Triop.arg1 );
+ set_FPU_DFP_rounding_mode( env, triop->arg1 );
addInstr( env, PPCInstr_Dfp64Binary( fpop, r_dst, r_srcL, r_srcR ) );
return r_dst;
}
- switch (e->Iex.Triop.op) {
+ switch (triop->op) {
case Iop_QuantizeD64: fpop = Pfp_DQUA; break;
case Iop_SignificanceRoundD64: fpop = Pfp_RRDTR; break;
default: break;
}
if (fpop != Pfp_INVALID) {
HReg r_dst = newVRegF(env);
- HReg r_srcL = iselDfp64Expr(env, e->Iex.Triop.arg2);
- HReg r_srcR = iselDfp64Expr(env, e->Iex.Triop.arg3);
- PPCRI* rmc = iselWordExpr_RI(env, e->Iex.Triop.arg1);
+ HReg r_srcL = iselDfp64Expr(env, triop->arg2);
+ HReg r_srcR = iselDfp64Expr(env, triop->arg3);
+ PPCRI* rmc = iselWordExpr_RI(env, triop->arg1);
addInstr(env, PPCInstr_DfpQuantize(fpop, r_dst, r_srcL, r_srcR,
rmc));
}
if (e->tag == Iex_Triop) {
+ IRTriop *triop = e->Iex.Triop.details;
PPCFpOp fpop = Pfp_INVALID;
- switch (e->Iex.Triop.op) {
+ switch (triop->op) {
case Iop_AddD128:
fpop = Pfp_DFPADDQ;
break;
HReg r_srcRLo = newVRegV( env );
/* dst will be used to pass in the left operand and get the result. */
- iselDfp128Expr( &r_dstHi, &r_dstLo, env, e->Iex.Triop.arg2 );
- iselDfp128Expr( &r_srcRHi, &r_srcRLo, env, e->Iex.Triop.arg3 );
- set_FPU_rounding_mode( env, e->Iex.Triop.arg1 );
+ iselDfp128Expr( &r_dstHi, &r_dstLo, env, triop->arg2 );
+ iselDfp128Expr( &r_srcRHi, &r_srcRLo, env, triop->arg3 );
+ set_FPU_rounding_mode( env, triop->arg1 );
addInstr( env,
PPCInstr_Dfp128Binary( fpop, r_dstHi, r_dstLo,
r_srcRHi, r_srcRLo ) );
*rLo = r_dstLo;
return;
}
- switch (e->Iex.Triop.op) {
+ switch (triop->op) {
case Iop_QuantizeD128: fpop = Pfp_DQUAQ; break;
case Iop_SignificanceRoundD128: fpop = Pfp_DRRNDQ; break;
default: break;
PPCRI* rmc = iselWordExpr_RI(env, e->Iex.Binop.arg1);
/* dst will be used to pass in the left operand and get the result */
- iselDfp128Expr(&r_dstHi, &r_dstLo, env, e->Iex.Triop.arg2);
- iselDfp128Expr(&r_srcHi, &r_srcLo, env, e->Iex.Triop.arg3);
+ iselDfp128Expr(&r_dstHi, &r_dstLo, env, triop->arg2);
+ iselDfp128Expr(&r_srcHi, &r_srcLo, env, triop->arg3);
// will set RMC when issuing instruction
addInstr(env, PPCInstr_DfpQuantize128(fpop, r_dstHi, r_dstLo,
/* --------- TERNARY OP --------- */
case Iex_Triop: {
- IROp op = expr->Iex.Triop.op;
- IRExpr *left = expr->Iex.Triop.arg2;
- IRExpr *right = expr->Iex.Triop.arg3;
+ IRTriop *triop = expr->Iex.Triop.details;
+ IROp op = triop->op;
+ IRExpr *left = triop->arg2;
+ IRExpr *right = triop->arg3;
s390_bfp_binop_t bfpop;
s390_round_t rounding_mode;
HReg op1_hi, op1_lo, op2_hi, op2_lo, f12, f13, f14, f15;
goto irreducible;
}
- rounding_mode = decode_rounding_mode(expr->Iex.Triop.arg1);
+ rounding_mode = decode_rounding_mode(triop->arg1);
addInstr(env, s390_insn_bfp128_binop(16, bfpop, f12, f14, f13,
f15, rounding_mode));
/* --------- TERNARY OP --------- */
case Iex_Triop: {
- IROp op = expr->Iex.Triop.op;
- IRExpr *left = expr->Iex.Triop.arg2;
- IRExpr *right = expr->Iex.Triop.arg3;
+ IRTriop *triop = expr->Iex.Triop.details;
+ IROp op = triop->op;
+ IRExpr *left = triop->arg2;
+ IRExpr *right = triop->arg3;
s390_bfp_binop_t bfpop;
s390_round_t rounding_mode;
HReg h1, op2, dst;
goto irreducible;
}
- rounding_mode = decode_rounding_mode(expr->Iex.Triop.arg1);
+ rounding_mode = decode_rounding_mode(triop->arg1);
addInstr(env, s390_insn_bfp_binop(size, bfpop, dst, op2, rounding_mode));
return dst;
}
/* --------- TERNARY OP --------- */
case Iex_Triop: {
+ IRTriop *triop = e->Iex.Triop.details;
/* C3210 flags following FPU partial remainder (fprem), both
IEEE compliant (PREM1) and non-IEEE compliant (PREM). */
- if (e->Iex.Triop.op == Iop_PRemC3210F64
- || e->Iex.Triop.op == Iop_PRem1C3210F64) {
+ if (triop->op == Iop_PRemC3210F64
+ || triop->op == Iop_PRem1C3210F64) {
HReg junk = newVRegF(env);
HReg dst = newVRegI(env);
- HReg srcL = iselDblExpr(env, e->Iex.Triop.arg2);
- HReg srcR = iselDblExpr(env, e->Iex.Triop.arg3);
+ HReg srcL = iselDblExpr(env, triop->arg2);
+ HReg srcR = iselDblExpr(env, triop->arg3);
/* XXXROUNDINGFIXME */
/* set roundingmode here */
addInstr(env, X86Instr_FpBinary(
if (e->tag == Iex_Triop) {
X86FpOp fpop = Xfp_INVALID;
- switch (e->Iex.Triop.op) {
+ IRTriop *triop = e->Iex.Triop.details;
+ switch (triop->op) {
case Iop_AddF64: fpop = Xfp_ADD; break;
case Iop_SubF64: fpop = Xfp_SUB; break;
case Iop_MulF64: fpop = Xfp_MUL; break;
}
if (fpop != Xfp_INVALID) {
HReg res = newVRegF(env);
- HReg srcL = iselDblExpr(env, e->Iex.Triop.arg2);
- HReg srcR = iselDblExpr(env, e->Iex.Triop.arg3);
+ HReg srcL = iselDblExpr(env, triop->arg2);
+ HReg srcR = iselDblExpr(env, triop->arg3);
/* XXXROUNDINGFIXME */
/* set roundingmode here */
addInstr(env, X86Instr_FpBinary(fpop,srcL,srcR,res));
vex_printf( ")" );
break;
}
- case Iex_Triop:
- ppIROp(e->Iex.Triop.op);
+ case Iex_Triop: {
+ IRTriop *triop = e->Iex.Triop.details;
+ ppIROp(triop->op);
vex_printf( "(" );
- ppIRExpr(e->Iex.Triop.arg1);
+ ppIRExpr(triop->arg1);
vex_printf( "," );
- ppIRExpr(e->Iex.Triop.arg2);
+ ppIRExpr(triop->arg2);
vex_printf( "," );
- ppIRExpr(e->Iex.Triop.arg3);
+ ppIRExpr(triop->arg3);
vex_printf( ")" );
break;
+ }
case Iex_Binop:
ppIROp(e->Iex.Binop.op);
vex_printf( "(" );
}
IRExpr* IRExpr_Triop ( IROp op, IRExpr* arg1,
IRExpr* arg2, IRExpr* arg3 ) {
- IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
+ IRExpr* e = LibVEX_Alloc(sizeof(IRExpr));
+ IRTriop* triop = LibVEX_Alloc(sizeof(IRTriop));
+ triop->op = op;
+ triop->arg1 = arg1;
+ triop->arg2 = arg2;
+ triop->arg3 = arg3;
e->tag = Iex_Triop;
- e->Iex.Triop.op = op;
- e->Iex.Triop.arg1 = arg1;
- e->Iex.Triop.arg2 = arg2;
- e->Iex.Triop.arg3 = arg3;
+ e->Iex.Triop.details = triop;
return e;
}
IRExpr* IRExpr_Binop ( IROp op, IRExpr* arg1, IRExpr* arg2 ) {
deepCopyIRExpr(qop->arg3),
deepCopyIRExpr(qop->arg4));
}
- case Iex_Triop:
- return IRExpr_Triop(e->Iex.Triop.op,
- deepCopyIRExpr(e->Iex.Triop.arg1),
- deepCopyIRExpr(e->Iex.Triop.arg2),
- deepCopyIRExpr(e->Iex.Triop.arg3));
+ case Iex_Triop: {
+ IRTriop *triop = e->Iex.Triop.details;
+
+ return IRExpr_Triop(triop->op,
+ deepCopyIRExpr(triop->arg1),
+ deepCopyIRExpr(triop->arg2),
+ deepCopyIRExpr(triop->arg3));
+ }
case Iex_Binop:
return IRExpr_Binop(e->Iex.Binop.op,
deepCopyIRExpr(e->Iex.Binop.arg1),
&t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
return t_dst;
case Iex_Triop:
- typeOfPrimop(e->Iex.Triop.op,
+ typeOfPrimop(e->Iex.Triop.details->op,
&t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
return t_dst;
case Iex_Binop:
IRCAS* cas;
IRPutI* puti;
IRQop* qop;
+ IRTriop* triop;
switch (st->tag) {
case Ist_AbiHint:
&& isIRAtom(qop->arg2)
&& isIRAtom(qop->arg3)
&& isIRAtom(qop->arg4));
- case Iex_Triop: return toBool(
- isIRAtom(e->Iex.Triop.arg1)
- && isIRAtom(e->Iex.Triop.arg2)
- && isIRAtom(e->Iex.Triop.arg3));
+ case Iex_Triop: triop = e->Iex.Triop.details;
+ return toBool(
+ isIRAtom(triop->arg1)
+ && isIRAtom(triop->arg2)
+ && isIRAtom(triop->arg3));
case Iex_Binop: return toBool(
isIRAtom(e->Iex.Binop.arg1)
&& isIRAtom(e->Iex.Binop.arg2));
useBeforeDef_Expr(bb,stmt,qop->arg4,def_counts);
break;
}
- case Iex_Triop:
- useBeforeDef_Expr(bb,stmt,expr->Iex.Triop.arg1,def_counts);
- useBeforeDef_Expr(bb,stmt,expr->Iex.Triop.arg2,def_counts);
- useBeforeDef_Expr(bb,stmt,expr->Iex.Triop.arg3,def_counts);
+ case Iex_Triop: {
+ IRTriop* triop = expr->Iex.Triop.details;
+ useBeforeDef_Expr(bb,stmt,triop->arg1,def_counts);
+ useBeforeDef_Expr(bb,stmt,triop->arg2,def_counts);
+ useBeforeDef_Expr(bb,stmt,triop->arg3,def_counts);
break;
+ }
case Iex_Binop:
useBeforeDef_Expr(bb,stmt,expr->Iex.Binop.arg1,def_counts);
useBeforeDef_Expr(bb,stmt,expr->Iex.Binop.arg2,def_counts);
}
case Iex_Triop: {
IRType ttarg1, ttarg2, ttarg3;
- tcExpr(bb,stmt, expr->Iex.Triop.arg1, gWordTy );
- tcExpr(bb,stmt, expr->Iex.Triop.arg2, gWordTy );
- tcExpr(bb,stmt, expr->Iex.Triop.arg3, gWordTy );
- typeOfPrimop(expr->Iex.Triop.op,
+ IRTriop *triop = expr->Iex.Triop.details;
+ tcExpr(bb,stmt, triop->arg1, gWordTy );
+ tcExpr(bb,stmt, triop->arg2, gWordTy );
+ tcExpr(bb,stmt, triop->arg3, gWordTy );
+ typeOfPrimop(triop->op,
&t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4);
if (t_arg1 == Ity_INVALID || t_arg2 == Ity_INVALID
|| t_arg3 == Ity_INVALID || t_arg4 != Ity_INVALID) {
vex_printf(" op name: " );
- ppIROp(expr->Iex.Triop.op);
+ ppIROp(triop->op);
vex_printf("\n");
sanityCheckFail(bb,stmt,
"Iex.Triop: wrong arity op\n"
"... name of op precedes BB printout\n");
}
- ttarg1 = typeOfIRExpr(tyenv, expr->Iex.Triop.arg1);
- ttarg2 = typeOfIRExpr(tyenv, expr->Iex.Triop.arg2);
- ttarg3 = typeOfIRExpr(tyenv, expr->Iex.Triop.arg3);
+ ttarg1 = typeOfIRExpr(tyenv, triop->arg1);
+ ttarg2 = typeOfIRExpr(tyenv, triop->arg2);
+ ttarg3 = typeOfIRExpr(tyenv, triop->arg3);
if (t_arg1 != ttarg1 || t_arg2 != ttarg2 || t_arg3 != ttarg3) {
vex_printf(" op name: ");
- ppIROp(expr->Iex.Triop.op);
+ ppIROp(triop->op);
vex_printf("\n");
vex_printf(" op type is (");
ppIRType(t_arg1);
return IRExpr_RdTmp(t1);
}
- case Iex_Triop:
+ case Iex_Triop: {
+ IRTriop* triop = ex->Iex.Triop.details;
t1 = newIRTemp(bb->tyenv, ty);
addStmtToIRSB(bb, IRStmt_WrTmp(t1,
- IRExpr_Triop(ex->Iex.Triop.op,
- flatten_Expr(bb, ex->Iex.Triop.arg1),
- flatten_Expr(bb, ex->Iex.Triop.arg2),
- flatten_Expr(bb, ex->Iex.Triop.arg3))));
+ IRExpr_Triop(triop->op,
+ flatten_Expr(bb, triop->arg1),
+ flatten_Expr(bb, triop->arg2),
+ flatten_Expr(bb, triop->arg3))));
return IRExpr_RdTmp(t1);
+ }
case Iex_Binop:
t1 = newIRTemp(bb->tyenv, ty);
return False;
}
- case Iex_Triop:
- return toBool( e1->Iex.Triop.op == e2->Iex.Triop.op
- && sameIRExprs_aux( env, e1->Iex.Triop.arg1, e2->Iex.Triop.arg1 )
- && sameIRExprs_aux( env, e1->Iex.Triop.arg2, e2->Iex.Triop.arg2 )
- && sameIRExprs_aux( env, e1->Iex.Triop.arg3, e2->Iex.Triop.arg3 ));
+ case Iex_Triop: {
+ IRTriop *tri1 = e1->Iex.Triop.details;
+ IRTriop *tri2 = e2->Iex.Triop.details;
+ return toBool( tri1->op == tri2->op
+ && sameIRExprs_aux( env, tri1->arg1, tri2->arg1 )
+ && sameIRExprs_aux( env, tri1->arg2, tri2->arg2 )
+ && sameIRExprs_aux( env, tri1->arg3, tri2->arg3 ));
+ }
case Iex_Mux0X:
return toBool( sameIRExprs_aux( env, e1->Iex.Mux0X.cond, e2->Iex.Mux0X.cond )
);
}
- case Iex_Triop:
- vassert(isIRAtom(ex->Iex.Triop.arg1));
- vassert(isIRAtom(ex->Iex.Triop.arg2));
- vassert(isIRAtom(ex->Iex.Triop.arg3));
+ case Iex_Triop: {
+ IRTriop* triop = ex->Iex.Triop.details;
+ vassert(isIRAtom(triop->arg1));
+ vassert(isIRAtom(triop->arg2));
+ vassert(isIRAtom(triop->arg3));
return IRExpr_Triop(
- ex->Iex.Triop.op,
- subst_Expr(env, ex->Iex.Triop.arg1),
- subst_Expr(env, ex->Iex.Triop.arg2),
- subst_Expr(env, ex->Iex.Triop.arg3)
+ triop->op,
+ subst_Expr(env, triop->arg1),
+ subst_Expr(env, triop->arg2),
+ subst_Expr(env, triop->arg3)
);
+ }
case Iex_Binop:
vassert(isIRAtom(ex->Iex.Binop.arg1));
addUses_Expr(set, e->Iex.Qop.details->arg4);
return;
case Iex_Triop:
- addUses_Expr(set, e->Iex.Triop.arg1);
- addUses_Expr(set, e->Iex.Triop.arg2);
- addUses_Expr(set, e->Iex.Triop.arg3);
+ addUses_Expr(set, e->Iex.Triop.details->arg1);
+ addUses_Expr(set, e->Iex.Triop.details->arg2);
+ addUses_Expr(set, e->Iex.Triop.details->arg3);
return;
case Iex_Binop:
addUses_Expr(set, e->Iex.Binop.arg1);
deltaIRExpr(e->Iex.Qop.details->arg4, delta);
break;
case Iex_Triop:
- deltaIRExpr(e->Iex.Triop.arg1, delta);
- deltaIRExpr(e->Iex.Triop.arg2, delta);
- deltaIRExpr(e->Iex.Triop.arg3, delta);
+ deltaIRExpr(e->Iex.Triop.details->arg1, delta);
+ deltaIRExpr(e->Iex.Triop.details->arg2, delta);
+ deltaIRExpr(e->Iex.Triop.details->arg3, delta);
break;
case Iex_Binop:
deltaIRExpr(e->Iex.Binop.arg1, delta);
setHints_Expr(doesLoad, doesGet, e->Iex.Qop.details->arg4);
return;
case Iex_Triop:
- setHints_Expr(doesLoad, doesGet, e->Iex.Triop.arg1);
- setHints_Expr(doesLoad, doesGet, e->Iex.Triop.arg2);
- setHints_Expr(doesLoad, doesGet, e->Iex.Triop.arg3);
+ setHints_Expr(doesLoad, doesGet, e->Iex.Triop.details->arg1);
+ setHints_Expr(doesLoad, doesGet, e->Iex.Triop.details->arg2);
+ setHints_Expr(doesLoad, doesGet, e->Iex.Triop.details->arg3);
return;
case Iex_Binop:
setHints_Expr(doesLoad, doesGet, e->Iex.Binop.arg1);
return;
case Iex_Triop:
- aoccCount_Expr(uses, e->Iex.Triop.arg1);
- aoccCount_Expr(uses, e->Iex.Triop.arg2);
- aoccCount_Expr(uses, e->Iex.Triop.arg3);
+ aoccCount_Expr(uses, e->Iex.Triop.details->arg1);
+ aoccCount_Expr(uses, e->Iex.Triop.details->arg2);
+ aoccCount_Expr(uses, e->Iex.Triop.details->arg3);
return;
case Iex_Binop:
);
case Iex_Triop:
return IRExpr_Triop(
- e->Iex.Triop.op,
- atbSubst_Expr(env, e->Iex.Triop.arg1),
- atbSubst_Expr(env, e->Iex.Triop.arg2),
- atbSubst_Expr(env, e->Iex.Triop.arg3)
+ e->Iex.Triop.details->op,
+ atbSubst_Expr(env, e->Iex.Triop.details->arg1),
+ atbSubst_Expr(env, e->Iex.Triop.details->arg2),
+ atbSubst_Expr(env, e->Iex.Triop.details->arg3)
);
case Iex_Binop:
return fold_IRExpr_Binop(
/* These take a lot of space, so make sure we don't have
any unnoticed size regressions. */
if (VEX_HOST_WORDSIZE == 4) {
- vassert(sizeof(IRExpr) == 20);
+ vassert(sizeof(IRExpr) == 16);
vassert(sizeof(IRStmt) == 20 /* x86 */
|| sizeof(IRStmt) == 24 /* arm */);
} else {
- vassert(sizeof(IRExpr) == 40);
+ vassert(sizeof(IRExpr) == 32);
vassert(sizeof(IRStmt) == 32);
}
/* ------------------ Expressions ------------------ */
typedef struct _IRQop IRQop; /* forward declaration */
+typedef struct _IRQop IRTriop; /* forward declaration */
/* The different kinds of expressions. Their meaning is explained below
eg. MulF64(1, 2.0, 3.0)
*/
struct {
- IROp op; /* op-code */
- IRExpr* arg1; /* operand 1 */
- IRExpr* arg2; /* operand 2 */
- IRExpr* arg3; /* operand 3 */
+ IRTriop* details;
} Triop;
/* A binary operation.
} Iex;
};
+/* ------------------ A ternary expression ---------------------- */
+struct _IRTriop {
+ IROp op; /* op-code */
+ IRExpr* arg1; /* operand 1 */
+ IRExpr* arg2; /* operand 2 */
+ IRExpr* arg3; /* operand 3 */
+};
+
/* ------------------ A quarternary expression ------------------ */
struct _IRQop {
IROp op; /* op-code */