|
From: <sv...@va...> - 2013-02-11 00:03:40
|
florian 2013-02-11 00:03:27 +0000 (Mon, 11 Feb 2013)
New Revision: 2681
Log:
s390: Be consistent with emulation warnings about unsupported
rounding modes in absence of the floating-point extension facility.
For some insns we would vassert for others we'd give a warning.
Now we always issue an emulation warning.
Modified files:
trunk/priv/guest_s390_toIR.c
trunk/priv/host_s390_defs.c
Modified: trunk/priv/host_s390_defs.c (+2 -2)
===================================================================
--- trunk/priv/host_s390_defs.c 2013-02-08 23:32:54 +00:00 (rev 2680)
+++ trunk/priv/host_s390_defs.c 2013-02-11 00:03:27 +00:00 (rev 2681)
@@ -4492,7 +4492,7 @@
{
vassert(s390_host_has_dfp);
vassert(m4 == 0);
- vassert(m3 == 0 || s390_host_has_fpext);
+ vassert(s390_host_has_fpext || m3 < 1 || m3 > 7);
if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT),
@@ -4508,7 +4508,7 @@
{
vassert(s390_host_has_dfp);
vassert(m4 == 0);
- vassert(m3 == 0 || s390_host_has_fpext);
+ vassert(s390_host_has_fpext || m3 < 1 || m3 > 7);
if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT),
Modified: trunk/priv/guest_s390_toIR.c (+59 -26)
===================================================================
--- trunk/priv/guest_s390_toIR.c 2013-02-08 23:32:54 +00:00 (rev 2680)
+++ trunk/priv/guest_s390_toIR.c 2013-02-11 00:03:27 +00:00 (rev 2681)
@@ -9226,9 +9226,12 @@
IRTemp rounding_mode;
vassert(s390_host_has_dfp);
- vassert(m4 == 0 || s390_host_has_fpext);
- /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
- since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
+
+ if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
+ emulation_warning(EmWarn_S390X_fpext_rounding);
+ m4 = S390_DFP_ROUND_PER_FPC_0;
+ }
+
rounding_mode = encode_dfp_rounding_mode(m4);
assign(op1, get_dpr_dw0(r2));
assign(op2, get_dpr_dw0(r3));
@@ -9249,9 +9252,12 @@
IRTemp rounding_mode;
vassert(s390_host_has_dfp);
- vassert(m4 == 0 || s390_host_has_fpext);
- /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
- since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
+
+ if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
+ emulation_warning(EmWarn_S390X_fpext_rounding);
+ m4 = S390_DFP_ROUND_PER_FPC_0;
+ }
+
rounding_mode = encode_dfp_rounding_mode(m4);
assign(op1, get_dpr_pair(r2));
assign(op2, get_dpr_pair(r3));
@@ -9361,6 +9367,9 @@
vassert(s390_host_has_dfp);
+ /* No emulation warning here about an non-zero m3 on hosts without
+ floating point extension facility. No rounding is performed */
+
assign(op2, get_gpr_dw0(r2));
put_dpr_pair(r1, unop(Iop_I64StoD128, mkexpr(op2)));
@@ -9662,9 +9671,12 @@
IRTemp rounding_mode;
vassert(s390_host_has_dfp);
- vassert(m4 == 0 || s390_host_has_fpext);
- /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
- since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
+
+ if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
+ emulation_warning(EmWarn_S390X_fpext_rounding);
+ m4 = S390_DFP_ROUND_PER_FPC_0;
+ }
+
rounding_mode = encode_dfp_rounding_mode(m4);
assign(op1, get_dpr_dw0(r2));
assign(op2, get_dpr_dw0(r3));
@@ -9684,9 +9696,12 @@
IRTemp rounding_mode;
vassert(s390_host_has_dfp);
- vassert(m4 == 0 || s390_host_has_fpext);
- /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
- since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
+
+ if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
+ emulation_warning(EmWarn_S390X_fpext_rounding);
+ m4 = S390_DFP_ROUND_PER_FPC_0;
+ }
+
rounding_mode = encode_dfp_rounding_mode(m4);
assign(op1, get_dpr_pair(r2));
assign(op2, get_dpr_pair(r3));
@@ -9742,7 +9757,10 @@
UChar r1, UChar r2)
{
vassert(s390_host_has_dfp);
- if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
+
+ /* If fpext is not installed and m3 is in 1:7,
+ rounding mode performed is unpredictable */
+ if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
emulation_warning(EmWarn_S390X_fpext_rounding);
m3 = S390_DFP_ROUND_PER_FPC_0;
}
@@ -9760,7 +9778,10 @@
UChar r1, UChar r2)
{
vassert(s390_host_has_dfp);
- if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
+
+ /* If fpext is not installed and m3 is in 1:7,
+ rounding mode performed is unpredictable */
+ if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
emulation_warning(EmWarn_S390X_fpext_rounding);
m3 = S390_DFP_ROUND_PER_FPC_0;
}
@@ -9806,9 +9827,12 @@
IRTemp rounding_mode;
vassert(s390_host_has_dfp);
- vassert(m4 == 0 || s390_host_has_fpext);
- /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
- since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
+
+ if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
+ emulation_warning(EmWarn_S390X_fpext_rounding);
+ m4 = S390_DFP_ROUND_PER_FPC_0;
+ }
+
rounding_mode = encode_dfp_rounding_mode(m4);
assign(op1, get_dpr_dw0(r2));
assign(op2, get_dpr_dw0(r3));
@@ -9828,9 +9852,12 @@
IRTemp rounding_mode;
vassert(s390_host_has_dfp);
- vassert(m4 == 0 || s390_host_has_fpext);
- /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
- since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
+
+ if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
+ emulation_warning(EmWarn_S390X_fpext_rounding);
+ m4 = S390_DFP_ROUND_PER_FPC_0;
+ }
+
rounding_mode = encode_dfp_rounding_mode(m4);
assign(op1, get_dpr_pair(r2));
assign(op2, get_dpr_pair(r3));
@@ -9850,9 +9877,12 @@
IRTemp rounding_mode;
vassert(s390_host_has_dfp);
- vassert(m4 == 0 || s390_host_has_fpext);
- /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
- since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
+
+ if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
+ emulation_warning(EmWarn_S390X_fpext_rounding);
+ m4 = S390_DFP_ROUND_PER_FPC_0;
+ }
+
rounding_mode = encode_dfp_rounding_mode(m4);
assign(op1, get_dpr_dw0(r2));
assign(op2, get_dpr_dw0(r3));
@@ -9873,9 +9903,12 @@
IRTemp rounding_mode;
vassert(s390_host_has_dfp);
- vassert(m4 == 0 || s390_host_has_fpext);
- /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
- since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
+
+ if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
+ emulation_warning(EmWarn_S390X_fpext_rounding);
+ m4 = S390_DFP_ROUND_PER_FPC_0;
+ }
+
rounding_mode = encode_dfp_rounding_mode(m4);
assign(op1, get_dpr_pair(r2));
assign(op2, get_dpr_pair(r3));
|