]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
s390: Generalise S390_INSN_GADD which only worked on the guest
authorFlorian Krohm <florian@eich-krohm.de>
Sat, 22 Dec 2012 02:28:25 +0000 (02:28 +0000)
committerFlorian Krohm <florian@eich-krohm.de>
Sat, 22 Dec 2012 02:28:25 +0000 (02:28 +0000)
state to S390_INSN_MADD which works for any memory location
addressable with base reg + 20-bit displacement.

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

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

index dcfef615e2616dee47a09d43ef0f967967487a69..c3efa44cca76db019b7fc64ed26dc0e7f38c0c06 100644 (file)
@@ -737,8 +737,11 @@ s390_insn_get_reg_usage(HRegUsage *u, const s390_insn *insn)
       s390_amode_get_reg_usage(u, insn->variant.mzero.dst);
       break;
 
+   case S390_INSN_MADD:
+      s390_amode_get_reg_usage(u, insn->variant.madd.dst);
+      break;
+
    case S390_INSN_MFENCE:
-   case S390_INSN_GADD:
       break;
 
    case S390_INSN_SET_FPC_BFPRM:
@@ -1017,8 +1020,11 @@ s390_insn_map_regs(HRegRemap *m, s390_insn *insn)
       s390_amode_map_regs(m, insn->variant.mzero.dst);
       break;
 
+   case S390_INSN_MADD:
+      s390_amode_map_regs(m, insn->variant.madd.dst);
+      break;
+
    case S390_INSN_MFENCE:
-   case S390_INSN_GADD:
       break;
 
    case S390_INSN_SET_FPC_BFPRM:
@@ -5444,15 +5450,21 @@ s390_insn_mzero(UChar size, s390_amode *dst)
 
 
 s390_insn *
-s390_insn_gadd(UChar size, UInt offset, UChar delta, ULong value)
+s390_insn_madd(UChar size, s390_amode *dst, UChar delta, ULong value)
 {
    s390_insn *insn = LibVEX_Alloc(sizeof(s390_insn));
 
-   insn->tag  = S390_INSN_GADD;
+   vassert(size == 4 || size == 8);
+
+   /* This insn will be mapped to an ASI or AGSI so we can only allow base
+      register plus 12-bit / 20-bit displacement. */
+   vassert(dst->tag == S390_AMODE_B12 || dst->tag == S390_AMODE_B20);
+
+   insn->tag  = S390_INSN_MADD;
    insn->size = size;
-   insn->variant.gadd.offset = offset;
-   insn->variant.gadd.delta = delta;
-   insn->variant.gadd.value = value;
+   insn->variant.madd.dst   = dst;
+   insn->variant.madd.delta = delta;
+   insn->variant.madd.value = value;
 
    return insn;
 }
@@ -6018,11 +6030,11 @@ s390_insn_as_string(const s390_insn *insn)
       s390_sprintf(buf, "%M %A", "v-mzero", insn->variant.mzero.dst);
       break;
 
-   case S390_INSN_GADD:
-      s390_sprintf(buf, "%M %G += %I  (= %I)", "v-gadd",
-                   insn->variant.gadd.offset,
-                   (Long)(Char)insn->variant.gadd.delta,
-                   insn->variant.gadd.value);
+   case S390_INSN_MADD:
+      s390_sprintf(buf, "%M %A += %I  (= %I)", "v-madd",
+                   insn->variant.madd.dst,
+                   (Long)(Char)insn->variant.madd.delta,
+                   insn->variant.madd.value);
       break;
 
    case S390_INSN_SET_FPC_BFPRM:
@@ -8237,11 +8249,16 @@ s390_insn_mzero_emit(UChar *buf, const s390_insn *insn)
 
 
 static UChar *
-s390_insn_gadd_emit(UChar *buf, const s390_insn *insn)
+s390_insn_madd_emit(UChar *buf, const s390_insn *insn)
 {
-   return s390_emit_AGSI(buf, insn->variant.gadd.delta,
-                         S390_REGNO_GUEST_STATE_POINTER,
-                         DISP20(insn->variant.gadd.offset));
+   s390_amode *am = insn->variant.madd.dst;
+
+   if (insn->size == 4) {
+      return s390_emit_ASI(buf, insn->variant.madd.delta, am->b,
+                           DISP20(am->d));
+   }
+
+   return s390_emit_AGSI(buf, insn->variant.madd.delta, am->b, DISP20(am->d));
 }
 
 
