s390: Update IR generation for the SRNM insn. 
Add support for the SRNMB insn.
New emulation warning EmWarn_S390X_invalid_rounding.


git-svn-id: svn://svn.valgrind.org/vex/trunk@2538 8f6e269a-dfd6-0310-a8e1-e2731360e62c
diff --git a/priv/guest_s390_toIR.c b/priv/guest_s390_toIR.c
index d796171..6655fb6 100644
--- a/priv/guest_s390_toIR.c
+++ b/priv/guest_s390_toIR.c
@@ -8174,17 +8174,52 @@
 static HChar *
 s390_irgen_SRNM(IRTemp op2addr)
 {
-   UInt mask;
+   UInt input_mask, fpc_mask;
 
-   mask = 3;
-   put_fpc_w0(binop(Iop_Or32, binop(Iop_And32, get_fpc_w0(), mkU32(~mask)),
-              binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)), mkU32(mask)))
-              );
+   input_mask = 3;
+   fpc_mask = s390_host_has_fpext ? 7 : 3;
 
+   put_fpc_w0(binop(Iop_Or32,
+                    binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
+                    binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
+                          mkU32(input_mask))));
    return "srnm";
 }
 
 static HChar *
+s390_irgen_SRNMB(IRTemp op2addr)
+{
+   UInt input_mask, fpc_mask;
+
+   input_mask = 7;
+   fpc_mask = 7;
+
+   put_fpc_w0(binop(Iop_Or32,
+                    binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
+                    binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
+                          mkU32(input_mask))));
+   return "srnmb";
+}
+
+ void
+s390_irgen_srnmb_wrapper(UChar b2, UShort d2)
+{
+   if (b2 == 0) {  /* This is the typical case */
+      if (d2 > 3) {
+         if (s390_host_has_fpext && d2 == 7) {
+            /* ok */
+         } else {
+            emulation_warning(EmWarn_S390X_invalid_rounding);
+            d2 = S390_FPC_ROUND_NEAREST_EVEN;
+         }
+      }
+   }
+
+   s390_format_S_RD(s390_irgen_SRNMB, b2, d2);
+}
+
+
+static HChar *
 s390_irgen_SFPC(UChar r1)
 {
    put_fpc_w0(get_gpr_w1(r1));
@@ -12635,7 +12670,8 @@
                                  goto ok;
    case 0xb2b1: /* STFL */ goto unimplemented;
    case 0xb2b2: /* LPSWE */ goto unimplemented;
-   case 0xb2b8: /* SRNMB */ goto unimplemented;
+   case 0xb2b8: s390_irgen_srnmb_wrapper(ovl.fmt.S.b2, ovl.fmt.S.d2);
+      goto ok;
    case 0xb2b9: /* SRNMT */ goto unimplemented;
    case 0xb2bd: /* LFAS */ goto unimplemented;
    case 0xb2ff: /* TRAP4 */ goto unimplemented;