[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v4 2/2] target-m68k: add 680x0 divu/divs variant
From: |
Laurent Vivier |
Subject: |
Re: [Qemu-devel] [PATCH v4 2/2] target-m68k: add 680x0 divu/divs variants |
Date: |
Sun, 27 Nov 2016 18:42:29 +0100 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.4.0 |
Hi,
I come back on some patches as I've been able to test some instructions
using RISU.
Le 01/11/2016 à 21:03, Laurent Vivier a écrit :
...
> --- a/target-m68k/op_helper.c
> +++ b/target-m68k/op_helper.c
> @@ -179,51 +184,178 @@ void HELPER(raise_exception)(CPUM68KState *env,
> uint32_t tt)
> raise_exception(env, tt);
> }
>
> -void HELPER(divu)(CPUM68KState *env, uint32_t word)
> +void HELPER(divuw)(CPUM68KState *env, int destr, uint32_t den)
> {
> - uint32_t num;
> - uint32_t den;
> - uint32_t quot;
> - uint32_t rem;
> + uint32_t num = env->dregs[destr];
> + uint32_t quot, rem;
>
> - num = env->div1;
> - den = env->div2;
> - /* ??? This needs to make sure the throwing location is accurate. */
> if (den == 0) {
> - raise_exception(env, EXCP_DIV0);
> + raise_exception_ra(env, EXCP_DIV0, GETPC());
> }
> quot = num / den;
> rem = num % den;
>
> - env->cc_v = (word && quot > 0xffff ? -1 : 0);
> + env->cc_c = 0; /* always cleared, even if overflow */
> + if (quot > 0xffff) {
> + env->cc_v = -1;
> + /* nothing else is modified */
> + /* real 68040 keeps Z and N on overflow,
> + * whereas documentation says "undefined"
> + */
> + return;
> + }
> + env->dregs[destr] = deposit32(quot, 16, 16, rem);
> env->cc_z = quot;
> env->cc_n = quot;
quot is here a 32bit, but the result is only the 16 lower bits, so I
think we should have
env->cc_z = (int16_t)quot;
env->cc_n = (int16_t)quot;
> + env->cc_v = 0;
> +}
> +
> +void HELPER(divsw)(CPUM68KState *env, int destr, int32_t den)
> +{
> + int32_t num = env->dregs[destr];
> + uint32_t quot, rem;
> +
> + if (den == 0) {
> + raise_exception_ra(env, EXCP_DIV0, GETPC());
> + }
> + quot = num / den;
> + rem = num % den;
> +
> + env->cc_c = 0; /* always cleared, even if overflow */
> + if (quot != (int16_t)quot) {
> + env->cc_v = -1;
> + /* nothing else is modified */
> + /* real 68040 keeps Z and N on overflow,
> + * whereas documentation says "undefined"
> + */
> + return;
> + }
> + env->dregs[destr] = deposit32(quot, 16, 16, rem);
> + env->cc_z = quot;
> + env->cc_n = quot;
Same here:
env->cc_z = (int16_t)quot;
env->cc_n = (int16_t)quot;
Thanks,
Laurent