From: Florian Krohm Date: Tue, 18 Sep 2012 20:24:38 +0000 (+0000) Subject: s390: Update IR generation for the SRNM insn. X-Git-Tag: svn/VALGRIND_3_9_0^2~235 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5a09b058e0b2f89c7171edd38075066b01538f94;p=thirdparty%2Fvalgrind.git 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 --- diff --git a/VEX/priv/guest_s390_toIR.c b/VEX/priv/guest_s390_toIR.c index d796171e77..6655fb6b28 100644 --- a/VEX/priv/guest_s390_toIR.c +++ b/VEX/priv/guest_s390_toIR.c @@ -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; diff --git a/VEX/priv/main_main.c b/VEX/priv/main_main.c index bbfc7ec122..a04a10f70d 100644 --- a/VEX/priv/main_main.c +++ b/VEX/priv/main_main.c @@ -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: diff --git a/VEX/pub/libvex_emnote.h b/VEX/pub/libvex_emnote.h index 4295d73d16..a817eb7f06 100644 --- a/VEX/pub/libvex_emnote.h +++ b/VEX/pub/libvex_emnote.h @@ -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,