]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Use "load on condition" insns, if availably, to implement
authorFlorian Krohm <florian@eich-krohm.de>
Mon, 3 Dec 2012 13:32:05 +0000 (13:32 +0000)
committerFlorian Krohm <florian@eich-krohm.de>
Mon, 3 Dec 2012 13:32:05 +0000 (13:32 +0000)
S390_INSN_COND_MOVE.

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

VEX/priv/host_s390_defs.c
VEX/priv/host_s390_defs.h
VEX/priv/main_main.c
VEX/pub/libvex.h

index 95a1167d5cfd5dbeaa33ef4e60a1dd8eb7ef8a46..28b9cf8c044dd738da9b6dd0e60d5feb3ed3bc33 100644 (file)
@@ -3935,6 +3935,43 @@ s390_emit_SDTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2)
    return emit_RRF4(p, 0xb3d30000, r3, m4, r1, r2);
 }
 
+
+static UChar *
+s390_emit_LOCGR(UChar *p, UChar m3, UChar r1, UChar r2)
+{
+   vassert(s390_host_has_lscond);
+   if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
+      s390_disasm(ENC4(MNM, GPR, GPR, UINT), "locgr", r1, r2, m3);
+   }
+
+   return emit_RRF3(p, 0xb9e20000, m3, r1, r2);
+}
+
+
+static UChar *
+s390_emit_LOC(UChar *p, UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2)
+{
+   vassert(s390_host_has_ldisp || dh2 == 0);
+
+   if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
+      s390_disasm(ENC4(MNM, GPR, UINT, SDXB), "loc", r1, m3, dh2, dl2, 0, b2);
+
+   return emit_RSY(p, 0xeb00000000f2ULL, r1, m3, b2, dl2, dh2);
+}
+
+
+static UChar *
+s390_emit_LOCG(UChar *p, UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2)
+{
+   vassert(s390_host_has_ldisp || dh2 == 0);
+
+   if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
+      s390_disasm(ENC4(MNM, GPR, UINT, SDXB), "locg", r1, m3, dh2, dl2, 0, b2);
+
+   return emit_RSY(p, 0xeb00000000e2ULL, r1, m3, b2, dl2, dh2);
+}
+
+
 /* Provide a symbolic name for register "R0" */
 #define R0 0
 
@@ -7394,8 +7431,61 @@ s390_insn_cond_move_emit(UChar *buf, const s390_insn *insn)
    dst  = insn->variant.cond_move.dst;
    src  = insn->variant.cond_move.src;
 
+   if (cond == S390_CC_NEVER) return buf;
+
    p = buf;
 
