This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 7/7] [NDS32] Fix nds32_split_ashiftdi3 with large shift amount


From: Kito Cheng <kito.cheng@gmail.com>

Kito Cheng  <kito.cheng@gmail.com>
Shiva Chen  <shiva0217@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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]