]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
s390: Add support for FIEBR(A) and FIDBR(A).
authorFlorian Krohm <florian@eich-krohm.de>
Thu, 9 Jul 2015 20:59:24 +0000 (20:59 +0000)
committerFlorian Krohm <florian@eich-krohm.de>
Thu, 9 Jul 2015 20:59:24 +0000 (20:59 +0000)
Patch by Andreas Arnez (arnez@linux.vnet.ibm.com). Part of fixing BZ #342841.

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

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

index 023cb7d9b15293982c78aac138422b8dfe740bbd..9b563f75cd6bff21beb4effd64b515e056e1de8a 100644 (file)
@@ -12383,6 +12383,32 @@ s390_irgen_LXEB(UChar r1, IRTemp op2addr)
    return "lxeb";
 }
 
+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)
 {
@@ -14520,11 +14546,15 @@ s390_decode_4byte_and_irgen(const UChar *bytes)
    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;
index 974ec6d47fbd17798d83115aebd65754ff798ea4..3d821f9e0848a2368f66c88db3e5fbe19e1a2674 100644 (file)
@@ -3938,6 +3938,40 @@ s390_emit_LEXBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
 }
 
 
+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)
 {
@@ -6693,6 +6727,8 @@ s390_insn_as_string(const s390_insn *insn)
       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 @@ s390_insn_bfp_convert_emit(UChar *buf, const s390_insn *insn)
    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;
    }
 
index 9d732f975e420c9df7bed2a0e949f9270df3ac24..d10376b0d707fd019f7af468e2e61ad3f7c8b0fe 100644 (file)
@@ -242,7 +242,9 @@ typedef enum {
    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 */
index dee892aeb62fe4c929e7ce7f583b84d5e00a3629..37ef88b5c636a9c8685657973063eac731643515 100644 (file)
@@ -2378,6 +2378,8 @@ s390_isel_float_expr_wrk(ISelEnv *env, IRExpr *expr)
          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;