]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Support the variety of "convert to/from fixed" and "load rounded" opcodes
authorFlorian Krohm <florian@eich-krohm.de>
Sun, 2 Sep 2012 18:07:08 +0000 (18:07 +0000)
committerFlorian Krohm <florian@eich-krohm.de>
Sun, 2 Sep 2012 18:07:08 +0000 (18:07 +0000)
that have an additional m3 and/or m4 field.
Add emulation warning EmWarn_S390X_fpext_rounding and issue it in case
the current opcode cannot be emulated correctly (i.e. with the specified
rounding mode).
New function: emulation_warning.
Part of fixing bugzilla #306098.

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

VEX/priv/guest_s390_toIR.c
VEX/priv/host_s390_isel.c
VEX/priv/main_main.c
VEX/pub/libvex_emnote.h

index 3001152d1242d8822cf9a4cae24dda26b743ce2a..8a3ec93c93d5b0f0b4f130707a39f2aa1ccefb2d 100644 (file)
@@ -431,6 +431,7 @@ static IRRoundingMode
 encode_rounding_mode(UChar mode)
 {
    switch (mode) {
+   default: return Irrm_NEAREST;  // fixs390: for now
    case S390_ROUND_NEAREST_EVEN:  return Irrm_NEAREST;
    case S390_ROUND_ZERO:          return Irrm_ZERO;
    case S390_ROUND_POSINF:        return Irrm_PosINF;
@@ -469,11 +470,19 @@ static void
 emulation_failure(VexEmNote fail_kind)
 {
    stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(fail_kind)));
-   put_IA(mkaddr_expr(guest_IA_next_instr));
    dis_res->whatNext = Dis_StopHere;
    dis_res->jk_StopHere = Ijk_EmFail;
 }
 
+/* Terminate the current IRSB with an emulation warning. */
+static void
+emulation_warning(VexEmNote warn_kind)
+{
+   stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(warn_kind)));
+   dis_res->whatNext = Dis_StopHere;
+   dis_res->jk_StopHere = Ijk_EmWarn;
+}
+
 /*------------------------------------------------------------*/
 /*--- IR Debugging aids.                                   ---*/
 /*------------------------------------------------------------*/
@@ -1711,6 +1720,16 @@ s390_format_RRF_F0FF(HChar *(*irgen)(UChar, UChar, UChar),
       s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
 }
 
+static void
+s390_format_RRF_UUFF(HChar *(*irgen)(UChar m3, UChar m4, UChar r1, UChar r2),
+                     UChar m3, UChar m4, UChar r1, UChar r2)
+{
+   HChar *mnm = irgen(m3, m4, r1, r2);
+
+   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
+      s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
+}
+
 static void
 s390_format_RRF_UUFR(HChar *(*irgen)(UChar m3, UChar m4, UChar r1, UChar r2),
                      UChar m3, UChar m4, UChar r1, UChar r2)
@@ -1742,16 +1761,6 @@ s390_format_RRF_U0RR(HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
       s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
 }
 
-static void
-s390_format_RRF_U0RF(HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
-                     UChar r3, UChar r1, UChar r2)
-{
-   HChar *mnm = irgen(r3, r1, r2);
-
-   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
-      s390_disasm(ENC4(MNM, GPR, UINT, FPR), mnm, r1, r3, r2);
-}
-
 static void
 s390_format_RRF_F0FF2(HChar *(*irgen)(UChar, UChar, UChar),
                       UChar r3, UChar r1, UChar r2)
@@ -8237,18 +8246,25 @@ s390_irgen_ADB(UChar r1, IRTemp op2addr)
 }
 
 static HChar *
