Re: [PATCH 04/19] target/ppc: Set result to QNaN for DENBCD when VXCVI occurs

2022-09-05 Thread Daniel Henrique Barboza




On 9/1/22 10:17, Víctor Colombo wrote:

According to the ISA, for instruction DENBCD:
"If an invalid BCD digit or sign code is detected in the source
operand, an invalid-operation exception (VXCVI) occurs."

In the Invalid Operation Exception section, there is the situation:
"When Invalid Operation Exception is disabled (VE=0) and Invalid
Operation occurs (...) If the operation is an (...) or format the
target FPR is set to a Quiet NaN". This was not being done in
QEMU.

This patch sets the result to QNaN when the instruction DENBCD causes
an Invalid Operation Exception.

Signed-off-by: Víctor Colombo 
---


Reviewed-by: Daniel Henrique Barboza 


  target/ppc/dfp_helper.c | 26 --
  1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index be7aa5357a..cc024316d5 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -1147,6 +1147,26 @@ static inline uint8_t dfp_get_bcd_digit_128(ppc_vsr_t 
*t, unsigned n)
  return t->VsrD((n & 0x10) ? 0 : 1) >> ((n << 2) & 63) & 15;
  }
  
+static inline void dfp_invalid_op_vxcvi_64(struct PPC_DFP *dfp)

+{
+/* TODO: fpscr is incorrectly not being saved to env */
+dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXCVI, FPSCR_VE);
+if ((dfp->env->fpscr & FP_VE) == 0) {
+dfp->vt.VsrD(1) = 0x7c00; /* QNaN */
+}
+}
+
+
+static inline void dfp_invalid_op_vxcvi_128(struct PPC_DFP *dfp)
+{
+/* TODO: fpscr is incorrectly not being saved to env */
+dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXCVI, FPSCR_VE);
+if ((dfp->env->fpscr & FP_VE) == 0) {
+dfp->vt.VsrD(0) = 0x7c00; /* QNaN */
+dfp->vt.VsrD(1) = 0x0;
+}
+}
+
  #define DFP_HELPER_ENBCD(op, size)   \
  void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b, \
   uint32_t s) \
@@ -1173,7 +1193,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b, \
  sgn = 0; \
  break;   \
  default: \
-dfp_set_FPSCR_flag(&dfp, FP_VX | FP_VXCVI, FPSCR_VE);\
+dfp_invalid_op_vxcvi_##size(&dfp);   \
+set_dfp##size(t, &dfp.vt);   \
  return;  \
  }\
  }\
@@ -1183,7 +1204,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b, \
  digits[(size) / 4 - n] = dfp_get_bcd_digit_##size(&dfp.vb,   \
offset++); \
  if (digits[(size) / 4 - n] > 10) {   \
-dfp_set_FPSCR_flag(&dfp, FP_VX | FP_VXCVI, FPSCR_VE);\
+dfp_invalid_op_vxcvi_##size(&dfp);   \
+set_dfp##size(t, &dfp.vt);   \
  return;  \
  } else { \
  nonzero |= (digits[(size) / 4 - n] > 0); \




[PATCH 04/19] target/ppc: Set result to QNaN for DENBCD when VXCVI occurs

2022-09-01 Thread Víctor Colombo
According to the ISA, for instruction DENBCD:
"If an invalid BCD digit or sign code is detected in the source
operand, an invalid-operation exception (VXCVI) occurs."

In the Invalid Operation Exception section, there is the situation:
"When Invalid Operation Exception is disabled (VE=0) and Invalid
Operation occurs (...) If the operation is an (...) or format the
target FPR is set to a Quiet NaN". This was not being done in
QEMU.

This patch sets the result to QNaN when the instruction DENBCD causes
an Invalid Operation Exception.

Signed-off-by: Víctor Colombo 
---
 target/ppc/dfp_helper.c | 26 --
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index be7aa5357a..cc024316d5 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -1147,6 +1147,26 @@ static inline uint8_t dfp_get_bcd_digit_128(ppc_vsr_t 
*t, unsigned n)
 return t->VsrD((n & 0x10) ? 0 : 1) >> ((n << 2) & 63) & 15;
 }
 
+static inline void dfp_invalid_op_vxcvi_64(struct PPC_DFP *dfp)
+{
+/* TODO: fpscr is incorrectly not being saved to env */
+dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXCVI, FPSCR_VE);
+if ((dfp->env->fpscr & FP_VE) == 0) {
+dfp->vt.VsrD(1) = 0x7c00; /* QNaN */
+}
+}
+
+
+static inline void dfp_invalid_op_vxcvi_128(struct PPC_DFP *dfp)
+{
+/* TODO: fpscr is incorrectly not being saved to env */
+dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXCVI, FPSCR_VE);
+if ((dfp->env->fpscr & FP_VE) == 0) {
+dfp->vt.VsrD(0) = 0x7c00; /* QNaN */
+dfp->vt.VsrD(1) = 0x0;
+}
+}
+
 #define DFP_HELPER_ENBCD(op, size)   \
 void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b, \
  uint32_t s) \
@@ -1173,7 +1193,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b, \
 sgn = 0; \
 break;   \
 default: \
-dfp_set_FPSCR_flag(&dfp, FP_VX | FP_VXCVI, FPSCR_VE);\
+dfp_invalid_op_vxcvi_##size(&dfp);   \
+set_dfp##size(t, &dfp.vt);   \
 return;  \
 }\
 }\
@@ -1183,7 +1204,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, 
ppc_fprp_t *b, \
 digits[(size) / 4 - n] = dfp_get_bcd_digit_##size(&dfp.vb,   \
   offset++); \
 if (digits[(size) / 4 - n] > 10) {   \
-dfp_set_FPSCR_flag(&dfp, FP_VX | FP_VXCVI, FPSCR_VE);\
+dfp_invalid_op_vxcvi_##size(&dfp);   \
+set_dfp##size(t, &dfp.vt);   \
 return;  \
 } else { \
 nonzero |= (digits[(size) / 4 - n] > 0); \
-- 
2.25.1