* [PATCH v2 0/3] targets/microblaze: Handle signed division overflows
@ 2025-08-25 11:20 Edgar E. Iglesias
2025-08-25 11:20 ` [PATCH v2 1/3] target/microblaze: Remove unused arg from check_divz() Edgar E. Iglesias
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Edgar E. Iglesias @ 2025-08-25 11:20 UTC (permalink / raw)
To: qemu-devel; +Cc: richard.henderson, philmd, edgar.iglesias
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
First a few preparatory clean-ups followed by the detection and
contional exception of signed division overflow.
Spec:
https://docs.amd.com/r/en-US/ug984-vivado-microblaze-ref/idiv
Cheers,
Edgar
ChangeLog:
v1 -> v2:
* Fix ESR_ESS_DEC_OF from bit 20 (big-bit-endian) to 11 (little-bit-endian).
* Rename pc -> unwind_pc.
* Squash patches 2 and 3.
Edgar E. Iglesias (3):
target/microblaze: Remove unused arg from check_divz()
target/microblaze: div: Break out raise_divzero()
target/microblaze: Handle signed division overflows
target/microblaze/cpu.h | 1 +
target/microblaze/op_helper.c | 53 ++++++++++++++++++++++-------------
target/microblaze/translate.c | 12 ++------
3 files changed, 36 insertions(+), 30 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 1/3] target/microblaze: Remove unused arg from check_divz()
2025-08-25 11:20 [PATCH v2 0/3] targets/microblaze: Handle signed division overflows Edgar E. Iglesias
@ 2025-08-25 11:20 ` Edgar E. Iglesias
2025-08-25 12:50 ` Philippe Mathieu-Daudé
2025-08-25 11:20 ` [PATCH v2 2/3] target/microblaze: div: Break out raise_divzero() Edgar E. Iglesias
2025-08-25 11:20 ` [PATCH v2 3/3] target/microblaze: Handle signed division overflows Edgar E. Iglesias
2 siblings, 1 reply; 6+ messages in thread
From: Edgar E. Iglesias @ 2025-08-25 11:20 UTC (permalink / raw)
To: qemu-devel, Edgar E. Iglesias; +Cc: richard.henderson, philmd, edgar.iglesias
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
Remove unused arg from check_divz(). No functional change.
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/microblaze/op_helper.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/target/microblaze/op_helper.c b/target/microblaze/op_helper.c
index b8365b3b1d..470526ee92 100644
--- a/target/microblaze/op_helper.c
+++ b/target/microblaze/op_helper.c
@@ -69,7 +69,7 @@ void helper_raise_exception(CPUMBState *env, uint32_t index)
cpu_loop_exit(cs);
}
-static bool check_divz(CPUMBState *env, uint32_t a, uint32_t b, uintptr_t ra)
+static bool check_divz(CPUMBState *env, uint32_t b, uintptr_t ra)
{
if (unlikely(b == 0)) {
env->msr |= MSR_DZ;
@@ -89,7 +89,7 @@ static bool check_divz(CPUMBState *env, uint32_t a, uint32_t b, uintptr_t ra)
uint32_t helper_divs(CPUMBState *env, uint32_t a, uint32_t b)
{
- if (!check_divz(env, a, b, GETPC())) {
+ if (!check_divz(env, b, GETPC())) {
return 0;
}
return (int32_t)a / (int32_t)b;
@@ -97,7 +97,7 @@ uint32_t helper_divs(CPUMBState *env, uint32_t a, uint32_t b)
uint32_t helper_divu(CPUMBState *env, uint32_t a, uint32_t b)
{
- if (!check_divz(env, a, b, GETPC())) {
+ if (!check_divz(env, b, GETPC())) {
return 0;
}
return a / b;
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v2 2/3] target/microblaze: div: Break out raise_divzero()
2025-08-25 11:20 [PATCH v2 0/3] targets/microblaze: Handle signed division overflows Edgar E. Iglesias
2025-08-25 11:20 ` [PATCH v2 1/3] target/microblaze: Remove unused arg from check_divz() Edgar E. Iglesias
@ 2025-08-25 11:20 ` Edgar E. Iglesias
2025-08-25 12:53 ` Philippe Mathieu-Daudé
2025-08-25 11:20 ` [PATCH v2 3/3] target/microblaze: Handle signed division overflows Edgar E. Iglesias
2 siblings, 1 reply; 6+ messages in thread
From: Edgar E. Iglesias @ 2025-08-25 11:20 UTC (permalink / raw)
To: qemu-devel, Edgar E. Iglesias; +Cc: richard.henderson, philmd, edgar.iglesias
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
Break out raise_divzero() and take the opportunity to rename
and reorder function args to better match with spec and
pseudo code.
No functional change.
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/microblaze/op_helper.c | 38 +++++++++++++++++------------------
target/microblaze/translate.c | 12 ++---------
2 files changed, 20 insertions(+), 30 deletions(-)
diff --git a/target/microblaze/op_helper.c b/target/microblaze/op_helper.c
index 470526ee92..fbc9c8ca4f 100644
--- a/target/microblaze/op_helper.c
+++ b/target/microblaze/op_helper.c
@@ -69,38 +69,36 @@ void helper_raise_exception(CPUMBState *env, uint32_t index)
cpu_loop_exit(cs);
}
-static bool check_divz(CPUMBState *env, uint32_t b, uintptr_t ra)
+/* Raises ESR_EC_DIVZERO if exceptions are enabled. */
+static void raise_divzero(CPUMBState *env, uint32_t esr, uintptr_t unwind_pc)
{
- if (unlikely(b == 0)) {
- env->msr |= MSR_DZ;
-
- if ((env->msr & MSR_EE) &&
- env_archcpu(env)->cfg.div_zero_exception) {
- CPUState *cs = env_cpu(env);
-
- env->esr = ESR_EC_DIVZERO;
- cs->exception_index = EXCP_HW_EXCP;
- cpu_loop_exit_restore(cs, ra);
- }
- return false;
+ env->msr |= MSR_DZ;
+
+ if ((env->msr & MSR_EE) && env_archcpu(env)->cfg.div_zero_exception) {
+ CPUState *cs = env_cpu(env);
+
+ env->esr = esr;
+ cs->exception_index = EXCP_HW_EXCP;
+ cpu_loop_exit_restore(cs, unwind_pc);
}
- return true;
}
-uint32_t helper_divs(CPUMBState *env, uint32_t a, uint32_t b)
+uint32_t helper_divs(CPUMBState *env, uint32_t ra, uint32_t rb)
{
- if (!check_divz(env, b, GETPC())) {
+ if (!ra) {
+ raise_divzero(env, ESR_EC_DIVZERO, GETPC());
return 0;
}
- return (int32_t)a / (int32_t)b;
+ return (int32_t)rb / (int32_t)ra;
}
-uint32_t helper_divu(CPUMBState *env, uint32_t a, uint32_t b)
+uint32_t helper_divu(CPUMBState *env, uint32_t ra, uint32_t rb)
{
- if (!check_divz(env, b, GETPC())) {
+ if (!ra) {
+ raise_divzero(env, ESR_EC_DIVZERO, GETPC());
return 0;
}
- return a / b;
+ return rb / ra;
}
/* raise FPU exception. */
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index 5098a1db4d..2f5fd5c271 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -450,16 +450,8 @@ DO_TYPEA0_CFG(flt, use_fpu >= 2, true, gen_flt)
DO_TYPEA0_CFG(fint, use_fpu >= 2, true, gen_fint)
DO_TYPEA0_CFG(fsqrt, use_fpu >= 2, true, gen_fsqrt)
-/* Does not use ENV_WRAPPER3, because arguments are swapped as well. */
-static void gen_idiv(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
-{
- gen_helper_divs(out, tcg_env, inb, ina);
-}
-
-static void gen_idivu(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
-{
- gen_helper_divu(out, tcg_env, inb, ina);
-}
+ENV_WRAPPER3(gen_idiv, gen_helper_divs)
+ENV_WRAPPER3(gen_idivu, gen_helper_divu)
DO_TYPEA_CFG(idiv, use_div, true, gen_idiv)
DO_TYPEA_CFG(idivu, use_div, true, gen_idivu)
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v2 3/3] target/microblaze: Handle signed division overflows
2025-08-25 11:20 [PATCH v2 0/3] targets/microblaze: Handle signed division overflows Edgar E. Iglesias
2025-08-25 11:20 ` [PATCH v2 1/3] target/microblaze: Remove unused arg from check_divz() Edgar E. Iglesias
2025-08-25 11:20 ` [PATCH v2 2/3] target/microblaze: div: Break out raise_divzero() Edgar E. Iglesias
@ 2025-08-25 11:20 ` Edgar E. Iglesias
2 siblings, 0 replies; 6+ messages in thread
From: Edgar E. Iglesias @ 2025-08-25 11:20 UTC (permalink / raw)
To: qemu-devel, Edgar E. Iglesias; +Cc: richard.henderson, philmd, edgar.iglesias
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>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
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..c9bf9361db 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 << 11) /* 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 fbc9c8ca4f..c704233c8c 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
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v2 1/3] target/microblaze: Remove unused arg from check_divz()
2025-08-25 11:20 ` [PATCH v2 1/3] target/microblaze: Remove unused arg from check_divz() Edgar E. Iglesias
@ 2025-08-25 12:50 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 6+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-08-25 12:50 UTC (permalink / raw)
To: Edgar E. Iglesias, qemu-devel; +Cc: richard.henderson, edgar.iglesias
On 25/8/25 13:20, Edgar E. Iglesias wrote:
> From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
>
> Remove unused arg from check_divz(). No functional change.
>
> Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/microblaze/op_helper.c | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 2/3] target/microblaze: div: Break out raise_divzero()
2025-08-25 11:20 ` [PATCH v2 2/3] target/microblaze: div: Break out raise_divzero() Edgar E. Iglesias
@ 2025-08-25 12:53 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 6+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-08-25 12:53 UTC (permalink / raw)
To: Edgar E. Iglesias, qemu-devel; +Cc: richard.henderson, edgar.iglesias
On 25/8/25 13:20, Edgar E. Iglesias wrote:
> From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
>
> Break out raise_divzero() and take the opportunity to rename
> and reorder function args to better match with spec and
> pseudo code.
>
> No functional change.
>
> Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/microblaze/op_helper.c | 38 +++++++++++++++++------------------
> target/microblaze/translate.c | 12 ++---------
> 2 files changed, 20 insertions(+), 30 deletions(-)
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2025-08-25 12:54 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-25 11:20 [PATCH v2 0/3] targets/microblaze: Handle signed division overflows Edgar E. Iglesias
2025-08-25 11:20 ` [PATCH v2 1/3] target/microblaze: Remove unused arg from check_divz() Edgar E. Iglesias
2025-08-25 12:50 ` Philippe Mathieu-Daudé
2025-08-25 11:20 ` [PATCH v2 2/3] target/microblaze: div: Break out raise_divzero() Edgar E. Iglesias
2025-08-25 12:53 ` Philippe Mathieu-Daudé
2025-08-25 11:20 ` [PATCH v2 3/3] target/microblaze: Handle signed division overflows Edgar E. Iglesias
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).