[PATCH v1 4/4] target/microblaze: Handle signed division overflows

Edgar E. Iglesias posted 4 patches 2 months, 3 weeks ago
Maintainers: "Edgar E. Iglesias" <edgar.iglesias@gmail.com>
There is a newer version of this series
[PATCH v1 4/4] target/microblaze: Handle signed division overflows
Posted by Edgar E. Iglesias 2 months, 3 weeks ago
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>

Handle signed division overflows as specified in UG984:
https://docs.amd.com/r/en-US/ug984-vivado-microblaze-ref/idiv

Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
---
 target/microblaze/cpu.h       |  1 +
 target/microblaze/op_helper.c | 15 +++++++++++++++
 2 files changed, 16 insertions(+)

diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index 3ce28b302f..7dd86653f0 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -87,6 +87,7 @@ typedef struct CPUArchState CPUMBState;
 #define          ESR_ESS_FSL_OFFSET     5
 
 #define          ESR_ESS_MASK  (0x7f << 5)
+#define          ESR_ESS_DEC_OF  (1 << 20) /* DEC: 0=DBZ, 1=OF */
 
 #define          ESR_EC_FSL             0
 #define          ESR_EC_UNALIGNED_DATA  1
diff --git a/target/microblaze/op_helper.c b/target/microblaze/op_helper.c
index d9444aee29..e5f13824d8 100644
--- a/target/microblaze/op_helper.c
+++ b/target/microblaze/op_helper.c
@@ -89,6 +89,21 @@ uint32_t helper_divs(CPUMBState *env, uint32_t ra, uint32_t rb)
         raise_divzero(env, ESR_EC_DIVZERO, GETPC());
         return 0;
     }
+
+    /*
+     * Check for division overflows.
+     *
+     * Spec: https://docs.amd.com/r/en-US/ug984-vivado-microblaze-ref/idiv
+     * UG984, Chapter 5 MicroBlaze Instruction Set Architecture, idiv.
+     *
+     * If the U bit is clear, the value of rA is -1, and the value of rB is
+     * -2147483648 (divide overflow), the DZO bit in MSR will be set and
+     * the value in rD will be -2147483648, unless an exception is generated.
+     */
+    if ((int32_t)ra == -1 && (int32_t)rb == INT32_MIN) {
+        raise_divzero(env, ESR_EC_DIVZERO | ESR_ESS_DEC_OF, GETPC());
+        return INT32_MIN;
+    }
     return (int32_t)rb / (int32_t)ra;
 }
 
-- 
2.43.0
Re: [PATCH v1 4/4] target/microblaze: Handle signed division overflows
Posted by Richard Henderson 2 months, 3 weeks ago
On 8/25/25 08:27, Edgar E. Iglesias wrote:
> From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
> 
> Handle signed division overflows as specified in UG984:
> https://docs.amd.com/r/en-US/ug984-vivado-microblaze-ref/idiv
> 
> Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
> ---
>   target/microblaze/cpu.h       |  1 +
>   target/microblaze/op_helper.c | 15 +++++++++++++++
>   2 files changed, 16 insertions(+)
> 
> diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
> index 3ce28b302f..7dd86653f0 100644
> --- a/target/microblaze/cpu.h
> +++ b/target/microblaze/cpu.h
> @@ -87,6 +87,7 @@ typedef struct CPUArchState CPUMBState;
>   #define          ESR_ESS_FSL_OFFSET     5
>   
>   #define          ESR_ESS_MASK  (0x7f << 5)
> +#define          ESR_ESS_DEC_OF  (1 << 20) /* DEC: 0=DBZ, 1=OF */

That's bit 20 big-endian, so bit (1 << 11).

Otherwise,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~
Re: [PATCH v1 4/4] target/microblaze: Handle signed division overflows
Posted by Edgar E. Iglesias 2 months, 3 weeks ago
On Mon, Aug 25, 2025 at 09:44:34AM +1000, Richard Henderson wrote:
> On 8/25/25 08:27, Edgar E. Iglesias wrote:
> > From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
> > 
> > Handle signed division overflows as specified in UG984:
> > https://docs.amd.com/r/en-US/ug984-vivado-microblaze-ref/idiv
> > 
> > Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
> > ---
> >   target/microblaze/cpu.h       |  1 +
> >   target/microblaze/op_helper.c | 15 +++++++++++++++
> >   2 files changed, 16 insertions(+)
> > 
> > diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
> > index 3ce28b302f..7dd86653f0 100644
> > --- a/target/microblaze/cpu.h
> > +++ b/target/microblaze/cpu.h
> > @@ -87,6 +87,7 @@ typedef struct CPUArchState CPUMBState;
> >   #define          ESR_ESS_FSL_OFFSET     5
> >   #define          ESR_ESS_MASK  (0x7f << 5)
> > +#define          ESR_ESS_DEC_OF  (1 << 20) /* DEC: 0=DBZ, 1=OF */
> 
> That's bit 20 big-endian, so bit (1 << 11).

Fixed for v2, thanks!

> 
> Otherwise,
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
> 
> 
> r~