-s390_irgen_CEFBR(UChar r1, UChar r2)
+s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
+                 UChar r1, UChar r2)
 {
+   if (! s390_host_has_fpext && m3 != 0) {
+      emulation_warning(EmWarn_S390X_fpext_rounding);
+      m3 = 0;
+   }
    IRTemp op2 = newTemp(Ity_I32);
 
    assign(op2, get_gpr_w1(r2));
-   put_fpr_w0(r1, binop(Iop_I32StoF32, mkU32(Irrm_NEAREST), mkexpr(op2)));
+   put_fpr_w0(r1, binop(Iop_I32StoF32, mkU32(encode_rounding_mode(m3)),
+                        mkexpr(op2)));
 
    return "cefbr";
 }
 
 static HChar *
-s390_irgen_CDFBR(UChar r1, UChar r2)
+s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
+                 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
 {
    IRTemp op2 = newTemp(Ity_I32);
 
@@ -8259,23 +8275,35 @@ s390_irgen_CDFBR(UChar r1, UChar r2)
 }
 
 static HChar *
-s390_irgen_CEGBR(UChar r1, UChar r2)
+s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
+                 UChar r1, UChar r2)
 {
+   if (! s390_host_has_fpext && m3 != 0) {
+      emulation_warning(EmWarn_S390X_fpext_rounding);
+      m3 = 0;
+   }
    IRTemp op2 = newTemp(Ity_I64);
 
    assign(op2, get_gpr_dw0(r2));
-   put_fpr_w0(r1, binop(Iop_I64StoF32, mkU32(Irrm_NEAREST), mkexpr(op2)));
+   put_fpr_w0(r1, binop(Iop_I64StoF32, mkU32(encode_rounding_mode(m3)),
+                        mkexpr(op2)));
 
    return "cegbr";
 }
 
 static HChar *
-s390_irgen_CDGBR(UChar r1, UChar r2)
+s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
+                 UChar r1, UChar r2)
 {
+   if (! s390_host_has_fpext && m3 != 0) {
+      emulation_warning(EmWarn_S390X_fpext_rounding);
+      m3 = 0;
+   }
    IRTemp op2 = newTemp(Ity_I64);
 
    assign(op2, get_gpr_dw0(r2));
-   put_fpr_dw0(r1, binop(Iop_I64StoF64, mkU32(Irrm_NEAREST), mkexpr(op2)));
+   put_fpr_dw0(r1, binop(Iop_I64StoF64, mkU32(encode_rounding_mode(m3)),
+                         mkexpr(op2)));
 
    return "cdgbr";
 }
@@ -8420,13 +8448,18 @@ s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
 }
 
 static HChar *
