LGTM.

Kito Cheng <k...@andestech.com> 於 2019年3月26日 週二 下午1:29寫道:

> From: Kito Cheng <kito.ch...@gmail.com>
>
> Kito Cheng  <kito.ch...@gmail.com>
> Shiva Chen  <shiva0...@gmail.com>
>
> ChangeLog:
> gcc/
>         * config/nds32/nds32-md-auxiliary.c (nds32_split_ashiftdi3):
>         Fix wrong code gen with large shift amount.
>
> gcc/testsuite/
>         * gcc.target/nds32/ashiftdi3.c: New.
> ---
>  gcc/config/nds32/nds32-md-auxiliary.c      | 21 ++++++++++++++-------
>  gcc/testsuite/gcc.target/nds32/ashiftdi3.c | 23 +++++++++++++++++++++++
>  2 files changed, 37 insertions(+), 7 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/nds32/ashiftdi3.c
>
> diff --git a/gcc/config/nds32/nds32-md-auxiliary.c
> b/gcc/config/nds32/nds32-md-auxiliary.c
> index 35fcc64..eadd841 100644
> --- a/gcc/config/nds32/nds32-md-auxiliary.c
> +++ b/gcc/config/nds32/nds32-md-auxiliary.c
> @@ -3304,15 +3304,22 @@ nds32_split_ashiftdi3 (rtx dst, rtx src, rtx
> shiftamount)
>        ext_start = gen_reg_rtx (SImode);
>
>        /*
> -        if (shiftamount < 32)
> +        # In fact, we want to check shift amonut is great than or equal
> 32,
> +        # but in some corner case, the shift amount might be very large
> value,
> +        # however we've defined SHIFT_COUNT_TRUNCATED, so GCC think we've
> +        # handle that correctly without any truncate.
> +        # so check the the condition of (shiftamount & 32) is most
> +        # safe way to do.
> +        if (shiftamount & 32)
> +          dst_low_part = 0
> +          dst_high_part = src_low_part << shiftamount & 0x1f
> +        else
>            dst_low_part = src_low_part << shiftamout
>            dst_high_part = wext (src, 32 - shiftamount)
>            # wext can't handle wext (src, 32) since it's only take rb[0:4]
>            # for extract.
>            dst_high_part = shiftamount == 0 ? src_high_part : dst_high_part
> -        else
> -          dst_low_part = 0
> -          dst_high_part = src_low_part << shiftamount & 0x1f
> +
>        */
>
>        emit_insn (gen_subsi3 (ext_start,
> @@ -3331,11 +3338,11 @@ nds32_split_ashiftdi3 (rtx dst, rtx src, rtx
> shiftamount)
>        emit_insn (gen_ashlsi3 (dst_high_part_g32, src_low_part,
>                                                  new_shift_amout));
>
> -      emit_insn (gen_slt_compare (select_reg, shiftamount, GEN_INT (32)));
> +      emit_insn (gen_andsi3 (select_reg, shiftamount, GEN_INT (32)));
>
> -      emit_insn (gen_cmovnsi (dst_low_part, select_reg,
> +      emit_insn (gen_cmovzsi (dst_low_part, select_reg,
>                               dst_low_part_l32, dst_low_part_g32));
> -      emit_insn (gen_cmovnsi (dst_high_part, select_reg,
> +      emit_insn (gen_cmovzsi (dst_high_part, select_reg,
>                               dst_high_part_l32, dst_high_part_g32));
>      }
>  }
> diff --git a/gcc/testsuite/gcc.target/nds32/ashiftdi3.c
> b/gcc/testsuite/gcc.target/nds32/ashiftdi3.c
> new file mode 100644
> index 0000000..e3faff5
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/nds32/ashiftdi3.c
> @@ -0,0 +1,23 @@
> +/* { dg-options "-mext-dsp" { target nds32 } } */
> +
> +#include<stdio.h>
> +extern void abort (void);
> +
> +unsigned long long int ull;
> +
> +unsigned long long int __attribute__ ((noinline))
> +foo (unsigned long long int a, unsigned long long int b)
> +{
> +  return a << b;
> +}
> +
> +int
> +main (void)
> +{
> +  unsigned long long shiftamt = 0x45806aca;
> +  ull = foo(0xfffffffff, shiftamt);
> +  if (ull != 70368744176640)
> +    abort ();
> +
> +  return 0;
> +}
> --
> 1.8.3.1
>
>

Reply via email to