@@ -8829,8 +8846,8 @@ emit_S390Instr(Bool *is_profinc, UChar *buf, Int nbuf, s390_insn *insn,
       end = s390_insn_mzero_emit(buf, insn);
       break;
 
-   case S390_INSN_GADD:
-      end = s390_insn_gadd_emit(buf, insn);
+   case S390_INSN_MADD:
+      end = s390_insn_madd_emit(buf, insn);
       break;
 
    case S390_INSN_SET_FPC_BFPRM:
index 5789baa23e1937b9c173e683cf92e3481dfadaf5..304e557536ff11ab8cc97fb5d71576c3dfe66c9f 100644 (file)
@@ -142,7 +142,7 @@ typedef enum {
    S390_INSN_DFP_CONVERT,
    S390_INSN_MFENCE,
    S390_INSN_MZERO,   /* Assign zero to a memory location */
-   S390_INSN_GADD,    /* Add a value to a guest register */
+   S390_INSN_MADD,    /* Add a value to a memory location */
    S390_INSN_SET_FPC_BFPRM, /* Set the bfp rounding mode in the FPC */
    S390_INSN_SET_FPC_DFPRM, /* Set the dfp rounding mode in the FPC */
    /* The following 5 insns are mandated by translation chaining */
@@ -537,10 +537,10 @@ typedef struct {
          s390_amode      *dst;
       } mzero;
       struct {
-         UInt             offset;
+         s390_amode      *dst;
          UChar            delta;
          ULong            value;  /* for debugging only */
-      } gadd;
+      } madd;
       struct {
          HReg             mode;
       } set_fpc_bfprm;
@@ -655,7 +655,8 @@ s390_insn *s390_insn_dfp128_convert_from(UChar size, s390_dfp_conv_t,
                                          s390_dfp_round_t);
 s390_insn *s390_insn_mfence(void);
 s390_insn *s390_insn_mzero(UChar size, s390_amode *dst);
-s390_insn *s390_insn_gadd(UChar size, UInt offset, UChar delta, ULong value);
+s390_insn *s390_insn_madd(UChar size, s390_amode *dst, UChar delta,
+                          ULong value);
 s390_insn *s390_insn_set_fpc_bfprm(UChar size, HReg mode);
 s390_insn *s390_insn_set_fpc_dfprm(UChar size, HReg mode);
 
index 9aca09f6c4f52f743e6bd4f13ff6aae06c2d860d..209bfb8dacf95ec43b248d5f6b11b768db2e8954 100644 (file)
@@ -2912,6 +2912,7 @@ s390_isel_stmt(ISelEnv *env, IRStmt *stmt)
       case Ity_I16:
       case Ity_I32:
       case Ity_I64:
+         /* fixs390: We could check for INSN_MADD here. */
          if (am->tag == S390_AMODE_B12 &&
              s390_expr_is_const_zero(stmt->Ist.Store.data)) {
             addInstr(env, s390_insn_mzero(sizeofIRType(tyd), am));
@@ -3020,7 +3021,8 @@ s390_isel_stmt(ISelEnv *env, IRStmt *stmt)
       difference = new_value - old_value;
 
       if (s390_host_has_gie && ulong_fits_signed_8bit(difference)) {
-         addInstr(env, s390_insn_gadd(sizeofIRType(tyd), offset,
+         am = s390_amode_for_guest_state(offset);
+         addInstr(env, s390_insn_madd(sizeofIRType(tyd), am,
                                       (difference & 0xFF), new_value));
          return;
       }
@@ -3029,13 +3031,11 @@ s390_isel_stmt(ISelEnv *env, IRStmt *stmt)
          Use R0 as a scratch reg. */
       if ((old_value >> 32) == (new_value >> 32)) {
          HReg r0  = make_gpr(0);
-         HReg gsp = make_gpr(S390_REGNO_GUEST_STATE_POINTER);
-         s390_amode *gam;
 
-         gam = s390_amode_b12(offset + 4, gsp);
+         am = s390_amode_for_guest_state(offset + 4);
          addInstr(env, s390_insn_load_immediate(4, r0,
                                                 new_value & 0xFFFFFFFF));
-         addInstr(env, s390_insn_store(4, gam, r0));
+         addInstr(env, s390_insn_store(4, am, r0));
          return;
       }