-s390_irgen_CFEBR(UChar r3, UChar r1, UChar r2)
+s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
+                 UChar r1, UChar r2)
 {
+   if (! s390_host_has_fpext && m3 != 0) {
+      emulation_warning(EmWarn_S390X_fpext_rounding);
+      m3 = 0;
+   }
    IRTemp op = newTemp(Ity_F32);
    IRTemp result = newTemp(Ity_I32);
 
    assign(op, get_fpr_w0(r2));
-   assign(result, binop(Iop_F32toI32S, mkU32(encode_rounding_mode(r3)),
+   assign(result, binop(Iop_F32toI32S, mkU32(encode_rounding_mode(m3)),
           mkexpr(op)));
    put_gpr_w1(r1, mkexpr(result));
    s390_cc_thunk_putF(S390_CC_OP_BFP_32_TO_INT_32, op);
@@ -8435,13 +8468,18 @@ s390_irgen_CFEBR(UChar r3, UChar r1, UChar r2)
 }
 
 static HChar *
-s390_irgen_CFDBR(UChar r3, UChar r1, UChar r2)
+s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
+                 UChar r1, UChar r2)
 {
+   if (! s390_host_has_fpext && m3 != 0) {
+      emulation_warning(EmWarn_S390X_fpext_rounding);
+      m3 = 0;
+   }
    IRTemp op = newTemp(Ity_F64);
    IRTemp result = newTemp(Ity_I32);
 
    assign(op, get_fpr_dw0(r2));
-   assign(result, binop(Iop_F64toI32S, mkU32(encode_rounding_mode(r3)),
+   assign(result, binop(Iop_F64toI32S, mkU32(encode_rounding_mode(m3)),
           mkexpr(op)));
    put_gpr_w1(r1, mkexpr(result));
    s390_cc_thunk_putF(S390_CC_OP_BFP_64_TO_INT_32, op);
@@ -8450,13 +8488,18 @@ s390_irgen_CFDBR(UChar r3, UChar r1, UChar r2)
 }
 
 static HChar *
-s390_irgen_CGEBR(UChar r3, UChar r1, UChar r2)
+s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
+                 UChar r1, UChar r2)
 {
+   if (! s390_host_has_fpext && m3 != 0) {
+      emulation_warning(EmWarn_S390X_fpext_rounding);
+      m3 = 0;
+   }
    IRTemp op = newTemp(Ity_F32);
    IRTemp result = newTemp(Ity_I64);
 
    assign(op, get_fpr_w0(r2));
-   assign(result, binop(Iop_F32toI64S, mkU32(encode_rounding_mode(r3)),
+   assign(result, binop(Iop_F32toI64S, mkU32(encode_rounding_mode(m3)),
           mkexpr(op)));
    put_gpr_dw0(r1, mkexpr(result));
    s390_cc_thunk_putF(S390_CC_OP_BFP_32_TO_INT_64, op);
@@ -8465,13 +8508,18 @@ s390_irgen_CGEBR(UChar r3, UChar r1, UChar r2)
 }
 
 static HChar *
-s390_irgen_CGDBR(UChar r3, UChar r1, UChar r2)
+s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
+                 UChar r1, UChar r2)
 {
+   if (! s390_host_has_fpext && m3 != 0) {
+      emulation_warning(EmWarn_S390X_fpext_rounding);
+      m3 = 0;
+   }
    IRTemp op = newTemp(Ity_F64);
    IRTemp result = newTemp(Ity_I64);
 
    assign(op, get_fpr_dw0(r2));
-   assign(result, binop(Iop_F64toI64S, mkU32(encode_rounding_mode(r3)),
+   assign(result, binop(Iop_F64toI64S, mkU32(encode_rounding_mode(m3)),
           mkexpr(op)));
    put_gpr_dw0(r1, mkexpr(result));
    s390_cc_thunk_putF(S390_CC_OP_BFP_64_TO_INT_64, op);
@@ -8614,12 +8662,14 @@ s390_irgen_LDEB(UChar r1, IRTemp op2addr)
 }
 
 static HChar *
-s390_irgen_LEDBR(UChar r1, UChar r2)
+s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
+                 UChar r1, UChar r2)
 {
    IRTemp op = newTemp(Ity_F64);
 
    assign(op, get_fpr_dw0(r2));
-   put_fpr_w0(r1, binop(Iop_F64toF32, mkU32(Irrm_NEAREST), mkexpr(op)));
+   put_fpr_w0(r1, binop(Iop_F64toF32, mkU32(encode_rounding_mode(m3)),
+                        mkexpr(op)));
 
    return "ledbr";
 }
@@ -10304,7 +10354,8 @@ s390_irgen_CDB(UChar r1, IRTemp op2addr)
 }
 
 static HChar *
-s390_irgen_CXFBR(UChar r1, UChar r2)
+s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
+                 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
 {
    IRTemp op2 = newTemp(Ity_I32);
 
@@ -10331,7 +10382,8 @@ s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
 
 
 static HChar *
-s390_irgen_CXGBR(UChar r1, UChar r2)
+s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
+                 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
 {
    IRTemp op2 = newTemp(Ity_I64);
 
@@ -10357,13 +10409,18 @@ s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
 }
 
 static HChar *
-s390_irgen_CFXBR(UChar r3, UChar r1, UChar r2)
+s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
+                 UChar r1, UChar r2)
 {
+   if (! s390_host_has_fpext && m3 != 0) {
+      emulation_warning(EmWarn_S390X_fpext_rounding);
+      m3 = 0;
+   }
    IRTemp op = newTemp(Ity_F128);
    IRTemp result = newTemp(Ity_I32);
 
    assign(op, get_fpr_pair(r2));
-   assign(result, binop(Iop_F128toI32S, mkU32(encode_rounding_mode(r3)),
+   assign(result, binop(Iop_F128toI32S, mkU32(encode_rounding_mode(m3)),
                         mkexpr(op)));
    put_gpr_w1(r1, mkexpr(result));
    s390_cc_thunk_put1f128(S390_CC_OP_BFP_128_TO_INT_32, op);
@@ -10392,13 +10449,18 @@ s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
 
 
 static HChar *
-s390_irgen_CGXBR(UChar r3, UChar r1, UChar r2)
+s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
+                 UChar r1, UChar r2)
 {
+   if (! s390_host_has_fpext && m3 != 0) {
+      emulation_warning(EmWarn_S390X_fpext_rounding);
+      m3 = 0;
+   }
    IRTemp op = newTemp(Ity_F128);
    IRTemp result = newTemp(Ity_I64);
 
    assign(op, get_fpr_pair(r2));
-   assign(result, binop(Iop_F128toI64S, mkU32(encode_rounding_mode(r3)),
+   assign(result, binop(Iop_F128toI64S, mkU32(encode_rounding_mode(m3)),
                         mkexpr(op)));
    put_gpr_dw0(r1, mkexpr(result));
    s390_cc_thunk_put1f128(S390_CC_OP_BFP_128_TO_INT_64, op);
@@ -10582,22 +10644,26 @@ s390_irgen_LPXBR(UChar r1, UChar r2)
 }
 
 static HChar *
-s390_irgen_LDXBR(UChar r1, UChar r2)
+s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
+                 UChar r1, UChar r2)
 {
    IRTemp result = newTemp(Ity_F64);
 
-   assign(result, binop(Iop_F128toF64, mkU32(Irrm_NEAREST), get_fpr_pair(r2)));
+   assign(result, binop(Iop_F128toF64, mkU32(encode_rounding_mode(m3)),
+                        get_fpr_pair(r2)));
    put_fpr_dw0(r1, mkexpr(result));
 
    return "ldxbr";
 }
 
 static HChar *
-s390_irgen_LEXBR(UChar r1, UChar r2)
+s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
+                 UChar r1, UChar r2)
 {
    IRTemp result = newTemp(Ity_F32);
 
-   assign(result, binop(Iop_F128toF32, mkU32(Irrm_NEAREST), get_fpr_pair(r2)));
+   assign(result, binop(Iop_F128toF32, mkU32(encode_rounding_mode(m3)),
+                        get_fpr_pair(r2)));
    put_fpr_w0(r1, mkexpr(result));
 
    return "lexbr";
@@ -12561,12 +12627,15 @@ s390_decode_4byte_and_irgen(UChar *bytes)
                                    ovl.fmt.RRE.r2);  goto ok;
    case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
                                    ovl.fmt.RRE.r2);  goto ok;
-   case 0xb344: s390_format_RRE_FF(s390_irgen_LEDBR, ovl.fmt.RRE.r1,
-                                   ovl.fmt.RRE.r2);  goto ok;
-   case 0xb345: s390_format_RRE_FF(s390_irgen_LDXBR, ovl.fmt.RRE.r1,
-                                   ovl.fmt.RRE.r2);  goto ok;
-   case 0xb346: s390_format_RRE_FF(s390_irgen_LEXBR, ovl.fmt.RRE.r1,
-                                   ovl.fmt.RRE.r2);  goto ok;
+   case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, ovl.fmt.RRF2.m3,
+                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
+                                     ovl.fmt.RRF2.r2);  goto ok;
+   case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, ovl.fmt.RRF2.m3,
+                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
+                                     ovl.fmt.RRF2.r2);  goto ok;
+   case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, ovl.fmt.RRF2.m3,
+                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
+                                     ovl.fmt.RRF2.r2);  goto ok;
    case 0xb347: /* FIXBR */ goto unimplemented;
    case 0xb348: /* KXBR */ goto unimplemented;
    case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
@@ -12622,21 +12691,24 @@ s390_decode_4byte_and_irgen(UChar *bytes)
    case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
                                      ovl.fmt.RRF2.r2);  goto ok;
