|
From: <sv...@va...> - 2015-07-09 20:59:32
|
Author: florian
Date: Thu Jul 9 21:59:24 2015
New Revision: 3162
Log:
s390: Add support for FIEBR(A) and FIDBR(A).
Patch by Andreas Arnez (ar...@li...). Part of fixing BZ #342841.
Modified:
trunk/priv/guest_s390_toIR.c
trunk/priv/host_s390_defs.c
trunk/priv/host_s390_defs.h
trunk/priv/host_s390_isel.c
Modified: trunk/priv/guest_s390_toIR.c
==============================================================================
--- trunk/priv/guest_s390_toIR.c (original)
+++ trunk/priv/guest_s390_toIR.c Thu Jul 9 21:59:24 2015
@@ -12384,6 +12384,32 @@
}
static const HChar *
+s390_irgen_FIEBRA(UChar m3, UChar m4 __attribute__((unused)),
+ UChar r1, UChar r2)
+{
+ IRTemp result = newTemp(Ity_F32);
+
+ assign(result, binop(Iop_RoundF32toInt, mkexpr(encode_bfp_rounding_mode(m3)),
+ get_fpr_w0(r2)));
+ put_fpr_w0(r1, mkexpr(result));
+
+ return "fiebra";
+}
+
+static const HChar *
+s390_irgen_FIDBRA(UChar m3, UChar m4 __attribute__((unused)),
+ UChar r1, UChar r2)
+{
+ IRTemp result = newTemp(Ity_F64);
+
+ assign(result, binop(Iop_RoundF64toInt, mkexpr(encode_bfp_rounding_mode(m3)),
+ get_fpr_dw0(r2)));
+ put_fpr_dw0(r1, mkexpr(result));
+
+ return "fidbra";
+}
+
+static const HChar *
s390_irgen_LNEBR(UChar r1, UChar r2)
{
IRTemp result = newTemp(Ity_F32);
@@ -14520,11 +14546,15 @@
case 0xb350: /* TBEDR */ goto unimplemented;
case 0xb351: /* TBDR */ goto unimplemented;
case 0xb353: /* DIEBR */ goto unimplemented;
- case 0xb357: /* FIEBR */ goto unimplemented;
+ case 0xb357: s390_format_RRF_UUFF(s390_irgen_FIEBRA, ovl.fmt.RRF2.m3,
+ ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
+ ovl.fmt.RRF2.r2); goto ok;
case 0xb358: /* THDER */ goto unimplemented;
case 0xb359: /* THDR */ goto unimplemented;
case 0xb35b: /* DIDBR */ goto unimplemented;
- case 0xb35f: /* FIDBR */ goto unimplemented;
+ case 0xb35f: s390_format_RRF_UUFF(s390_irgen_FIDBRA, ovl.fmt.RRF2.m3,
+ ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
+ ovl.fmt.RRF2.r2); goto ok;
case 0xb360: /* LPXR */ goto unimplemented;
case 0xb361: /* LNXR */ goto unimplemented;
case 0xb362: /* LTXR */ goto unimplemented;
Modified: trunk/priv/host_s390_defs.c
==============================================================================
--- trunk/priv/host_s390_defs.c (original)
+++ trunk/priv/host_s390_defs.c Thu Jul 9 21:59:24 2015
@@ -3939,6 +3939,40 @@
static UChar *
+s390_emit_FIEBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
+{
+ vassert(m3 == 0 || s390_host_has_fpext);
+
+ if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
+ if (m4 == 0)
+ s390_disasm(ENC4(MNM, FPR, UINT, FPR), "fiebr", r1, m3, r2);
+ else
+ s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT),
+ "fiebra", r1, m3, r2, m4);
+ }
+
+ return emit_RRF2(p, 0xb3570000, m3, m4, r1, r2);
+}
+
+
+static UChar *
+s390_emit_FIDBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
+{
+ vassert(m3 == 0 || s390_host_has_fpext);
+
+ if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
+ if (m4 == 0)
+ s390_disasm(ENC4(MNM, FPR, UINT, FPR), "fidbr", r1, m3, r2);
+ else
+ s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT),
+ "fidbra", r1, m3, r2, m4);
+ }
+
+ return emit_RRF2(p, 0xb35f0000, m3, m4, r1, r2);
+}
+
+
+static UChar *
s390_emit_MEEBR(UChar *p, UChar r1, UChar r2)
{
if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
@@ -6693,6 +6727,8 @@
case S390_BFP_F64_TO_F128:
case S390_BFP_F128_TO_F32:
case S390_BFP_F128_TO_F64: op = "v-f2f"; break;
+ case S390_BFP_F32_TO_F32I:
+ case S390_BFP_F64_TO_F64I: op = "v-f2fi"; break;
default: goto fail;
}
s390_sprintf(buf, "%M %R,%R", op, insn->variant.bfp_convert.dst_hi,
@@ -8964,6 +9000,10 @@
case S390_BFP_F128_TO_F32: return s390_emit_LEXBRA(buf, m3, m4, r1, r2);
case S390_BFP_F128_TO_F64: return s390_emit_LDXBRA(buf, m3, m4, r1, r2);
+ /* Load FP integer */
+ case S390_BFP_F32_TO_F32I: return s390_emit_FIEBRA(buf, m3, m4, r1, r2);
+ case S390_BFP_F64_TO_F64I: return s390_emit_FIDBRA(buf, m3, m4, r1, r2);
+
default: goto fail;
}
Modified: trunk/priv/host_s390_defs.h
==============================================================================
--- trunk/priv/host_s390_defs.h (original)
+++ trunk/priv/host_s390_defs.h Thu Jul 9 21:59:24 2015
@@ -242,7 +242,9 @@
S390_BFP_F128_TO_U32,
S390_BFP_F128_TO_U64,
S390_BFP_F128_TO_F32,
- S390_BFP_F128_TO_F64
+ S390_BFP_F128_TO_F64,
+ S390_BFP_F32_TO_F32I,
+ S390_BFP_F64_TO_F64I
} s390_bfp_conv_t;
/* Type conversion operations: to and/or from decimal floating point */
Modified: trunk/priv/host_s390_isel.c
==============================================================================
--- trunk/priv/host_s390_isel.c (original)
+++ trunk/priv/host_s390_isel.c Thu Jul 9 21:59:24 2015
@@ -2378,6 +2378,8 @@
return dst;
case Iop_F64toF32: conv = S390_BFP_F64_TO_F32; goto convert_float;
+ case Iop_RoundF32toInt: conv = S390_BFP_F32_TO_F32I; goto convert_float;
+ case Iop_RoundF64toInt: conv = S390_BFP_F64_TO_F64I; goto convert_float;
case Iop_I32StoF32: conv = S390_BFP_I32_TO_F32; goto convert_int;
case Iop_I32UtoF32: conv = S390_BFP_U32_TO_F32; goto convert_int;
case Iop_I64StoF32: conv = S390_BFP_I64_TO_F32; goto convert_int;
|