|
From: <sv...@va...> - 2012-09-18 20:24:45
|
florian 2012-09-18 21:24:38 +0100 (Tue, 18 Sep 2012)
New Revision: 2538
Log:
s390: Update IR generation for the SRNM insn.
Add support for the SRNMB insn.
New emulation warning EmWarn_S390X_invalid_rounding.
Modified files:
trunk/priv/guest_s390_toIR.c
trunk/priv/main_main.c
trunk/pub/libvex_emnote.h
Modified: trunk/priv/main_main.c (+3 -0)
===================================================================
--- trunk/priv/main_main.c 2012-09-17 19:08:00 +01:00 (rev 2537)
+++ trunk/priv/main_main.c 2012-09-18 21:24:38 +01:00 (rev 2538)
@@ -1031,6 +1031,9 @@
" 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:
Modified: trunk/pub/libvex_emnote.h (+3 -0)
===================================================================
--- trunk/pub/libvex_emnote.h 2012-09-17 19:08:00 +01:00 (rev 2537)
+++ trunk/pub/libvex_emnote.h 2012-09-18 21:24:38 +01:00 (rev 2538)
@@ -90,6 +90,9 @@
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,
Modified: trunk/priv/guest_s390_toIR.c (+42 -6)
===================================================================
--- trunk/priv/guest_s390_toIR.c 2012-09-17 19:08:00 +01:00 (rev 2537)
+++ trunk/priv/guest_s390_toIR.c 2012-09-18 21:24:38 +01:00 (rev 2538)
@@ -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;
|