-   case 0xb394: s390_format_RRE_FR(s390_irgen_CEFBR, ovl.fmt.RRE.r1,
-                                   ovl.fmt.RRE.r2);  goto ok;
-   case 0xb395: s390_format_RRE_FR(s390_irgen_CDFBR, ovl.fmt.RRE.r1,
-                                   ovl.fmt.RRE.r2);  goto ok;
-   case 0xb396: s390_format_RRE_FR(s390_irgen_CXFBR, ovl.fmt.RRE.r1,
-                                   ovl.fmt.RRE.r2);  goto ok;
-   case 0xb398: s390_format_RRF_U0RF(s390_irgen_CFEBR, ovl.fmt.RRF3.r3,
-                                     ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
-                                     goto ok;
-   case 0xb399: s390_format_RRF_U0RF(s390_irgen_CFDBR, ovl.fmt.RRF3.r3,
-                                     ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
-                                     goto ok;
-   case 0xb39a: s390_format_RRF_U0RF(s390_irgen_CFXBR, ovl.fmt.RRF3.r3,
-                                     ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
-                                     goto ok;
+   case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, ovl.fmt.RRF2.m3,
+                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
+                                     ovl.fmt.RRF2.r2);  goto ok;
+   case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, ovl.fmt.RRF2.m3,
+                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
+                                     ovl.fmt.RRF2.r2);  goto ok;
+   case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, ovl.fmt.RRF2.m3,
+                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
+                                     ovl.fmt.RRF2.r2);  goto ok;
+   case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, ovl.fmt.RRF2.m3,
+                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
+                                     ovl.fmt.RRF2.r2);  goto ok;
+   case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, ovl.fmt.RRF2.m3,
+                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
+                                     ovl.fmt.RRF2.r2);  goto ok;
+   case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, ovl.fmt.RRF2.m3,
+                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
+                                     ovl.fmt.RRF2.r2);  goto ok;
    case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
                                      ovl.fmt.RRF2.r2);  goto ok;
