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