From: Edgar E. Iglesias Date: Sun, 24 Aug 2025 19:37:32 +0000 (+0200) Subject: target/microblaze: Handle signed division overflows X-Git-Tag: v10.2.0-rc1~37^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=cfc1d54251d3b4c4cf21c4fa278c8aea2fe25a99;p=thirdparty%2Fqemu.git target/microblaze: Handle signed division overflows 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 Reviewed-by: Richard Henderson --- diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h index 14b107876a..d26b933b6d 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 d3f688e375..31da2c7c3a 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; }