@@ -12655,21 +12727,24 @@ s390_decode_4byte_and_irgen(UChar *bytes)
    case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
                                      ovl.fmt.RRF2.r2);  goto ok;
-   case 0xb3a4: s390_format_RRE_FR(s390_irgen_CEGBR, ovl.fmt.RRE.r1,
-                                   ovl.fmt.RRE.r2);  goto ok;
-   case 0xb3a5: s390_format_RRE_FR(s390_irgen_CDGBR, ovl.fmt.RRE.r1,
-                                   ovl.fmt.RRE.r2);  goto ok;
-   case 0xb3a6: s390_format_RRE_FR(s390_irgen_CXGBR, ovl.fmt.RRE.r1,
-                                   ovl.fmt.RRE.r2);  goto ok;
-   case 0xb3a8: s390_format_RRF_U0RF(s390_irgen_CGEBR, ovl.fmt.RRF3.r3,
-                                     ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
-                                     goto ok;
-   case 0xb3a9: s390_format_RRF_U0RF(s390_irgen_CGDBR, ovl.fmt.RRF3.r3,
-                                     ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
-                                     goto ok;
-   case 0xb3aa: s390_format_RRF_U0RF(s390_irgen_CGXBR, ovl.fmt.RRF3.r3,
-                                     ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
-                                     goto ok;
+   case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, ovl.fmt.RRF2.m3,
+                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
+                                     ovl.fmt.RRF2.r2);  goto ok;
+   case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, ovl.fmt.RRF2.m3,
+                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
+                                     ovl.fmt.RRF2.r2);  goto ok;
+   case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, ovl.fmt.RRF2.m3,
+                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
+                                     ovl.fmt.RRF2.r2);  goto ok;
+   case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, ovl.fmt.RRF2.m3,
+                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
+                                     ovl.fmt.RRF2.r2);  goto ok;
+   case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, ovl.fmt.RRF2.m3,
+                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
+                                     ovl.fmt.RRF2.r2);  goto ok;
+   case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, ovl.fmt.RRF2.m3,
+                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
+                                     ovl.fmt.RRF2.r2);  goto ok;
    case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
                                      ovl.fmt.RRF2.r2);  goto ok;
