Xilinx queue

-----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEErET+3BT38evtv0FRKcWWeA9ryoMFAmkCDzgACgkQKcWWeA9r
 yoMxwAf/YRf8aNwn8+4MRAn5vuNI/Hyh75/Mu5m007fqU/gLEZxxzJQ0Jxrc5Oot
 tNqGBGnVsRmH7i7Kkn+Ch4GOozIEJkXmqeQ3brmCg1VvSgi2vtqvS9F3SK8U3I6j
 pavSC04KOtu33jlN63ObU+aAD/o5gLVwl2wAk+w0SWnnN4IhvPOilO7+ZeF5Lueh
 GH57sh9DRnMYJl4mOj5z5NDsgZhdnmjpvAkvWBI9cQ7uwhGXLk0lCu0+lJ25tr3T
 NAg6N4S94rCm0eaMKL79BHPuG59G3A5G8SOjn6pXkT2aYaaeHpqu2DcuFJsSsVxV
 4CTignh5SVwICueFF4Z3RF5iZGHIDw==
 =ua+I
 -----END PGP SIGNATURE-----

Merge tag 'edgar/xilinx-queue-2025-10-29.for-upstream' of https://gitlab.com/edgar.iglesias/qemu into staging

Xilinx queue

# -----BEGIN PGP SIGNATURE-----
#
# iQEzBAABCgAdFiEErET+3BT38evtv0FRKcWWeA9ryoMFAmkCDzgACgkQKcWWeA9r
# yoMxwAf/YRf8aNwn8+4MRAn5vuNI/Hyh75/Mu5m007fqU/gLEZxxzJQ0Jxrc5Oot
# tNqGBGnVsRmH7i7Kkn+Ch4GOozIEJkXmqeQ3brmCg1VvSgi2vtqvS9F3SK8U3I6j
# pavSC04KOtu33jlN63ObU+aAD/o5gLVwl2wAk+w0SWnnN4IhvPOilO7+ZeF5Lueh
# GH57sh9DRnMYJl4mOj5z5NDsgZhdnmjpvAkvWBI9cQ7uwhGXLk0lCu0+lJ25tr3T
# NAg6N4S94rCm0eaMKL79BHPuG59G3A5G8SOjn6pXkT2aYaaeHpqu2DcuFJsSsVxV
# 4CTignh5SVwICueFF4Z3RF5iZGHIDw==
# =ua+I
# -----END PGP SIGNATURE-----
# gpg: Signature made Wed 29 Oct 2025 01:57:28 PM CET
# gpg:                using RSA key AC44FEDC14F7F1EBEDBF415129C596780F6BCA83
# gpg: Good signature from "Edgar E. Iglesias (Xilinx key) <edgar.iglesias@xilinx.com>" [unknown]
# gpg:                 aka "Edgar E. Iglesias <edgar.iglesias@gmail.com>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: AC44 FEDC 14F7 F1EB EDBF  4151 29C5 9678 0F6B CA83

* tag 'edgar/xilinx-queue-2025-10-29.for-upstream' of https://gitlab.com/edgar.iglesias/qemu:
  target/microblaze: Handle signed division overflows
  target/microblaze: div: Break out raise_divzero()
  target/microblaze: Remove unused arg from check_divz()

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2025-10-30 09:24:48 +01:00
commit 12688b0037
3 changed files with 34 additions and 28 deletions

View file

@ -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

View file

@ -69,38 +69,51 @@ 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)
/* 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;
env->msr |= MSR_DZ;
if ((env->msr & MSR_EE) &&
env_archcpu(env)->cfg.div_zero_exception) {
CPUState *cs = env_cpu(env);
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->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, a, b, GETPC())) {
if (!ra) {
raise_divzero(env, ESR_EC_DIVZERO, GETPC());
return 0;
}
return (int32_t)a / (int32_t)b;
/*
* 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;
}
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, a, b, GETPC())) {
if (!ra) {
raise_divzero(env, ESR_EC_DIVZERO, GETPC());
return 0;
}
return a / b;
return rb / ra;
}
/* raise FPU exception. */

View file

@ -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)