CRIS: Add support for __builtin_clz.

Hans-Peter Nilsson hans-peter.nilsson@axis.com
Mon Sep 3 01:23:00 GMT 2007


> Date: Sat, 1 Sep 2007 14:13:51 +0200
> From: Hans-Peter Nilsson <hp@axis.com>

> I'll just run an extra round of regtesting with
> RUNTESTFLAGS=--target_board=cris-sim\{,-march=v3,-march=v8,-march=v10\}
> and then hopefully check it in with those changes.

It's unfortunately undocumented that libgcc won't use the new and
improved clz until you define count_leading_zeros, but quite obvious
once you read libgcc2.c:__clzSI2 and I just had to fix that.  The
format of the target name and the containing comment wasn't the
official ones so I corrected them.  The builtin_clz_v3.c as originally
submitted used -march=v8 instead of -march=v3, so to avoid confusion I
fixed that too, but only after I'd committed the first version;
however the tweak does not warrant its own changelog entry, see the
GNU standard.  Altogether, the changes warranted posting this final
version.

No regressions with cross to cris-elf and testing with
'RUNTESTFLAGS=--target_board=cris-sim\{,-march=v3,-march=v8,-march=v10\}'
with the last mentioned tweak tested separately, and observing that
libgcc.a uses lz also in functions outside those from arit.c.

gcc:
	* config/cris/cris.h (TARGET_HAS_LZ, CLZ_DEFINED_VALUE_AT_ZERO):
	Defined to describe availability and behavior of CLZ.
	* config/cris/cris.md (clzsi2): Implement using lz instruction.
	* config/cris/cris.opt: Tweak comment for "-metrax4".
	* config/cris/arit.c (LZ): When defined, define as __builtin_clz.
	* longlong.h [__CRIS__ && __CRIS_arch_version >= 3]
	(count_leading_zeros): Define.

gcc/testsuite:
	* gcc.target/cris/builtin_clz_v0.c: New testcase.
	* gcc.target/cris/builtin_clz_v3.c: New testcase.


Index: testsuite/gcc.target/cris/builtin_clz_v0.c
===================================================================
--- testsuite/gcc.target/cris/builtin_clz_v0.c	(revision 0)
+++ testsuite/gcc.target/cris/builtin_clz_v0.c	(revision 0)
@@ -0,0 +1,12 @@
+/* Check that we don't use the lz insn for clz by checking assembler output.
+   The lz insn was implemented in CRIS v3 (ETRAX 4).  */
+/* { dg-do compile } */
+/* { dg-skip-if "" { "cris-*-elf" } { "-march*" } { "" } } */
+/* { dg-options "-O2 -march=v0" } */
+/* { dg-final { scan-assembler-not "\[ \t\]lz\[ \t\]" } } */
+
+int
+f (int a)
+{
+	return __builtin_clz(a);
+}
Index: testsuite/gcc.target/cris/builtin_clz_v3.c
===================================================================
--- testsuite/gcc.target/cris/builtin_clz_v3.c	(revision 0)
+++ testsuite/gcc.target/cris/builtin_clz_v3.c	(revision 0)
@@ -0,0 +1,12 @@
+/* Check that we use the lz insn for clz by checking assembler output.
+   The lz insn was implemented in CRIS v3 (ETRAX 4).  */
+/* { dg-do compile } */
+/* { dg-skip-if "" { "cris-*-elf" } { "-march*" } { "" } } */
+/* { dg-options "-O2 -march=v3" } */
+/* { dg-final { scan-assembler "\[ \t\]lz\[ \t\]" } } */
+
+int
+f (int a)
+{
+	return __builtin_clz(a);
+}
Index: longlong.h
===================================================================
--- longlong.h	(revision 128032)
+++ longlong.h	(working copy)
@@ -226,6 +226,10 @@ UDItype __umulsidi3 (USItype, USItype);
 #define UDIV_TIME 100
 #endif /* __arm__ */
 
+#if defined (__CRIS__) && __CRIS_arch_version >= 3
+#define count_leading_zeros(COUNT, X) ((COUNT) = __builtin_clz (X))
+#endif /* __CRIS__ */
+
 #if defined (__hppa) && W_TYPE_SIZE == 32
 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
   __asm__ ("add %4,%5,%1\n\taddc %2,%3,%0"				\
Index: config/cris/arit.c
===================================================================
--- config/cris/arit.c	(revision 128032)
+++ config/cris/arit.c	(working copy)
@@ -48,8 +48,7 @@ Boston, MA 02110-1301, USA.
 #include "config.h"
 
 #if defined (__CRIS_arch_version) && __CRIS_arch_version >= 3
-#define LZ(v) __extension__ \
- ({ int tmp_; __asm__ ("lz %1,%0" : "=r" (tmp_) : "r" (v)); tmp_; })
+#define LZ(v) __builtin_clz (v)
 #endif
 
 
Index: config/cris/cris.h
===================================================================
--- config/cris/cris.h	(revision 128032)
+++ config/cris/cris.h	(working copy)
@@ -278,6 +278,7 @@ extern int target_flags;
 #define CRIS_DEFAULT_CPU_VERSION CRIS_CPU_BASE
 
 #define TARGET_HAS_MUL_INSNS (cris_cpu_version >= CRIS_CPU_NG)
+#define TARGET_HAS_LZ (cris_cpu_version >= CRIS_CPU_ETRAX4)
 
 #define CRIS_SUBTARGET_HANDLE_OPTION(x, y, z)
 
@@ -1407,6 +1408,8 @@ enum cris_pic_symbol_type
 
 #define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
 
+#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 32, 1)
+
 #define Pmode SImode
 
 #define FUNCTION_MODE QImode
Index: config/cris/cris.md
===================================================================
--- config/cris/cris.md	(revision 128032)
+++ config/cris/cris.md	(working copy)
@@ -2663,7 +2663,14 @@ (define_expand "abs<mode>2"
 	(subreg:BW (match_dup 3) 0))]
   ""
   "operands[2] = gen_reg_rtx (SImode); operands[3] = gen_reg_rtx (SImode);")
-
+
+(define_insn "clzsi2"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(clz:SI (match_operand:SI 1 "register_operand" "r")))]
+  "TARGET_HAS_LZ"
+  "lz %1,%0"
+  [(set_attr "slottable" "yes")])
+
 ;; Bound-insn.  Defined to be the same as an unsigned minimum, which is an
 ;; operation supported by gcc.  Used in casesi, but used now and then in
 ;; normal code too.
Index: config/cris/cris.opt
===================================================================
--- config/cris/cris.opt	(revision 128032)
+++ config/cris/cris.opt	(working copy)
@@ -45,7 +45,7 @@ Target Report Mask(MUL_BUG)
 Work around bug in multiplication instruction
 
 ; TARGET_ETRAX4_ADD: Instruction-set additions from Etrax 4 and up.
-; (Just "lz", which we don't really generate from GCC -- yet).
+; (Just "lz".)
 metrax4
 Target Report Mask(ETRAX4_ADD)
 Compile for ETRAX 4 (CRIS v3)

brgds, H-P



More information about the Gcc-patches mailing list