From: Georg-Johann Lay <avr@gjlay.de>
To: gcc-patches@gcc.gnu.org
Cc: Denis Chertykov <chertykov@gmail.com>,
Anatoly Sokolov <aesok@post.ru>,
"Eric B. Weddington" <eric.weddington@atmel.com>
Subject: [Patch, AVR]: QI builtins for parity, popcount, 1<< n
Date: Thu, 16 Jun 2011 16:08:00 -0000 [thread overview]
Message-ID: <4DFA26FE.1000400@gjlay.de> (raw)
[-- Attachment #1: Type: text/plain, Size: 1196 bytes --]
The recent implementation of some asm function in libgcc added
__popcountqi2 and __parityqi2. This patch makes these functions
available as __builtin_avr_popcount8 resp. __builtin_avr_parity8.
Moreover, just out of a mood, I wrote a builtin for 1<<n.
1<<n is sometimes used to set a variable SFR bit. The builtin supplies
a fast, loop-free implementation.
The nice thing is that all these can represented explicitly so that
gcc sees what's going on and can fold if it sees operation on a
compile time constant.
Johann
* config/avr/avr.c (avr_init_builtins, avr_builtin_id,
bdesc_1arg): Add support for __builtin_avr_parity8,
__builtin_avr_popcount8, __builtin_avr_pow2.
(adjust_insn_length): Filter out "ashlqi2_1" insn in length
computation.
* config/avr/avr.c (avr_cpu_cpp_builtins): New builtin defines for
__BUILTIN_AVR_PARITY8, __BUILTIN_AVR_POPCOUNT8, __BUILTIN_AVR_POW2.
* config/avr/avr.md (parityqi2): New expander.
(popcountqi2): New expander.
(*parityqihi2.libgcc): New insn.
(*popcountqi2.libgcc): New insn.
(ashlqi2_1): New insn.
* doc/extend.texi (AVR Built-in Functions): Document new builtins
__builtin_avr_parity8, __builtin_avr_popcount8,
__builtin_avr_pow2.
[-- Attachment #2: builtin-pop.diff --]
[-- Type: text/x-patch, Size: 5232 bytes --]
Index: doc/extend.texi
===================================================================
--- doc/extend.texi (Revision 175104)
+++ doc/extend.texi (Arbeitskopie)
@@ -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
Index: config/avr/avr.md
===================================================================
--- config/avr/avr.md (Revision 175104)
+++ config/avr/avr.md (Arbeitskopie)
@@ -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
Index: config/avr/avr-c.c
===================================================================
--- config/avr/avr-c.c (Revision 175104)
+++ config/avr/avr-c.c (Arbeitskopie)
@@ -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)
{
Index: config/avr/avr.c
===================================================================
--- config/avr/avr.c (Revision 175104)
+++ config/avr/avr.c (Arbeitskopie)
@@ -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
next reply other threads:[~2011-06-16 15:54 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-06-16 16:08 Georg-Johann Lay [this message]
2011-06-16 17:08 ` Joseph S. Myers
2011-06-17 11:04 ` Georg-Johann Lay
2011-06-17 13:06 ` Joseph S. Myers
2011-06-17 19:03 ` Georg-Johann Lay
2011-06-17 19:14 ` Georg-Johann Lay
2011-06-20 10:53 ` Joseph S. Myers
2011-06-20 14:31 ` Georg-Johann Lay
2011-06-20 15:39 ` Richard Henderson
2011-06-20 16:52 ` Georg-Johann Lay
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4DFA26FE.1000400@gjlay.de \
--to=avr@gjlay.de \
--cc=aesok@post.ru \
--cc=chertykov@gmail.com \
--cc=eric.weddington@atmel.com \
--cc=gcc-patches@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).