From: Florian Krohm Date: Sat, 2 Jun 2012 20:29:22 +0000 (+0000) Subject: Put the Triop member into a separate struct (IRTriop) and link to that X-Git-Tag: svn/VALGRIND_3_8_1^2~112 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=458df5a005b8d43ffec3637b6e5cb07492a84bd9;p=thirdparty%2Fvalgrind.git Put the Triop member into a separate struct (IRTriop) and link to that from IRExpr. Reduces size of IRExpr from 40 bytes to 32 bytes on LP64 and from 20 bytes to 16 bytes on ILP32. git-svn-id: svn://svn.valgrind.org/vex/trunk@2366 --- diff --git a/VEX/priv/host_amd64_isel.c b/VEX/priv/host_amd64_isel.c index 6062c17e06..c24678e9e8 100644 --- a/VEX/priv/host_amd64_isel.c +++ b/VEX/priv/host_amd64_isel.c @@ -1715,13 +1715,14 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) /* --------- 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 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) 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 @@ static HReg iselDblExpr_wrk ( ISelEnv* env, IRExpr* e ) } 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 @@ static HReg iselDblExpr_wrk ( ISelEnv* env, IRExpr* e ) } 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 @@ static HReg iselDblExpr_wrk ( ISelEnv* env, IRExpr* e ) 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 @@ static HReg iselDblExpr_wrk ( ISelEnv* env, IRExpr* e ) /* 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 --git a/VEX/priv/host_arm_isel.c b/VEX/priv/host_arm_isel.c index b9e5cecedc..f40aa6ef84 100644 --- a/VEX/priv/host_arm_isel.c +++ b/VEX/priv/host_arm_isel.c @@ -1133,14 +1133,15 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) //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 @@ static HReg iselNeon64Expr_wrk ( ISelEnv* env, IRExpr* e ) } /* 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 @@ static HReg iselNeon64Expr_wrk ( ISelEnv* env, IRExpr* e ) 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 @@ static HReg iselNeonExpr_wrk ( ISelEnv* env, IRExpr* e ) } 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 @@ static HReg iselDblExpr_wrk ( ISelEnv* env, IRExpr* e ) } 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 @@ static HReg iselFltExpr_wrk ( ISelEnv* env, IRExpr* e ) } 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 --git a/VEX/priv/host_ppc_isel.c b/VEX/priv/host_ppc_isel.c index 07c280df78..9cd0e52c10 100644 --- a/VEX/priv/host_ppc_isel.c +++ b/VEX/priv/host_ppc_isel.c @@ -3465,8 +3465,9 @@ static HReg iselDblExpr_wrk ( ISelEnv* env, IRExpr* e ) } 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 @@ static HReg iselDblExpr_wrk ( ISelEnv* env, IRExpr* e ) } 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 @@ static HReg iselDfp64Expr_wrk(ISelEnv* env, IRExpr* e) } 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 @@ static HReg iselDfp64Expr_wrk(ISelEnv* env, IRExpr* e) } 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 @@ static void iselDfp128Expr_wrk(HReg* rHi, HReg *rLo, ISelEnv* env, IRExpr* e) } 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 @@ static void iselDfp128Expr_wrk(HReg* rHi, HReg *rLo, ISelEnv* env, IRExpr* e) 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 @@ static void iselDfp128Expr_wrk(HReg* rHi, HReg *rLo, ISelEnv* env, IRExpr* e) *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 @@ static void iselDfp128Expr_wrk(HReg* rHi, HReg *rLo, ISelEnv* env, IRExpr* e) 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 --git a/VEX/priv/host_s390_isel.c b/VEX/priv/host_s390_isel.c index e21f700197..e0ec92b2f6 100644 --- a/VEX/priv/host_s390_isel.c +++ b/VEX/priv/host_s390_isel.c @@ -1517,9 +1517,10 @@ s390_isel_float128_expr_wrk(HReg *dst_hi, HReg *dst_lo, ISelEnv *env, /* --------- 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 @@ s390_isel_float128_expr_wrk(HReg *dst_hi, HReg *dst_lo, ISelEnv *env, 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 @@ s390_isel_float_expr_wrk(ISelEnv *env, IRExpr *expr) /* --------- 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 @@ s390_isel_float_expr_wrk(ISelEnv *env, IRExpr *expr) 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 --git a/VEX/priv/host_x86_isel.c b/VEX/priv/host_x86_isel.c index 1b83b6f8ad..62c26285cb 100644 --- a/VEX/priv/host_x86_isel.c +++ b/VEX/priv/host_x86_isel.c @@ -789,14 +789,15 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) /* --------- 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 @@ static HReg iselDblExpr_wrk ( ISelEnv* env, IRExpr* e ) 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 @@ static HReg iselDblExpr_wrk ( ISelEnv* env, IRExpr* e ) } 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 --git a/VEX/priv/ir_defs.c b/VEX/priv/ir_defs.c index 70c87c78be..ea7fe5d4e1 100644 --- a/VEX/priv/ir_defs.c +++ b/VEX/priv/ir_defs.c @@ -1031,16 +1031,18 @@ void ppIRExpr ( IRExpr* e ) 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_Qop ( IROp op, IRExpr* arg1, IRExpr* arg2, } 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 @@ IRExpr* deepCopyIRExpr ( IRExpr* e ) 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 @@ IRType typeOfIRExpr ( IRTypeEnv* tyenv, IRExpr* e ) &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 @@ Bool isFlatIRStmt ( IRStmt* st ) IRCAS* cas; IRPutI* puti; IRQop* qop; + IRTriop* triop; switch (st->tag) { case Ist_AbiHint: @@ -2972,10 +2980,11 @@ Bool isFlatIRStmt ( IRStmt* st ) && 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 @@ void useBeforeDef_Expr ( IRSB* bb, IRStmt* stmt, IRExpr* expr, Int* def_counts ) 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 @@ void tcExpr ( IRSB* bb, IRStmt* stmt, IRExpr* expr, IRType gWordTy ) } 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 --git a/VEX/priv/ir_opt.c b/VEX/priv/ir_opt.c index 78c094514e..c79cb58255 100644 --- a/VEX/priv/ir_opt.c +++ b/VEX/priv/ir_opt.c @@ -302,14 +302,16 @@ static IRExpr* flatten_Expr ( IRSB* bb, IRExpr* ex ) 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 @@ static Bool sameIRExprs_aux2 ( IRExpr** env, IRExpr* e1, IRExpr* e2 ) 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 @@ static IRExpr* subst_Expr ( IRExpr** env, IRExpr* ex ) ); } - 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 @@ static void addUses_Expr ( Bool* set, IRExpr* e ) 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 @@ static void deltaIRExpr ( IRExpr* e, Int delta ) 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 @@ static void setHints_Expr (Bool* doesLoad, Bool* doesGet, IRExpr* e ) 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 @@ static void aoccCount_Expr ( UShort* uses, IRExpr* e ) 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 @@ static IRExpr* atbSubst_Expr ( ATmpInfo* env, IRExpr* e ) ); 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 --git a/VEX/priv/main_main.c b/VEX/priv/main_main.c index 48a12b92c9..ccfb9d3f6c 100644 --- a/VEX/priv/main_main.c +++ b/VEX/priv/main_main.c @@ -159,11 +159,11 @@ void LibVEX_Init ( /* 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 --git a/VEX/pub/libvex_ir.h b/VEX/pub/libvex_ir.h index 05035eae73..74a21ec0fc 100644 --- a/VEX/pub/libvex_ir.h +++ b/VEX/pub/libvex_ir.h @@ -1478,6 +1478,7 @@ typedef IRCmpF64Result IRCmpF128Result; /* ------------------ 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 @@ struct _IRExpr { 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 @@ struct _IRExpr { } 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 */