From: Florian Krohm Date: Sun, 27 May 2012 16:52:43 +0000 (+0000) Subject: Change S390_INSN_HELPER_CALL such that returning a value is part X-Git-Tag: svn/VALGRIND_3_8_1^2~122 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=43b7734da7dfcdfacaa6286308f9c2221ef60f9c;p=thirdparty%2Fvalgrind.git Change S390_INSN_HELPER_CALL such that returning a value is part of the call. Previously, this was a separate insn. git-svn-id: svn://svn.valgrind.org/vex/trunk@2356 --- diff --git a/VEX/priv/host_s390_defs.c b/VEX/priv/host_s390_defs.c index f60beea74e..2d6722605c 100644 --- a/VEX/priv/host_s390_defs.c +++ b/VEX/priv/host_s390_defs.c @@ -624,6 +624,8 @@ s390_insn_get_reg_usage(HRegUsage *u, const s390_insn *insn) for (i = 1; i <= 5; ++i) { addHRegUse(u, HRmWrite, mkHReg(i, HRcInt64, False)); } + if (insn->variant.helper_call.dst != INVALID_HREG) + addHRegUse(u, HRmWrite, insn->variant.helper_call.dst); /* Ditto for floating point registers. f0 - f7 are volatile */ for (i = 0; i <= 7; ++i) { @@ -849,6 +851,8 @@ s390_insn_map_regs(HRegRemap *m, s390_insn *insn) As for the arguments of the helper call -- they will be loaded into non-virtual registers. Again, we don't need to do anything for those here. */ + if (insn->variant.helper_call.dst != INVALID_HREG) + insn->variant.helper_call.dst = lookupHRegRemap(m, insn->variant.helper_call.dst); break; case S390_INSN_BFP_TRIOP: @@ -4332,7 +4336,7 @@ s390_insn_compare(UChar size, HReg src1, s390_opnd_RMI src2, s390_insn * s390_insn_helper_call(s390_cc_t cond, Addr64 target, UInt num_args, - HChar *name) + HChar *name, HReg dst) { s390_insn *insn = LibVEX_Alloc(sizeof(s390_insn)); @@ -4342,6 +4346,7 @@ s390_insn_helper_call(s390_cc_t cond, Addr64 target, UInt num_args, insn->variant.helper_call.target = target; insn->variant.helper_call.num_args = num_args; insn->variant.helper_call.name = name; + insn->variant.helper_call.dst = dst; return insn; } @@ -4939,11 +4944,20 @@ s390_insn_as_string(const s390_insn *insn) break; case S390_INSN_HELPER_CALL: { - s390_sprintf(buf, "%M if (%C) %s{%I}(%L)", "v-call", - insn->variant.helper_call.cond, - insn->variant.helper_call.name, - insn->variant.helper_call.target, - insn->variant.helper_call.num_args); + if (insn->variant.helper_call.dst != INVALID_HREG) { + s390_sprintf(buf, "%M if (%C) %R = %s{%I}(%L)", "v-call", + insn->variant.helper_call.cond, + insn->variant.helper_call.dst, + insn->variant.helper_call.name, + insn->variant.helper_call.target, + insn->variant.helper_call.num_args); + } else { + s390_sprintf(buf, "%M if (%C) %s{%I}(%L)", "v-call", + insn->variant.helper_call.cond, + insn->variant.helper_call.name, + insn->variant.helper_call.target, + insn->variant.helper_call.num_args); + } return buf; /* avoid printing "size = ..." which is meaningless */ } @@ -6739,6 +6753,13 @@ s390_insn_helper_call_emit(UChar *buf, const s390_insn *insn) buf = s390_emit_STG(buf, S390_REGNO_LINK_REGISTER, 0, // save LR S390_REGNO_STACK_POINTER, S390_OFFSET_SAVED_LR, 0); buf = s390_emit_BASR(buf, S390_REGNO_LINK_REGISTER, 1); // call helper + + /* Move the return value to the destination register */ + if (insn->variant.helper_call.dst != INVALID_HREG) { + buf = s390_emit_LGR(buf, hregNumber(insn->variant.helper_call.dst), + S390_REGNO_RETURN_VALUE); + } + buf = s390_emit_LG(buf, S390_REGNO_LINK_REGISTER, 0, // restore LR S390_REGNO_STACK_POINTER, S390_OFFSET_SAVED_LR, 0); buf = s390_emit_LFPC(buf, S390_REGNO_STACK_POINTER, // restore FPC diff --git a/VEX/priv/host_s390_defs.h b/VEX/priv/host_s390_defs.h index a953b4356b..daa90ce589 100644 --- a/VEX/priv/host_s390_defs.h +++ b/VEX/priv/host_s390_defs.h @@ -353,6 +353,7 @@ typedef struct { s390_cc_t cond; Addr64 target; UInt num_args; + HReg dst; /* if not INVALID_HREG, put return value here */ HChar *name; /* callee's name (for debugging) */ } helper_call; struct { @@ -472,7 +473,7 @@ s390_insn *s390_insn_test(UChar size, s390_opnd_RMI src); s390_insn *s390_insn_compare(UChar size, HReg dst, s390_opnd_RMI opnd, Bool signed_comparison); s390_insn *s390_insn_helper_call(s390_cc_t cond, Addr64 target, UInt num_args, - HChar *name); + HChar *name, HReg dst); s390_insn *s390_insn_bfp_triop(UChar size, s390_bfp_triop_t, HReg dst, HReg op2, HReg op3, s390_round_t); s390_insn *s390_insn_bfp_binop(UChar size, s390_bfp_binop_t, HReg dst, HReg op2, diff --git a/VEX/priv/host_s390_isel.c b/VEX/priv/host_s390_isel.c index a84413e4b7..76173d2405 100644 --- a/VEX/priv/host_s390_isel.c +++ b/VEX/priv/host_s390_isel.c @@ -450,7 +450,7 @@ s390_expr_is_const_zero(IRExpr *expr) */ static void doHelperCall(ISelEnv *env, Bool passBBP, IRExpr *guard, - IRCallee *callee, IRExpr **args) + IRCallee *callee, IRExpr **args, HReg dst) { UInt n_args, i, argreg, size; ULong target; @@ -507,7 +507,7 @@ doHelperCall(ISelEnv *env, Bool passBBP, IRExpr *guard, /* Finally, the call itself. */ addInstr(env, s390_insn_helper_call(cc, (Addr64)target, n_args, - callee->name)); + callee->name, dst)); } @@ -1325,11 +1325,7 @@ s390_isel_int_expr_wrk(ISelEnv *env, IRExpr *expr) HReg dst = newVRegI(env); doHelperCall(env, False, NULL, expr->Iex.CCall.cee, - expr->Iex.CCall.args); - - /* Move the returned value into the return register */ - addInstr(env, s390_insn_move(sizeofIRType(expr->Iex.CCall.retty), dst, - make_gpr(S390_REGNO_RETURN_VALUE))); + expr->Iex.CCall.args, dst); return dst; } @@ -2417,6 +2413,7 @@ s390_isel_stmt(ISelEnv *env, IRStmt *stmt) IRType retty; IRDirty* d = stmt->Ist.Dirty.details; Bool passBBP; + HReg dst; Int i; /* Invalidate tracked values of those guest state registers that are @@ -2434,20 +2431,19 @@ s390_isel_stmt(ISelEnv *env, IRStmt *stmt) passBBP = toBool(d->nFxState > 0 && d->needsBBP); - doHelperCall(env, passBBP, d->guard, d->cee, d->args); - - /* Now figure out what to do with the returned value, if any. */ - if (d->tmp == IRTemp_INVALID) - /* No return value. Nothing to do. */ + if (d->tmp == IRTemp_INVALID) { + /* No return value. */ + dst = INVALID_HREG; + doHelperCall(env, passBBP, d->guard, d->cee, d->args, dst); return; + } retty = typeOfIRTemp(env->type_env, d->tmp); if (retty == Ity_I64 || retty == Ity_I32 || retty == Ity_I16 || retty == Ity_I8) { /* Move the returned value to the destination register */ - HReg dst = lookupIRTemp(env, d->tmp); - addInstr(env, s390_insn_move(sizeofIRType(retty), dst, - make_gpr(S390_REGNO_RETURN_VALUE))); + dst = lookupIRTemp(env, d->tmp); + doHelperCall(env, passBBP, d->guard, d->cee, d->args, dst); return; } break;