===================================================================
@@ -8203,6 +8203,21 @@ int __builtin_avr_fmuls (char, char)
int __builtin_avr_fmulsu (char, unsigned char)
@end smallexample
+The following built-in functions are a supplements to gcc's
+@code{__builtin_parity*} resp. @code{__builtin_popcount*} built-ins
+for 8-bit values and are implemented as library calls:
+@smallexample
+unsigned char __builtin_avr_parity8 (unsigned char)
+unsigned char __builtin_avr_popcount8 (unsigned char)
+@end smallexample
+
+@smallexample
+unsigned char __builtin_avr_pow2 (unsigned char)
+@end smallexample
+This built-in supplies a fast, loop-free implementation for the @var{N}-th
+power of two as of @code{1 << (N & 7)} that takes about seven ticks resp.
+seven instructions.
+
In order to delay execution for a specific number of cycles, GCC
implements
@smallexample
===================================================================
@@ -3321,6 +3321,62 @@ (define_insn "delay_cycles_4"
[(set_attr "length" "9")
(set_attr "cc" "clobber")])
+;; __builtin_avr_parity8
+(define_expand "parityqi2"
+ [(set (reg:QI 24)
+ (match_operand:QI 1 "register_operand" ""))
+ (set (reg:HI 24)
+ (zero_extend:HI (parity:QI (reg:QI 24))))
+ (set (match_operand:QI 0 "register_operand" "")
+ (reg:QI 24))]
+ ""
+ "")
+
+(define_insn "*parityqihi2.libgcc"
+ [(set (reg:HI 24)
+ (zero_extend:HI (parity:QI (reg:QI 24))))]
+ ""
+ "%~call __parityqi2"
+ [(set_attr "type" "xcall")
+ (set_attr "cc" "clobber")])
+
+;; __builtin_avr_popcount8
+(define_expand "popcountqi2"
+ [(set (reg:QI 24)
+ (match_operand:QI 1 "register_operand" ""))
+ (set (reg:QI 24)
+ (popcount:QI (reg:QI 24)))
+ (set (match_operand:QI 0 "register_operand" "")
+ (reg:QI 24))]
+ ""
+ "")
+
+(define_insn "*popcountqi2.libgcc"
+ [(set (reg:QI 24)
+ (popcount:QI (reg:QI 24)))]
+ ""
+ "%~call __popcountqi2"
+ [(set_attr "type" "xcall")
+ (set_attr "cc" "clobber")])
+
+;; __builtin_avr_pow2
+;; $0 = (1 << ($1 & 7))
+(define_insn "ashlqi2_1"
+ [(set (match_operand:QI 0 "register_operand" "=&d")
+ (ashift:QI (const_int 1)
+ (and:QI (match_operand:QI 1 "register_operand" "r")
+ (const_int 7))))]
+ ""
+ "ldi %0, 1
+ sbrc %1, 1
+ ldi %0, 4
+ sbrc %1, 0
+ lsl %0
+ sbrc %1, 2
+ swap %0"
+ [(set_attr "length" "7")
+ (set_attr "cc" "clobber")])
+
;; CPU instructions
;; NOP taking 1 or 2 Ticks
===================================================================
@@ -93,6 +93,9 @@ avr_cpu_cpp_builtins (struct cpp_reader
cpp_define (pfile, "__BUILTIN_AVR_SLEEP");
cpp_define (pfile, "__BUILTIN_AVR_SWAP");
cpp_define (pfile, "__BUILTIN_AVR_DELAY_CYCLES");
+ cpp_define (pfile, "__BUILTIN_AVR_PARITY8");
+ cpp_define (pfile, "__BUILTIN_AVR_POPCOUNT8");
+ cpp_define (pfile, "__BUILTIN_AVR_POW2");
if (AVR_HAVE_MUL)
{
===================================================================
@@ -4740,9 +4740,11 @@ adjust_insn_length (rtx insn, int len)
break;
}
}
- else if (GET_CODE (op[1]) == ASHIFT
- || GET_CODE (op[1]) == ASHIFTRT
- || GET_CODE (op[1]) == LSHIFTRT)
+ else if ((GET_CODE (op[1]) == ASHIFT
+ || GET_CODE (op[1]) == ASHIFTRT
+ || GET_CODE (op[1]) == LSHIFTRT)
+ /* Filter out "ashlqi2_1" */
+ && AND != GET_CODE (XEXP (op[1], 1)))
{
rtx ops[10];
ops[0] = op[0];
@@ -6614,7 +6616,10 @@ enum avr_builtin_id
AVR_BUILTIN_FMUL,
AVR_BUILTIN_FMULS,
AVR_BUILTIN_FMULSU,
- AVR_BUILTIN_DELAY_CYCLES
+ AVR_BUILTIN_DELAY_CYCLES,
+ AVR_BUILTIN_PARITY8,
+ AVR_BUILTIN_POPCOUNT8,
+ AVR_BUILTIN_POW2
};
#define DEF_BUILTIN(NAME, TYPE, CODE) \
@@ -6665,6 +6670,12 @@ avr_init_builtins (void)
DEF_BUILTIN ("__builtin_avr_swap", uchar_ftype_uchar, AVR_BUILTIN_SWAP);
DEF_BUILTIN ("__builtin_avr_delay_cycles", void_ftype_ulong,
AVR_BUILTIN_DELAY_CYCLES);
+ DEF_BUILTIN ("__builtin_avr_parity8", uchar_ftype_uchar,
+ AVR_BUILTIN_PARITY8);
+ DEF_BUILTIN ("__builtin_avr_popcount8", uchar_ftype_uchar,
+ AVR_BUILTIN_POPCOUNT8);
+ DEF_BUILTIN ("__builtin_avr_pow2", uchar_ftype_uchar,
+ AVR_BUILTIN_POW2);
if (AVR_HAVE_MUL)
{
@@ -6694,6 +6705,9 @@ static const struct avr_builtin_descript
bdesc_1arg[] =
{
{ CODE_FOR_rotlqi3_4, "__builtin_avr_swap", AVR_BUILTIN_SWAP }
+ , { CODE_FOR_parityqi2, "__builtin_avr_parity8", AVR_BUILTIN_PARITY8 }
+ , { CODE_FOR_popcountqi2, "__builtin_avr_popcount8", AVR_BUILTIN_POPCOUNT8 }
+ , { CODE_FOR_ashlqi2_1, "__builtin_avr_pow2", AVR_BUILTIN_POW2 }
};
static const struct avr_builtin_description