@@ -14558,6 +14633,13 @@ disInstr_S390_WRK(UChar *insn)
          put_IA(mkaddr_expr(dres.continueAt));
          break;
       case Dis_StopHere:
+         if (dres.jk_StopHere == Ijk_EmWarn ||
+             dres.jk_StopHere == Ijk_EmFail) {
+            /* We assume here, that emulation warnings are not given for
+               insns that transfer control. There is no good way to
+               do that. */
+            put_IA(mkaddr_expr(guest_IA_next_instr));
+         }
          break;
       default:
          vassert(0);
index abfd2a6f7c2a555cbe80ec15e5cddbc4e2c35303..1bfa7b5126326218b790def89c01af64ca85364e 100644 (file)
@@ -2610,6 +2610,7 @@ s390_isel_stmt(ISelEnv *env, IRStmt *stmt)
       /* Case: assisted transfer to arbitrary address */
       switch (stmt->Ist.Exit.jk) {
       case Ijk_EmFail:
+      case Ijk_EmWarn:
       case Ijk_NoDecode:
       case Ijk_TInval:
       case Ijk_Sys_syscall:
@@ -2724,6 +2725,7 @@ iselNext(ISelEnv *env, IRExpr *next, IRJumpKind jk, int offsIP)
    /* Case: some other kind of transfer to any address */
    switch (jk) {
    case Ijk_EmFail:
+   case Ijk_EmWarn:
    case Ijk_NoDecode:
    case Ijk_TInval:
    case Ijk_Sys_syscall:
index 29b971d5e52cfd18bc8de365baf09aadb9b3d0a7..bbfc7ec1222acb2c0200adeb6bfdab11f8a1022a 100644 (file)
@@ -1026,6 +1026,11 @@ HChar* LibVEX_EmNote_string ( VexEmNote ew )
         return "PPC64 function redirection stack overflow";
      case EmWarn_PPC64_redir_underflow:
         return "PPC64 function redirection stack underflow";
+     case EmWarn_S390X_fpext_rounding:
+        return "The specified rounding mode cannot be supported. That\n"
+               "  feature requires the floating point extension facility.\n"
+               "  which is not available on this host. Continuing using\n"
+               "  the rounding mode from FPC. Results may differ!";
      case EmFail_S390X_stfle:
         return "Instruction stfle is not supported on this host";
      case EmFail_S390X_stckf:
index bb9cab776af52222feedd3d40cf408251d859473..4295d73d1606b3a1842476ce0ecdb14ac4ef5ec9 100644 (file)
@@ -85,6 +85,11 @@ typedef
       EmWarn_PPC64_redir_overflow,
       EmWarn_PPC64_redir_underflow,
 
+      /* insn specifies a rounding mode other than "according to FPC"
+         which requires the floating point extension facility. But that
+         facility is not available on this host */
+      EmWarn_S390X_fpext_rounding,
+
       /* stfle insn is not supported on this host */
       EmFail_S390X_stfle,