diff options
author | belagod <belagod@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-06-18 10:43:03 +0000 |
---|---|---|
committer | belagod <belagod@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-06-18 10:43:03 +0000 |
commit | 65729bd00fb53c449d0db1ab1a23fe24d56f0e8a (patch) | |
tree | 3f348986a905d10f6625171379da020acb5abe77 /gcc | |
parent | fe26539668cdc56eb8ce1550f83909a811523d15 (diff) | |
download | gcc-65729bd00fb53c449d0db1ab1a23fe24d56f0e8a.tar.gz |
Implement support for int iterators.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@188726 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/doc/md.texi | 78 | ||||
-rw-r--r-- | gcc/read-rtl.c | 45 |
3 files changed, 131 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index be59b02de53..2f8e62dd32e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2012-06-18 Tejas Belagod <tejas.belagod@arm.com> + + * doc/md.texi: Document int iterators. + * read-rtl.c (ints): New iterator group. + (find_int): Int iterator group callback. + (apply_int_iterator): Likewise. + (apply_iterators): Traverse int iterator table and add all the used + iterators to list. + (initialize_iterators): Initialize data structures and callbacks for int + iterators. + (read_rtx): Parse and read mappings for int iterators. + (read_rtx_code): Record int iterator usage. + 2012-06-18 Richard Sandiford <rdsandiford@googlemail.com> PR middle-end/53698 diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index 50fa2f9d2a5..c71c59cef06 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -8895,6 +8895,7 @@ facilities to make this process easier. @menu * Mode Iterators:: Generating variations of patterns for different modes. * Code Iterators:: Doing the same for codes. +* Int Iterators:: Doing the same for integers. @end menu @node Mode Iterators @@ -9166,4 +9167,81 @@ This is equivalent to: @dots{} @end smallexample +@node Int Iterators +@subsection Int Iterators +@cindex int iterators in @file{.md} files +@findex define_int_iterator +@findex define_int_attr + +Int iterators operate in a similar way to code iterators. @xref{Code Iterators}. + +The construct: + +@smallexample +(define_int_iterator @var{name} [(@var{int1} "@var{cond1}") @dots{} (@var{intn} "@var{condn}")]) +@end smallexample + +defines a pseudo integer constant @var{name} that can be instantiated as +@var{inti} if condition @var{condi} is true. Each @var{int} +must have the same rtx format. @xref{RTL Classes}. Int iterators can appear +in only those rtx fields that have 'i' as the specifier. This means that +each @var{int} has to be a constant defined using define_constant or +define_c_enum. + +As with mode and code iterators, each pattern that uses @var{name} will be +expanded @var{n} times, once with all uses of @var{name} replaced by +@var{int1}, once with all uses replaced by @var{int2}, and so on. +@xref{Defining Mode Iterators}. + +It is possible to define attributes for ints as well as for codes and modes. +Attributes are defined using: + +@smallexample +(define_int_attr @var{name} [(@var{int1} "@var{value1}") @dots{} (@var{intn} "@var{valuen}")]) +@end smallexample + +Here's an example of int iterators in action, taken from the ARM port: + +@smallexample +(define_int_iterator QABSNEG [UNSPEC_VQABS UNSPEC_VQNEG]) + +(define_int_attr absneg [(UNSPEC_VQABS "abs") (UNSPEC_VQNEG "neg")]) + +(define_insn "neon_vq<absneg><mode>" + [(set (match_operand:VDQIW 0 "s_register_operand" "=w") + (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w") + (match_operand:SI 2 "immediate_operand" "i")] + QABSNEG))] + "TARGET_NEON" + "vq<absneg>.<V_s_elem>\t%<V_reg>0, %<V_reg>1" + [(set_attr "neon_type" "neon_vqneg_vqabs")] +) + +@end smallexample + +This is equivalent to: + +@smallexample +(define_insn "neon_vqabs<mode>" + [(set (match_operand:VDQIW 0 "s_register_operand" "=w") + (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w") + (match_operand:SI 2 "immediate_operand" "i")] + UNSPEC_VQABS))] + "TARGET_NEON" + "vqabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1" + [(set_attr "neon_type" "neon_vqneg_vqabs")] +) + +(define_insn "neon_vqneg<mode>" + [(set (match_operand:VDQIW 0 "s_register_operand" "=w") + (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w") + (match_operand:SI 2 "immediate_operand" "i")] + UNSPEC_VQNEG))] + "TARGET_NEON" + "vqneg.<V_s_elem>\t%<V_reg>0, %<V_reg>1" + [(set_attr "neon_type" "neon_vqneg_vqabs")] +) + +@end smallexample + @end ifset diff --git a/gcc/read-rtl.c b/gcc/read-rtl.c index c588722a4ec..71ecf537642 100644 --- a/gcc/read-rtl.c +++ b/gcc/read-rtl.c @@ -114,7 +114,7 @@ static rtx read_nested_rtx (void); static rtx read_rtx_variadic (rtx); /* The mode and code iterator structures. */ -static struct iterator_group modes, codes; +static struct iterator_group modes, codes, ints; /* All iterators used in the current rtx. */ static VEC (mapping_ptr, heap) *current_iterators; @@ -165,6 +165,25 @@ apply_code_iterator (void *loc, int code) PUT_CODE ((rtx) loc, (enum rtx_code) code); } +/* Implementations of the iterator_group callbacks for ints. */ + +/* Since GCC does not construct a table of valid constants, + we have to accept any int as valid. No cross-checking can + be done. */ + +static int +find_int (const char *name) +{ + validate_const_int (name); + return atoi (name); +} + +static void +apply_int_iterator (void *loc, int value) +{ + *(int *)loc = value; +} + /* Map attribute string P to its current value. Return null if the attribute isn't known. */ @@ -412,6 +431,7 @@ apply_iterators (rtx original, rtx *queue) definition order within each group. */ htab_traverse (modes.iterators, add_current_iterators, NULL); htab_traverse (codes.iterators, add_current_iterators, NULL); + htab_traverse (ints.iterators, add_current_iterators, NULL); gcc_assert (!VEC_empty (mapping_ptr, current_iterators)); for (;;) @@ -518,6 +538,12 @@ initialize_iterators (void) codes.find_builtin = find_code; codes.apply_iterator = apply_code_iterator; + ints.attrs = htab_create (13, leading_string_hash, leading_string_eq_p, 0); + ints.iterators = htab_create (13, leading_string_hash, + leading_string_eq_p, 0); + ints.find_builtin = find_int; + ints.apply_iterator = apply_int_iterator; + lower = add_mapping (&modes, modes.attrs, "mode"); upper = add_mapping (&modes, modes.attrs, "MODE"); lower_ptr = &lower->values; @@ -827,6 +853,16 @@ read_rtx (const char *rtx_name, rtx *x) check_code_iterator (read_mapping (&codes, codes.iterators)); return false; } + if (strcmp (rtx_name, "define_int_attr") == 0) + { + read_mapping (&ints, ints.attrs); + return false; + } + if (strcmp (rtx_name, "define_int_iterator") == 0) + { + read_mapping (&ints, ints.iterators); + return false; + } apply_iterators (read_rtx_code (rtx_name), &queue_head); VEC_truncate (iterator_use, iterator_uses, 0); @@ -850,7 +886,6 @@ read_rtx_code (const char *code_name) struct md_name name; rtx return_rtx; int c; - int tmp_int; HOST_WIDE_INT tmp_wide; /* Linked list structure for making RTXs: */ @@ -1026,10 +1061,10 @@ read_rtx_code (const char *code_name) case 'i': case 'n': + /* Can be an iterator or an integer constant. */ read_name (&name); - validate_const_int (name.string); - tmp_int = atoi (name.string); - XINT (return_rtx, i) = tmp_int; + record_potential_iterator_use (&ints, &XINT (return_rtx, i), + name.string); break; default: |