aboutsummaryrefslogtreecommitdiff
path: root/gcc/genopinit.c
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/genopinit.c
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/genopinit.c')
-rw-r--r--gcc/genopinit.c68
1 files changed, 67 insertions, 1 deletions
diff --git a/gcc/genopinit.c b/gcc/genopinit.c
index 65a38d2..79835cc 100644
--- a/gcc/genopinit.c
+++ b/gcc/genopinit.c
@@ -104,6 +104,63 @@ open_outfile (const char *file_name)
return f;
}
+/* Declare the maybe_code_for_* function for ONAME, and provide
+ an inline definition of the assserting code_for_* wrapper. */
+
+static void
+handle_overloaded_code_for (FILE *file, overloaded_name *oname)
+{
+ fprintf (file, "\nextern insn_code maybe_code_for_%s (", oname->name);
+ for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
+ fprintf (file, "%s%s", i == 0 ? "" : ", ", oname->arg_types[i]);
+ fprintf (file, ");\n");
+
+ fprintf (file, "inline insn_code\ncode_for_%s (", oname->name);
+ for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
+ fprintf (file, "%s%s arg%d", i == 0 ? "" : ", ", oname->arg_types[i], i);
+ fprintf (file, ")\n{\n insn_code code = maybe_code_for_%s (", oname->name);
+ for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
+ fprintf (file, "%sarg%d", i == 0 ? "" : ", ", i);
+ fprintf (file,
+ ");\n"
+ " gcc_assert (code != CODE_FOR_nothing);\n"
+ " return code;\n"
+ "}\n");
+}
+
+/* Declare the maybe_gen_* function for ONAME, and provide
+ an inline definition of the assserting gen_* wrapper. */
+
+static void
+handle_overloaded_gen (FILE *file, overloaded_name *oname)
+{
+ pattern_stats stats;
+ get_pattern_stats (&stats, XVEC (oname->first_instance->insn, 1));
+
+ fprintf (file, "\nextern rtx maybe_gen_%s (", oname->name);
+ for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
+ fprintf (file, "%s%s", i == 0 ? "" : ", ", oname->arg_types[i]);
+ for (int i = 0; i < stats.num_generator_args; ++i)
+ fprintf (file, ", rtx");
+ fprintf (file, ");\n");
+
+ fprintf (file, "inline rtx\ngen_%s (", oname->name);
+ for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
+ fprintf (file, "%s%s arg%d", i == 0 ? "" : ", ", oname->arg_types[i], i);
+ for (int i = 0; i < stats.num_generator_args; ++i)
+ fprintf (file, ", rtx x%d", i);
+ fprintf (file, ")\n{\n rtx res = maybe_gen_%s (", oname->name);
+ for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
+ fprintf (file, "%sarg%d", i == 0 ? "" : ", ", i);
+ for (int i = 0; i < stats.num_generator_args; ++i)
+ fprintf (file, ", x%d", i);
+ fprintf (file,
+ ");\n"
+ " gcc_assert (res);\n"
+ " return res;\n"
+ "}\n");
+}
+
int
main (int argc, const char **argv)
{
@@ -220,7 +277,16 @@ main (int argc, const char **argv)
"optab_to_code (optab op)\n"
"{\n"
" return optab_to_code_[op];\n"
- "}\n"
+ "}\n");
+
+ for (overloaded_name *oname = rtx_reader_ptr->get_overloads ();
+ oname; oname = oname->next)
+ {
+ handle_overloaded_code_for (h_file, oname);
+ handle_overloaded_gen (h_file, oname);
+ }
+
+ fprintf (h_file,
"#endif\n"
"\n"
"extern const struct convert_optab_libcall_d convlib_def[NUM_CONVLIB_OPTABS];\n"