]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Change S390_INSN_HELPER_CALL such that returning a value is part
authorFlorian Krohm <florian@eich-krohm.de>
Sun, 27 May 2012 16:52:43 +0000 (16:52 +0000)
committerFlorian Krohm <florian@eich-krohm.de>
Sun, 27 May 2012 16:52:43 +0000 (16:52 +0000)
of the call. Previously, this was a separate insn.

git-svn-id: svn://svn.valgrind.org/vex/trunk@2356

VEX/priv/host_s390_defs.c
VEX/priv/host_s390_defs.h
VEX/priv/host_s390_isel.c

index f60beea74e605379b7b270f4032e126ac040e302..2d6722605c2051a08064403159d09aebfd7cc27b 100644 (file)
@@ -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
index a953b4356ba91a9e157513da0c597122198047a4..daa90ce589a88ffe438fb58c70fdab8bf139cbf4 100644 (file)
@@ -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,
index a84413e4b70866385cd4ccbcecf662a28bad241a..76173d24055f08384a09c367de8ff733a543c0d0 100644 (file)
@@ -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;