qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH v2 3/5] target-m68k: Inline shifts


From: Laurent Vivier
Subject: Re: [Qemu-devel] [PATCH v2 3/5] target-m68k: Inline shifts
Date: Sun, 27 Nov 2016 18:53:16 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.4.0

Le 09/11/2016 à 14:46, Richard Henderson a écrit :
> diff --git a/target-m68k/translate.c b/target-m68k/translate.c
> index 4f224d7..1b3765f 100644
> --- a/target-m68k/translate.c
> +++ b/target-m68k/translate.c
> @@ -2883,48 +2883,205 @@ DISAS_INSN(addx_mem)
>      gen_store(s, opsize, addr_dest, QREG_CC_N);
>  }
>  
> -/* TODO: This could be implemented without helper functions.  */
> -DISAS_INSN(shift_im)
> +static inline void shift_im(DisasContext *s, uint16_t insn, int opsize)
>  {
> -    TCGv reg;
> -    int tmp;
> -    TCGv shift;
> +    int count = (insn >> 9) & 7;
> +    int logical = insn & 8;
> +    int left = insn & 0x100;
> +    int bits = opsize_bytes(opsize) * 8;
> +    TCGv reg = gen_extend(DREG(insn, 0), opsize, !logical);
> +
> +    if (count == 0) {
> +        count = 8;
> +    }
> +
> +    tcg_gen_movi_i32(QREG_CC_V, 0);
> +    if (left) {
> +        tcg_gen_shri_i32(QREG_CC_C, reg, bits - count);
> +        tcg_gen_shli_i32(QREG_CC_N, reg, count);
> +
> +        /* Note that ColdFire always clears V (done above),
> +           while M68000 sets if the most significant bit is changed at
> +           any time during the shift operation */
> +        if (!logical && m68k_feature(s->env, M68K_FEATURE_M68000)) {
> +            /* if shift count >= bits, V is (reg != 0) */
> +            if (count >= bits) {
> +                tcg_gen_setcond_i32(TCG_COND_NE, QREG_CC_V, reg, QREG_CC_V);
> +            } else {
> +                TCGv t0 = tcg_temp_new();
> +                tcg_gen_sari_i32(QREG_CC_V, reg, bits - 1);
> +                tcg_gen_sari_i32(t0, t0, bits - count);

t0 is used unitialized, I think we should have here:

                tcg_gen_sari_i32(t0, reg, bits - count - 1);

moreover we must use "bits - count - 1" to use also the current most
significant bit to compute V flag.

> +                tcg_gen_setcond_i32(TCG_COND_NE, QREG_CC_V, QREG_CC_V, t0);
> +                tcg_temp_free(t0);
> +            }
> +            tcg_gen_neg_i32(QREG_CC_V, QREG_CC_V);
> +        }
> +    } else {
> +        tcg_gen_shri_i32(QREG_CC_C, reg, count - 1);
> +        if (logical) {
> +            tcg_gen_shri_i32(QREG_CC_N, reg, count);
> +        } else {
> +            tcg_gen_sari_i32(QREG_CC_N, reg, count);
> +        }
> +    }

Thanks,
Laurent




reply via email to

[Prev in Thread] Current Thread [Next in Thread]