diff -r -u -x .svn brand-new/VEX/priv/host_amd64_isel.c trunk/VEX/priv/host_amd64_isel.c --- brand-new/VEX/priv/host_amd64_isel.c 2012-06-01 18:03:34.437691308 -0400 +++ trunk/VEX/priv/host_amd64_isel.c 2012-06-01 17:11:31.933821890 -0400 @@ -1715,13 +1715,14 @@ /* --------- 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)); @@ -1733,7 +1734,7 @@ 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; @@ -2557,8 +2558,9 @@ } 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; @@ -2567,8 +2569,8 @@ } 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 */ @@ -2601,21 +2603,22 @@ 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 */ @@ -2631,7 +2634,7 @@ /* do it */ /* XXXROUNDINGFIXME */ /* set roundingmode here */ - switch (e->Iex.Triop.op) { + switch (triop->op) { case Iop_ScaleF64: addInstr(env, AMD64Instr_A87FpOp(Afp_SCALE)); break; diff -r -u -x .svn brand-new/VEX/priv/host_arm_isel.c trunk/VEX/priv/host_arm_isel.c --- brand-new/VEX/priv/host_arm_isel.c 2012-06-01 18:02:17.805694515 -0400 +++ trunk/VEX/priv/host_arm_isel.c 2012-06-01 17:57:25.985706720 -0400 @@ -1133,14 +1133,15 @@ //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( @@ -3597,18 +3598,20 @@ } /* 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"); @@ -3621,16 +3624,16 @@ 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; @@ -5244,18 +5247,20 @@ } 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"); @@ -5412,16 +5417,18 @@ } 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; @@ -5555,16 +5562,18 @@ } 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; diff -r -u -x .svn brand-new/VEX/priv/host_ppc_isel.c trunk/VEX/priv/host_ppc_isel.c --- brand-new/VEX/priv/host_ppc_isel.c 2012-06-01 18:03:34.441691308 -0400 +++ trunk/VEX/priv/host_ppc_isel.c 2012-06-01 17:15:30.041811940 -0400 @@ -3465,8 +3465,9 @@ } 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; @@ -3479,22 +3480,22 @@ } 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)); @@ -3862,9 +3863,10 @@ } 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; @@ -3882,24 +3884,24 @@ } 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)); @@ -4041,8 +4043,9 @@ } 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; @@ -4066,9 +4069,9 @@ 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 ) ); @@ -4076,7 +4079,7 @@ *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; @@ -4089,8 +4092,8 @@ 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, diff -r -u -x .svn brand-new/VEX/priv/host_s390_isel.c trunk/VEX/priv/host_s390_isel.c --- brand-new/VEX/priv/host_s390_isel.c 2012-06-01 18:03:34.437691308 -0400 +++ trunk/VEX/priv/host_s390_isel.c 2012-06-01 18:08:19.433679379 -0400 @@ -1517,9 +1517,10 @@ /* --------- 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; @@ -1550,7 +1551,7 @@ 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)); @@ -1784,9 +1785,10 @@ /* --------- 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; @@ -1809,7 +1811,7 @@ 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; } diff -r -u -x .svn brand-new/VEX/priv/host_x86_isel.c trunk/VEX/priv/host_x86_isel.c --- brand-new/VEX/priv/host_x86_isel.c 2012-05-31 16:46:35.996781303 -0400 +++ trunk/VEX/priv/host_x86_isel.c 2012-06-01 17:05:59.793835808 -0400 @@ -789,14 +789,15 @@ /* --------- 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( @@ -2958,7 +2959,8 @@ 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; @@ -2973,8 +2975,8 @@ } 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)); diff -r -u -x .svn brand-new/VEX/priv/ir_defs.c trunk/VEX/priv/ir_defs.c --- brand-new/VEX/priv/ir_defs.c 2012-06-01 18:03:34.437691308 -0400 +++ trunk/VEX/priv/ir_defs.c 2012-06-01 16:55:45.513861483 -0400 @@ -1031,16 +1031,18 @@ 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( "(" ); @@ -1489,12 +1491,14 @@ } 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 ) { @@ -1897,11 +1901,14 @@ 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), @@ -2881,7 +2888,7 @@ &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: @@ -2945,6 +2952,7 @@ IRCAS* cas; IRPutI* puti; IRQop* qop; + IRTriop* triop; switch (st->tag) { case Ist_AbiHint: @@ -2972,10 +2980,11 @@ && 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)); @@ -3133,11 +3142,13 @@ 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); @@ -3297,26 +3308,27 @@ } 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); diff -r -u -x .svn brand-new/VEX/priv/ir_opt.c trunk/VEX/priv/ir_opt.c --- brand-new/VEX/priv/ir_opt.c 2012-06-01 18:03:34.437691308 -0400 +++ trunk/VEX/priv/ir_opt.c 2012-06-01 17:02:53.165843598 -0400 @@ -302,14 +302,16 @@ 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); @@ -1022,11 +1024,14 @@ 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 ) @@ -2055,16 +2060,18 @@ ); } - 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)); @@ -2393,9 +2400,9 @@ 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); @@ -3823,9 +3830,9 @@ 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); @@ -4218,9 +4225,9 @@ 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); @@ -4292,9 +4299,9 @@ 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: @@ -4615,10 +4622,10 @@ ); 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( diff -r -u -x .svn brand-new/VEX/priv/main_main.c trunk/VEX/priv/main_main.c --- brand-new/VEX/priv/main_main.c 2012-06-01 18:03:34.437691308 -0400 +++ trunk/VEX/priv/main_main.c 2012-06-01 22:32:14.985016866 -0400 @@ -159,11 +159,11 @@ /* 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); } diff -r -u -x .svn brand-new/VEX/pub/libvex_ir.h trunk/VEX/pub/libvex_ir.h --- brand-new/VEX/pub/libvex_ir.h 2012-06-01 18:03:34.537691305 -0400 +++ trunk/VEX/pub/libvex_ir.h 2012-06-01 16:48:30.893879682 -0400 @@ -1478,6 +1478,7 @@ /* ------------------ Expressions ------------------ */ typedef struct _IRQop IRQop; /* forward declaration */ +typedef struct _IRQop IRTriop; /* forward declaration */ /* The different kinds of expressions. Their meaning is explained below @@ -1591,10 +1592,7 @@ 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. @@ -1696,6 +1694,14 @@ } 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 */ diff -r -u -x .svn brand-new/memcheck/mc_translate.c trunk/memcheck/mc_translate.c --- brand-new/memcheck/mc_translate.c 2012-06-01 18:03:31.873691415 -0400 +++ trunk/memcheck/mc_translate.c 2012-06-01 22:25:11.513034808 -0400 @@ -3832,8 +3832,9 @@ case Iex_Triop: return expr2vbits_Triop( mce, - e->Iex.Triop.op, - e->Iex.Triop.arg1, e->Iex.Triop.arg2, e->Iex.Triop.arg3 + e->Iex.Triop.details->op, + e->Iex.Triop.details->arg1, e->Iex.Triop.details->arg2, + e->Iex.Triop.details->arg3 ); case Iex_Binop: @@ -4981,9 +4982,9 @@ return isBogusAtom(e->Iex.Binop.arg1) || isBogusAtom(e->Iex.Binop.arg2); case Iex_Triop: - return isBogusAtom(e->Iex.Triop.arg1) - || isBogusAtom(e->Iex.Triop.arg2) - || isBogusAtom(e->Iex.Triop.arg3); + return isBogusAtom(e->Iex.Triop.details->arg1) + || isBogusAtom(e->Iex.Triop.details->arg2) + || isBogusAtom(e->Iex.Triop.details->arg3); case Iex_Qop: return isBogusAtom(e->Iex.Qop.details->arg1) || isBogusAtom(e->Iex.Qop.details->arg2) @@ -5741,9 +5742,9 @@ gen_maxU32( mce, b3, b4 ) ); } case Iex_Triop: { - IRAtom* b1 = schemeE( mce, e->Iex.Triop.arg1 ); - IRAtom* b2 = schemeE( mce, e->Iex.Triop.arg2 ); - IRAtom* b3 = schemeE( mce, e->Iex.Triop.arg3 ); + IRAtom* b1 = schemeE( mce, e->Iex.Triop.details->arg1 ); + IRAtom* b2 = schemeE( mce, e->Iex.Triop.details->arg2 ); + IRAtom* b3 = schemeE( mce, e->Iex.Triop.details->arg3 ); return gen_maxU32( mce, b1, gen_maxU32( mce, b2, b3 ) ); } case Iex_Binop: {