]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
s390: Update IR generation for the SRNM insn.
authorFlorian Krohm <florian@eich-krohm.de>
Tue, 18 Sep 2012 20:24:38 +0000 (20:24 +0000)
committerFlorian Krohm <florian@eich-krohm.de>
Tue, 18 Sep 2012 20:24:38 +0000 (20:24 +0000)
Add support for the SRNMB insn.
New emulation warning EmWarn_S390X_invalid_rounding.

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

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

index d796171e77e31cac1124675c5b4f388e8fb2c7fe..6655fb6b2879099e5660e43fa8db3392de847675 100644 (file)
@@ -8174,16 +8174,51 @@ s390_irgen_LZXR(UChar r1)
 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)
 {
@@ -12635,7 +12670,8 @@ s390_decode_4byte_and_irgen(UChar *bytes)
                                  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;
index bbfc7ec1222acb2c0200adeb6bfdab11f8a1022a..a04a10f70ddc4a85959d29a51814ffafd36df395 100644 (file)
@@ -1031,6 +1031,9 @@ HChar* LibVEX_EmNote_string ( VexEmNote ew )
                "  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 EmWarn_S390X_invalid_rounding:
+        return "The specified rounding mode is invalid.\n"
+               "  Continuing using 'round to nearest'. Results may differ!";
      case EmFail_S390X_stfle:
         return "Instruction stfle is not supported on this host";
      case EmFail_S390X_stckf:
index 4295d73d1606b3a1842476ce0ecdb14ac4ef5ec9..a817eb7f067c545743faa28e449bbf67df4dbb29 100644 (file)
@@ -90,6 +90,9 @@ typedef
          facility is not available on this host */
       EmWarn_S390X_fpext_rounding,
 
+      /* insn (e.g. srnmb) specifies an invalid rounding mode */
+      EmWarn_S390X_invalid_rounding,
+
       /* stfle insn is not supported on this host */
       EmFail_S390X_stfle,