+   if (s390_host_has_lscond) {
+      /* LOCx is not the preferred way to implement an unconditional load. */
+      if (cond != S390_CC_ALWAYS) goto use_branch_insn;
+
+      switch (src.tag) {
+      case S390_OPND_REG:
+         return s390_emit_LOCGR(p, cond, hregNumber(dst),
+                                hregNumber(src.variant.reg));
+
+      case S390_OPND_AMODE: {
+         const s390_amode *am = src.variant.am;
+
+         /* We cannot use LOCx for loads less than 4 bytes. In that case
+            load into R0 and then use LOCGR. Do the same if the amode uses
+            an index register. */
+         if (insn->size < 4 ||
+             am->tag == S390_AMODE_BX12 || am->tag == S390_AMODE_BX20) {
+            p = s390_emit_load_mem(p, insn->size, R0, am);
+            p = s390_emit_LOCGR(p, cond, hregNumber(dst), R0);
+            return p;
+         }
+
+         vassert(am->tag == S390_AMODE_B12 || am->tag == S390_AMODE_B20);
+         vassert(insn->size == 4 || insn->size == 8);
+
+         UInt b = hregNumber(am->b);
+         UInt d = am->d;
+
+         if (insn->size == 4) {
+            return s390_emit_LOC(p, hregNumber(dst), cond, b, DISP20(d));
+         }
+         return s390_emit_LOCG(p, hregNumber(dst), cond, b, DISP20(d));
+      }
+
+      case S390_OPND_IMMEDIATE: {
+         ULong value = src.variant.imm;
+
+         /* Load value into R0, then use LOCGR */
+         if (insn->size <= 4) {
+            p = s390_emit_load_32imm(p, R0, value);
+            return s390_emit_LOCGR(p, cond, hregNumber(dst), R0);
+         }
+
+         vassert(insn->size == 8);
+         p = s390_emit_load_64imm(p, R0, value);
+         return s390_emit_LOCGR(p, cond, hregNumber(dst), R0);
+      }
+      }
+   }
+
+use_branch_insn:
    /* Branch (if cond fails) over move instrs */
    if (cond != S390_CC_ALWAYS) {
       /* Don't know how many bytes to jump over yet.
index d123f706dc03903ea5245a5f5cd576ffb43639c1..6d21d08688a1cbbe5b13766abc41a4b35f0981fe 100644 (file)
@@ -694,6 +694,8 @@ extern UInt s390_host_hwcaps;
                       (s390_host_hwcaps & (VEX_HWCAPS_S390X_STCKF))
 #define s390_host_has_fpext \
                       (s390_host_hwcaps & (VEX_HWCAPS_S390X_FPEXT))
+#define s390_host_has_lscond \
+                      (s390_host_hwcaps & (VEX_HWCAPS_S390X_LSCOND))
 
 #endif /* ndef __VEX_HOST_S390_DEFS_H */
 
index 55e99c6cd293d1b31f1cd33370e4715720bac91c..4d98f510701a19ee7c0cacca3b0d776c6d276d31 100644 (file)
@@ -1260,7 +1260,7 @@ static const HChar* show_hwcaps_arm ( UInt hwcaps )
 static const HChar* show_hwcaps_s390x ( UInt hwcaps )
 {
    static const HChar prefix[] = "s390x";
-   static const HChar facilities[][6] = {
+   static const HChar facilities[][7] = {
      { "ldisp" },
      { "eimm" },
      { "gie" },
@@ -1271,6 +1271,7 @@ static const HChar* show_hwcaps_s390x ( UInt hwcaps )
      { "etf3" },
      { "stckf" },
      { "fpext" },
+     { "lscond" },
    };
    static HChar buf[sizeof facilities + sizeof prefix + 1];
    static HChar *p;
@@ -1300,6 +1301,8 @@ static const HChar* show_hwcaps_s390x ( UInt hwcaps )
      p = p + vex_sprintf(p, "-%s", facilities[8]);
    if (hwcaps & VEX_HWCAPS_S390X_FPEXT)
      p = p + vex_sprintf(p, "-%s", facilities[9]);
+   if (hwcaps & VEX_HWCAPS_S390X_LSCOND)
+     p = p + vex_sprintf(p, "-%s", facilities[10]);
 
    /* If there are no facilities, add "zarch" */
    if (hwcaps == 0)
index 0167a4ff5f6e229813d0f85d8592ef470215038c..d5c3483cae4c493b92e3ff507666f1119ea400e5 100644 (file)
@@ -133,6 +133,7 @@ typedef
 #define VEX_HWCAPS_S390X_ETF3  (1<<13)  /* ETF3-enhancement facility */
 #define VEX_HWCAPS_S390X_STCKF (1<<14)  /* STCKF facility */
 #define VEX_HWCAPS_S390X_FPEXT (1<<15)  /* Floating point extension facility */
+#define VEX_HWCAPS_S390X_LSCOND (1<<16) /* Conditional load/store facility */
 
 /* Special value representing all available s390x hwcaps */
 #define VEX_HWCAPS_S390X_ALL   (VEX_HWCAPS_S390X_LDISP | \
@@ -143,6 +144,7 @@ typedef
                                 VEX_HWCAPS_S390X_STFLE | \
                                 VEX_HWCAPS_S390X_STCKF | \
                                 VEX_HWCAPS_S390X_FPEXT | \
+                                VEX_HWCAPS_S390X_LSCOND| \
                                 VEX_HWCAPS_S390X_ETF3  | \
                                 VEX_HWCAPS_S390X_ETF2)