diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5d15a621f76..cd17c1f6019 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2007-09-06 Jesper Nilsson + + * longlong.h [__CRIS_arch_version >= 8] (count_trailing_zeros): + Defined. + * config/cris/cris.md (ctzsi2, cris_swap_bits): Implemented. + * config/cris/cris.h (CTZ_DEFINED_VALUE_AT_ZERO): Defined. + 2007-09-06 Jie Zhang * config.gcc (tm_file): Add linux.h for bfin*-uclinux*. diff --git a/gcc/config/cris/cris.h b/gcc/config/cris/cris.h index 7a2f714586e..3dd0dbd9511 100644 --- a/gcc/config/cris/cris.h +++ b/gcc/config/cris/cris.h @@ -1410,6 +1410,7 @@ enum cris_pic_symbol_type #define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1 #define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 32, 1) +#define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 32, 1) #define Pmode SImode diff --git a/gcc/config/cris/cris.md b/gcc/config/cris/cris.md index 765bd8602c4..e248d4307ed 100644 --- a/gcc/config/cris/cris.md +++ b/gcc/config/cris/cris.md @@ -69,7 +69,8 @@ (CRIS_UNSPEC_GOT 2) (CRIS_UNSPEC_GOTREL 3) (CRIS_UNSPEC_GOTREAD 4) - (CRIS_UNSPEC_PLTGOTREAD 5)]) + (CRIS_UNSPEC_PLTGOTREAD 5) + (CRIS_UNSPEC_SWAP_BITS 6)]) ;; Register numbers. (define_constants @@ -2678,6 +2679,31 @@ "swapwb %0" [(set_attr "slottable" "yes")]) +;; This instruction swaps all bits in a register. +;; That means that the most significant bit is put in the place +;; of the least significant bit, and so on. + +(define_insn "cris_swap_bits" + [(set (match_operand:SI 0 "register_operand" "=r") + (unspec:SI [(match_operand:SI 1 "register_operand" "0")] + CRIS_UNSPEC_SWAP_BITS))] + "TARGET_HAS_SWAP" + "swapwbr %0" + [(set_attr "slottable" "yes")]) + +;; Implement ctz using two instructions, one for bit swap and one for clz. +;; Defines a scratch register to avoid clobbering input. + +(define_expand "ctzsi2" + [(set (match_dup 2) + (match_operand:SI 1 "register_operand")) + (set (match_dup 2) + (unspec:SI [(match_dup 2)] CRIS_UNSPEC_SWAP_BITS)) + (set (match_operand:SI 0 "register_operand") + (clz:SI (match_dup 2)))] + "TARGET_HAS_LZ && TARGET_HAS_SWAP" + "operands[2] = gen_reg_rtx (SImode);") + ;; 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. diff --git a/gcc/longlong.h b/gcc/longlong.h index edb9bfd5f35..8350fbc2b45 100644 --- a/gcc/longlong.h +++ b/gcc/longlong.h @@ -228,6 +228,9 @@ UDItype __umulsidi3 (USItype, USItype); #if defined (__CRIS__) && __CRIS_arch_version >= 3 #define count_leading_zeros(COUNT, X) ((COUNT) = __builtin_clz (X)) +#if __CRIS_arch_version >= 8 +#define count_trailing_zeros(COUNT, X) ((COUNT) = __builtin_ctz (X)) +#endif #endif /* __CRIS__ */ #if defined (__hppa) && W_TYPE_SIZE == 32