|
From: <sv...@va...> - 2012-01-15 21:05:53
|
Author: florian
Date: 2012-01-15 21:01:16 +0000 (Sun, 15 Jan 2012)
New Revision: 2237
Log:
Add support for the s390's TROO insn. These are the VEX bits.
New hardware capability: VEX_HWCAPS_S390X_ETF2.
Patch by Divya Vyas (div...@li...).
Partial fix of #273114
Modified:
trunk/priv/guest_s390_toIR.c
trunk/priv/host_s390_defs.h
trunk/pub/libvex.h
Modified: trunk/priv/guest_s390_toIR.c
===================================================================
--- trunk/priv/guest_s390_toIR.c 2012-01-04 01:34:53 UTC (rev 2236)
+++ trunk/priv/guest_s390_toIR.c 2012-01-15 21:01:16 UTC (rev 2237)
@@ -1585,6 +1585,16 @@
}
static void
+s390_format_RRF_M0RERE(HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
+ UChar m3, UChar r1, UChar r2)
+{
+ irgen(m3, r1, r2);
+
+ if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
+ s390_disasm(ENC3(MNM, GPR, GPR), m3, r1, r2);
+}
+
+static void
s390_format_RRF_F0FF(HChar *(*irgen)(UChar, UChar, UChar),
UChar r1, UChar r3, UChar r2)
{
@@ -10847,7 +10857,56 @@
return "cksm";
}
+static HChar *
+s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
+{
+ IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
+ src_addr = newTemp(Ity_I64);
+ des_addr = newTemp(Ity_I64);
+ tab_addr = newTemp(Ity_I64);
+ test_byte = newTemp(Ity_I8);
+ src_len = newTemp(Ity_I64);
+ assign(src_addr, get_gpr_dw0(r2));
+ assign(des_addr, get_gpr_dw0(r1));
+ assign(tab_addr, get_gpr_dw0(1));
+ assign(src_len, get_gpr_dw0(r1+1));
+ assign(test_byte, get_gpr_b7(0));
+
+ IRTemp op = newTemp(Ity_I8);
+ IRTemp op1 = newTemp(Ity_I8);
+ IRTemp result = newTemp(Ity_I64);
+
+ /* End of source string? We're done; proceed to next insn */
+ s390_cc_set(0);
+ if_condition_goto(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)),
+ guest_IA_next_instr);
+
+ /* Load character from source string, index translation table and
+ store translated character in op1. */
+ assign(op, load(Ity_I8, mkexpr(src_addr)));
+
+ assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
+ mkexpr(tab_addr)));
+ assign(op1, load(Ity_I8, mkexpr(result)));
+
+ if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
+ s390_cc_set(1);
+ if_condition_goto(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)),
+ guest_IA_next_instr);
+ }
+ store(get_gpr_dw0(r1), mkexpr(op1));
+
+ put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
+ put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
+ put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
+
+ always_goto_and_chase(guest_IA_curr_instr);
+
+ return "troo";
+}
+
+
/*------------------------------------------------------------*/
/*--- Build IR for special instructions ---*/
/*------------------------------------------------------------*/
@@ -11652,7 +11711,8 @@
case 0xb990: /* TRTT */ goto unimplemented;
case 0xb991: /* TRTO */ goto unimplemented;
case 0xb992: /* TROT */ goto unimplemented;
- case 0xb993: /* TROO */ goto unimplemented;
+ case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
+ ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
ovl.fmt.RRE.r2); goto ok;
case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
Modified: trunk/priv/host_s390_defs.h
===================================================================
--- trunk/priv/host_s390_defs.h 2012-01-04 01:34:53 UTC (rev 2236)
+++ trunk/priv/host_s390_defs.h 2012-01-15 21:01:16 UTC (rev 2237)
@@ -487,6 +487,8 @@
(s390_archinfo_host->hwcaps & (VEX_HWCAPS_S390X_DFP))
#define s390_host_has_fgx \
(s390_archinfo_host->hwcaps & (VEX_HWCAPS_S390X_FGX))
+#define s390_host_has_etf2 \
+ (s390_archinfo_host->hwcaps & (VEX_HWCAPS_S390X_ETF2))
#endif /* ndef __VEX_HOST_S390_DEFS_H */
Modified: trunk/pub/libvex.h
===================================================================
--- trunk/pub/libvex.h 2012-01-04 01:34:53 UTC (rev 2236)
+++ trunk/pub/libvex.h 2012-01-15 21:01:16 UTC (rev 2237)
@@ -128,13 +128,15 @@
#define VEX_HWCAPS_S390X_GIE (1<<8) /* General-instruction-extension facility */
#define VEX_HWCAPS_S390X_DFP (1<<9) /* Decimal floating point facility */
#define VEX_HWCAPS_S390X_FGX (1<<10) /* FPR-GR transfer facility */
+#define VEX_HWCAPS_S390X_ETF2 (1<<11) /* ETF2-enhancement facility */
/* Special value representing all available s390x hwcaps */
#define VEX_HWCAPS_S390X_ALL (VEX_HWCAPS_S390X_LDISP | \
VEX_HWCAPS_S390X_EIMM | \
VEX_HWCAPS_S390X_GIE | \
VEX_HWCAPS_S390X_DFP | \
- VEX_HWCAPS_S390X_FGX)
+ VEX_HWCAPS_S390X_FGX | \
+ VEX_HWCAPS_S390X_ETF2)
#define VEX_HWCAPS_S390X(x) ((x) & ~VEX_S390X_MODEL_MASK)
#define VEX_S390X_MODEL(x) ((x) & VEX_S390X_MODEL_MASK)
|