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
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~
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~
© 2016 - 2025 Red Hat, Inc.