aboutsummaryrefslogtreecommitdiff
path: root/gcc/doc
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2018-08-02 10:59:35 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2018-08-02 10:59:35 +0000
commit0016d8d91cb2880e69be74efb44367b282577977 (patch)
treec65a69b7b2e33e1f21911fa540f0ce7579294e37 /gcc/doc
parenta451882123524de1b9b175af97a1cdd32e5f25c1 (diff)
downloadgcc-0016d8d91cb2880e69be74efb44367b282577977.zip
gcc-0016d8d91cb2880e69be74efb44367b282577977.tar.gz
gcc-0016d8d91cb2880e69be74efb44367b282577977.tar.bz2
[gen/AArch64] Generate helpers for substituting iterator values into pattern names
Given a pattern like: (define_insn "aarch64_frecpe<mode>" ...) the SVE ACLE implementation wants to generate the pattern for a particular (non-constant) mode. This patch automatically generates helpers to do that, specifically: // Return CODE_FOR_nothing on failure. insn_code maybe_code_for_aarch64_frecpe (machine_mode); // Assert that the code exists. insn_code code_for_aarch64_frecpe (machine_mode); // Return NULL_RTX on failure. rtx maybe_gen_aarch64_frecpe (machine_mode, rtx, rtx); // Assert that generation succeeds. rtx gen_aarch64_frecpe (machine_mode, rtx, rtx); Many patterns don't have sensible names when all <...>s are removed. E.g. "<optab><mode>2" would give a base name "2". The new functions therefore require explicit opt-in, which should also help to reduce code bloat. The (arbitrary) opt-in syntax I went for was to prefix the pattern name with '@', similarly to the existing '*' marker. The patch also makes config/aarch64 use the new routines in cases where they obviously apply. This was mostly straight-forward, but it seemed odd that we defined: aarch64_reload_movcp<...><P:mode> but then only used it with DImode, never SImode. If we should be using Pmode instead of DImode, then that's a simple change, but should probably be a separate patch. 2018-08-02 Richard Sandiford <richard.sandiford@arm.com> gcc/ * doc/md.texi: Expand the documentation of instruction names to mention port-local uses. Document '@' in pattern names. * read-md.h (overloaded_instance, overloaded_name): New structs. (mapping): Declare. (md_reader::handle_overloaded_name): New member function. (md_reader::get_overloads): Likewise. (md_reader::m_first_overload): New member variable. (md_reader::m_next_overload_ptr): Likewise. (md_reader::m_overloads_htab): Likewise. * read-md.c (md_reader::md_reader): Initialize m_first_overload, m_next_overload_ptr and m_overloads_htab. * read-rtl.c (iterator_group): Add "type" and "get_c_token" fields. (get_mode_token, get_code_token, get_int_token): New functions. (map_attr_string): Add an optional argument that passes back the associated iterator. (overloaded_name_hash, overloaded_name_eq_p, named_rtx_p): (md_reader::handle_overloaded_name, add_overload_instance): New functions. (apply_iterators): Handle '@' names. Report an error if '@' is used without iterators. (initialize_iterators): Initialize the new iterator_group fields. * genopinit.c (handle_overloaded_code_for) (handle_overloaded_gen): New functions. (main): Use them to print declarations of maybe_code_for_* and maybe_gen_* functions, and inline definitions of code_for_* and gen_*. * genemit.c (print_overload_arguments, print_overload_test) (handle_overloaded_code_for, handle_overloaded_gen): New functions. (main): Use it to print definitions of maybe_code_for_* and maybe_gen_* functions. * config/aarch64/aarch64.c (aarch64_split_128bit_move): Use gen_aarch64_mov{low,high}_di and gen_aarch64_movdi_{low,high} instead of explicit mode checks. (aarch64_split_simd_combine): Likewise gen_aarch64_simd_combine. (aarch64_split_simd_move): Likewise gen_aarch64_split_simd_mov. (aarch64_emit_load_exclusive): Likewise gen_aarch64_load_exclusive. (aarch64_emit_store_exclusive): Likewise gen_aarch64_store_exclusive. (aarch64_expand_compare_and_swap): Likewise gen_aarch64_compare_and_swap and gen_aarch64_compare_and_swap_lse (aarch64_gen_atomic_cas): Likewise gen_aarch64_atomic_cas. (aarch64_emit_atomic_swap): Likewise gen_aarch64_atomic_swp. (aarch64_constant_pool_reload_icode): Delete. (aarch64_secondary_reload): Use code_for_aarch64_reload_movcp instead of aarch64_constant_pool_reload_icode. Use code_for_aarch64_reload_mov instead of explicit mode checks. (rsqrte_type, get_rsqrte_type, rsqrts_type, get_rsqrts_type): Delete. (aarch64_emit_approx_sqrt): Use gen_aarch64_rsqrte instead of get_rsqrte_type and gen_aarch64_rsqrts instead of gen_rqrts_type. (recpe_type, get_recpe_type, recps_type, get_recps_type): Delete. (aarch64_emit_approx_div): Use gen_aarch64_frecpe instead of get_recpe_type and gen_aarch64_frecps instead of get_recps_type. (aarch64_atomic_load_op_code): Delete. (aarch64_emit_atomic_load_op): Likewise. (aarch64_gen_atomic_ldop): Use UNSPECV_ATOMIC_* instead of aarch64_atomic_load_op_code. Use gen_aarch64_atomic_load instead of aarch64_emit_atomic_load_op. * config/aarch64/aarch64.md (aarch64_reload_movcp<GPF_TF:mode><P:mode>) (aarch64_reload_movcp<VALL:mode><P:mode>, aarch64_reload_mov<mode>) (aarch64_movdi_<mode>low, aarch64_movdi_<mode>high) (aarch64_mov<mode>high_di, aarch64_mov<mode>low_di): Add a '@' character before the pattern name. * config/aarch64/aarch64-simd.md (aarch64_split_simd_mov<mode>) (aarch64_rsqrte<mode>, aarch64_rsqrts<mode>) (aarch64_simd_combine<mode>, aarch64_frecpe<mode>) (aarch64_frecps<mode>): Likewise. * config/aarch64/atomics.md (atomic_compare_and_swap<mode>) (aarch64_compare_and_swap<mode>, aarch64_compare_and_swap<mode>_lse) (aarch64_load_exclusive<mode>, aarch64_store_exclusive<mode>) (aarch64_atomic_swp<mode>, aarch64_atomic_cas<mode>) (aarch64_atomic_load<atomic_ldop><mode>): Likewise. From-SVN: r263251
Diffstat (limited to 'gcc/doc')
-rw-r--r--gcc/doc/md.texi125
1 files changed, 117 insertions, 8 deletions
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index e793525..e5851a6 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -115,26 +115,37 @@ A @code{define_insn} is an RTL expression containing four or five operands:
@enumerate
@item
-An optional name. The presence of a name indicates that this instruction
-pattern can perform a certain standard job for the RTL-generation
-pass of the compiler. This pass knows certain names and will use
-the instruction patterns with those names, if the names are defined
-in the machine description.
+An optional name @var{n}. When a name is present, the compiler
+automically generates a C++ function @samp{gen_@var{n}} that takes
+the operands of the instruction as arguments and returns the instruction's
+rtx pattern. The compiler also assigns the instruction a unique code
+@samp{CODE_FOR_@var{n}}, with all such codes belonging to an enum
+called @code{insn_code}.
+
+These names serve one of two purposes. The first is to indicate that the
+instruction performs a certain standard job for the RTL-generation
+pass of the compiler, such as a move, an addition, or a conditional
+jump. The second is to help the target generate certain target-specific
+operations, such as when implementing target-specific intrinsic functions.
+
+It is better to prefix target-specific names with the name of the
+target, to avoid any clash with current or future standard names.
The absence of a name is indicated by writing an empty string
where the name should go. Nameless instruction patterns are never
used for generating RTL code, but they may permit several simpler insns
to be combined later on.
-Names that are not thus known and used in RTL-generation have no
-effect; they are equivalent to no name at all.
-
For the purpose of debugging the compiler, you may also specify a
name beginning with the @samp{*} character. Such a name is used only
for identifying the instruction in RTL dumps; it is equivalent to having
a nameless pattern for all other purposes. Names beginning with the
@samp{*} character are not required to be unique.
+The name may also have the form @samp{@@@var{n}}. This has the same
+effect as a name @samp{@var{n}}, but in addition tells the compiler to
+generate further helper functions; see @xref{Parameterized Names} for details.
+
@item
The @dfn{RTL template}: This is a vector of incomplete RTL expressions
which describe the semantics of the instruction (@pxref{RTL Template}).
@@ -10530,6 +10541,7 @@ facilities to make this process easier.
* Code Iterators:: Doing the same for codes.
* Int Iterators:: Doing the same for integers.
* Subst Iterators:: Generating variations of patterns for define_subst.
+* Parameterized Names:: Specifying iterator values in C++ code.
@end menu
@node Mode Iterators
@@ -10925,4 +10937,101 @@ replaced in the first copy of the original RTL-template.
@var{subst-applied-value} is a value with which subst-attribute would be
replaced in the second copy of the original RTL-template.
+@node Parameterized Names
+@subsection Parameterized Names
+@cindex @samp{@@} in instruction pattern names
+Ports sometimes need to apply iterators using C++ code, in order to
+get the code or RTL pattern for a specific instruction. For example,
+suppose we have the @samp{neon_vq<absneg><mode>} pattern given above:
+
+@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))]
+ @dots{}
+)
+@end smallexample
+
+A port might need to generate this pattern for a variable
+@samp{QABSNEG} value and a variable @samp{VDQIW} mode. There are two
+ways of doing this. The first is to build the rtx for the pattern
+directly from C++ code; this is a valid technique and avoids any risk
+of combinatorial explosion. The second is to prefix the instruction
+name with the special character @samp{@@}, which tells GCC to generate
+the four additional functions below. In each case, @var{name} is the
+name of the instruction without the leading @samp{@@} character,
+without the @samp{<@dots{}>} placeholders, and with any underscore
+before a @samp{<@dots{}>} placeholder removed if keeping it would
+lead to a double or trailing underscore.
+
+@table @samp
+@item insn_code maybe_code_for_@var{name} (@var{i1}, @var{i2}, @dots{})
+See whether replacing the first @samp{<@dots{}>} placeholder with
+iterator value @var{i1}, the second with iterator value @var{i2}, and
+so on, gives a valid instruction. Return its code if so, otherwise
+return @code{CODE_FOR_nothing}.
+
+@item insn_code code_for_@var{name} (@var{i1}, @var{i2}, @dots{})
+Same, but abort the compiler if the requested instruction does not exist.
+
+@item rtx maybe_gen_@var{name} (@var{i1}, @var{i2}, @dots{}, @var{op0}, @var{op1}, @dots{})
+Check for a valid instruction in the same way as
+@code{maybe_code_for_@var{name}}. If the instruction exists,
+generate an instance of it using the operand values given by @var{op0},
+@var{op1}, and so on, otherwise return null.
+
+@item rtx gen_@var{name} (@var{i1}, @var{i2}, @dots{}, @var{op0}, @var{op1}, @dots{})
+Same, but abort the compiler if the requested instruction does not exist,
+or if the instruction generator invoked the @code{FAIL} macro.
+@end table
+
+For example, changing the pattern above to:
+
+@smallexample
+(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))]
+ @dots{}
+)
+@end smallexample
+
+would define the same patterns as before, but in addition would generate
+the four functions below:
+
+@smallexample
+insn_code maybe_code_for_neon_vq (int, machine_mode);
+insn_code code_for_neon_vq (int, machine_mode);
+rtx maybe_gen_neon_vq (int, machine_mode, rtx, rtx, rtx);
+rtx gen_neon_vq (int, machine_mode, rtx, rtx, rtx);
+@end smallexample
+
+Calling @samp{code_for_neon_vq (UNSPEC_VQABS, V8QImode)}
+would then give @code{CODE_FOR_neon_vqabsv8qi}.
+
+It is possible to have multiple @samp{@@} patterns with the same
+name and same types of iterator. For example:
+
+@smallexample
+(define_insn "@@some_arithmetic_op<mode>"
+ [(set (match_operand:INTEGER_MODES 0 "register_operand") @dots{})]
+ @dots{}
+)
+
+(define_insn "@@some_arithmetic_op<mode>"
+ [(set (match_operand:FLOAT_MODES 0 "register_operand") @dots{})]
+ @dots{}
+)
+@end smallexample
+
+would produce a single set of functions that handles both
+@code{INTEGER_MODES} and @code{FLOAT_MODES}.
+
@end ifset