summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog136
-rw-r--r--gcc/Makefile.in19
-rw-r--r--gcc/genopinit.c932
-rw-r--r--gcc/libfuncs.h2
-rw-r--r--gcc/optabs.c653
-rw-r--r--gcc/optabs.def308
-rw-r--r--gcc/optabs.h960
-rw-r--r--gcc/rtl.h7
8 files changed, 1108 insertions, 1909 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a5f9ee74479..ee809e01157 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,139 @@
+2012-07-24 Richard Henderson <rth@redhat.com>
+
+ * optabs.def: New file.
+ * Makefile.in (OPTABS_H): Add insn-opinit.h.
+ (MOSTLYCLEANFILES): Likewise.
+ (insn-opinit.o): Remove reload.h
+ (simple_rtl_generated_c): Remove insn-opinit.c.
+ (s-opinit): New rule.
+ (build/genopinit.o): Add optabs.def.
+ * genopinit.c (rtx_upname): New.
+ (optabs): Extract to optabs.def
+ (enum optab_tag, struct optab_def_d, optabs): New.
+ (struct pattern_d, patterns): New.
+ (match_pattern): Split out from ...
+ (gen_insn): ... here. Push matches on patterns vec.
+ (pattern_cmp, optab_kind_cmp, optab_rcode_cmp): New.
+ (header_file_name, source_file_name, handle_arg): New.
+ (open_outfile): New.
+ (main): Sort and emit new tables. Generate lookup_handler,
+ raw_optab_handler, swap_optab_enable.
+ * libfuncs.h (libfunc_entry): Change "size_t optab" to "optab op".
+ * optabs.c (code_to_optab_): Remove.
+ (hash_libfunc): Update for optab name change.
+ (eq_libfunc): Likewise.
+ (convert_optab_libfunc): Update computation of optab member;
+ use the new convlib_def table.
+ (optab_libfunc): Similarly.
+ (set_optab_libfunc, set_conv_libfunc): Likewise.
+ (sign_expand_binop): Use swap_optab_enable instead of fake optabs.
+ (init_insn_codes, init_optab, init_optabv, init_convert_optab): Remove.
+ (init_optabs): Don't call them; export the data to optabs.def.
+ (gen_int_libfunc, gen_fp_libfunc): Export non-static.
+ (gen_fixed_libfunc, gen_signed_fixed_libfunc): Likewise.
+ (gen_unsigned_fixed_libfunc, gen_int_fp_libfunc): Likewise.
+ (gen_intv_fp_libfunc, gen_int_fp_fixed_libfunc): Likewise.
+ (gen_int_fp_signed_fixed_libfunc, gen_int_fixed_libfunc): Likewise.
+ (gen_int_signed_fixed_libfunc): Likewise.
+ (gen_int_unsigned_fixed_libfunc): Likewise.
+ (gen_interclass_conv_libfunc, gen_int_to_fp_conv_libfunc): Likewise.
+ (gen_ufloat_conv_libfunc): Likewise.
+ (gen_int_to_fp_nondecimal_conv_libfunc): Likewise.
+ (gen_fp_to_int_conv_libfunc, gen_intraclass_conv_libfunc): Likewise.
+ (gen_trunc_conv_libfunc, gen_extend_conv_libfunc): Likewise.
+ (gen_fract_conv_libfunc, gen_fractuns_conv_libfunc): Likewise.
+ (gen_satfract_conv_libfunc, gen_satfractuns_conv_libfunc): Likewise.
+ (debug_optab_libfuncs): Update for optab representation change.
+ * optabs.h: Include insn-opinit.h.
+ (optab, convert_optab, direct_optab): New typedefs.
+ (struct optab_handlers, struct widening_optab_handlers): Remove.
+ (struct optab_libcall_d): Rename from optab_d; remove code_,
+ handlers, widening members.
+ (struct convert_optab_libcall_d): Rename from convert_optab_d;
+ remove code_ and handlers members.
+ (enum optab_index, enum convert_optab_index): Remove.
+ (enum direct_optab_index): Remove.
+ (code_to_optab_): Fix array range.
+ (optab_to_code): Covert to inline function.
+ (optab_to_code_, convlib_def, normlib_def): Declare.
+ (raw_optab_handler, swap_optab_enable): Declare.
+ (unknown_optab): Remove; export to optabs.def
+ (ssadd_optab, usadd_optab, sssub_optab, ussub_optab, ssmul_optab,
+ usmul_optab, ssdiv_optab, usdiv_optab, ssneg_optab, usneg_optab,
+ ssashl_optab, usashl_optab, add_optab, sub_optab, smul_optab,
+ addv_optab, subv_optab, smul_highpart_optab, umul_highpart_optab,
+ smul_widen_optab, umul_widen_optab, usmul_widen_optab,
+ smadd_widen_optab, umadd_widen_optab, ssmadd_widen_optab,
+ usmadd_widen_optab, smsub_widen_optab, umsub_widen_optab,
+ ssmsub_widen_optab, usmsub_widen_optab, sdiv_optab, smulv_optab,
+ sdivv_optab, sdivmod_optab, udiv_optab, udivmod_optab, smod_optab,
+ umod_optab, fmod_optab, remainder_optab, ftrunc_optab, and_optab,
+ ior_optab, xor_optab, ashl_optab, lshr_optab, ashr_optab, rotl_optab,
+ rotr_optab, vashl_optab, vlshr_optab, vashr_optab, vrotl_optab,
+ vrotr_optab, smin_optab, smax_optab, umin_optab, umax_optab, pow_optab,
+ atan2_optab, fma_optab, fms_optab, fnma_optab, fnms_optab, mov_optab,
+ movstrict_optab, movmisalign_optab, storent_optab, neg_optab,
+ negv_optab, abs_optab, absv_optab, one_cmpl_optab, bswap_optab,
+ ffs_optab, clz_optab, ctz_optab, clrsb_optab, popcount_optab,
+ parity_optab, sqrt_optab, sincos_optab, sin_optab, asin_optab,
+ cos_optab, acos_optab, exp_optab, exp10_optab, exp2_optab, expm1_optab,
+ ldexp_optab, scalb_optab, significand_optab, logb_optab, ilogb_optab,
+ log_optab, log10_optab, log2_optab, log1p_optab, floor_optab,
+ ceil_optab, btrunc_optab, round_optab, nearbyint_optab, rint_optab,
+ tan_optab, atan_optab, copysign_optab, signbit_optab, isinf_optab,
+ cmp_optab, ucmp_optab, eq_optab, ne_optab, gt_optab, ge_optab,
+ lt_optab, le_optab, unord_optab, strlen_optab, cbranch_optab,
+ cmov_optab, cstore_optab, ctrap_optab, push_optab, addcc_optab,
+ reduc_smax_optab, reduc_umax_optab, reduc_smin_optab, reduc_umin_optab,
+ reduc_splus_optab, reduc_uplus_optab, ssum_widen_optab,
+ usum_widen_optab, sdot_prod_optab, udot_prod_optab, vec_set_optab,
+ vec_extract_optab, vec_init_optab, vec_shl_optab, vec_shr_optab,
+ vec_realign_load_optab, vec_widen_umult_hi_optab,
+ vec_widen_umult_lo_optab, vec_widen_smult_hi_optab,
+ vec_widen_smult_lo_optab, vec_widen_umult_even_optab,
+ vec_widen_umult_odd_optab, vec_widen_smult_even_optab,
+ vec_widen_smult_odd_optab, vec_widen_ushiftl_hi_optab,
+ vec_widen_ushiftl_lo_optab, vec_widen_sshiftl_hi_optab,
+ vec_widen_sshiftl_lo_optab, vec_unpacks_hi_optab, vec_unpacks_lo_optab,
+ vec_unpacku_hi_optab, vec_unpacku_lo_optab, vec_unpacks_float_hi_optab,
+ vec_unpacks_float_lo_optab, vec_unpacku_float_hi_optab,
+ vec_unpacku_float_lo_optab, vec_pack_trunc_optab, vec_pack_ssat_optab,
+ vec_pack_usat_optab, vec_pack_sfix_trunc_optab,
+ vec_pack_ufix_trunc_optab, powi_optab, sync_compare_and_swap_optab,
+ sync_lock_test_and_set_optab, sync_old_add_optab, sync_old_sub_optab,
+ sync_old_ior_optab, sync_old_and_optab, sync_old_xor_optab,
+ sync_old_nand_optab, sync_new_add_optab, sync_new_sub_optab,
+ sync_new_ior_optab, sync_new_and_optab, sync_new_xor_optab,
+ sync_new_nand_optab, sext_optab, zext_optab, trunc_optab, sfix_optab,
+ ufix_optab, sfixtrunc_optab, ufixtrunc_optab, sfloat_optab,
+ ufloat_optab, lrint_optab, lround_optab, lfloor_optab, lceil_optab,
+ fract_optab, fractuns_optab, satfract_optab, satfractuns_optab,
+ vec_load_lanes_optab, vec_store_lanes_optab, vcond_optab, vcondu_optab,
+ movcc_optab, reload_in_optab, reload_out_optab, movmem_optab,
+ setmem_optab, cmpstr_optab, cmpstrn_optab, cmpmem_optab,
+ sync_lock_release_optab, sync_add_optab, sync_sub_optab,
+ sync_ior_optab, sync_and_optab, sync_xor_optab, sync_nand_optab,
+ atomic_exchange_optab, atomic_compare_and_swap_optab,
+ atomic_load_optab, atomic_store_optab, atomic_add_fetch_optab,
+ atomic_sub_fetch_optab, atomic_and_fetch_optab,
+ atomic_nand_fetch_optab, atomic_xor_fetch_optab, atomic_or_fetch_optab,
+ atomic_fetch_add_optab, atomic_fetch_sub_optab, atomic_fetch_and_optab,
+ atomic_fetch_nand_optab, atomic_fetch_xor_optab, atomic_fetch_or_optab,
+ atomic_add_optab, atomic_sub_optab, atomic_and_optab,
+ atomic_nand_optab, atomic_xor_optab, atomic_or_optab,
+ atomic_always_lock_free_optab, atomic_is_lock_free_optab,
+ atomic_thread_fence_optab, atomic_signal_fence_optab,
+ vec_perm_optab, vec_perm_const_optab): Likewise.
+ (struct target_optabs): Remove x_optab_table, x_convert_optab_table,
+ and x_direct_optab_table members; add pat_enable.
+ (optab_table, convert_optab_table, direct_optab_table): Remove.
+ (optab_handler): Use raw_optab_handler.
+ (widening_optab_handler, convert_optab_handler): Likewise.
+ (set_optab_handler, set_widening_optab_handler): Remove.
+ (set_convert_optab_handler, set_direct_optab_handler): Remove.
+ (direct_optab_handler): Defer to optab_handler.
+ * rtl.h (NON_GENERATOR_NUM_RTX_CODE): New.
+
2012-07-24 Jason Merrill <jason@redhat.com>
* bitmap.c (bitmap_descriptor): Adjust order of parameters to
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 81dc3122641..40f7c4de561 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -889,7 +889,7 @@ OPTIONS_H = options.h flag-types.h $(OPTIONS_H_EXTRA)
FUNCTION_H = function.h $(HASHTAB_H) vecprim.h $(TM_H) hard-reg-set.h \
$(VEC_H) vecir.h $(INPUT_H) $(MACHMODE_H)
EXPR_H = expr.h insn-config.h $(FUNCTION_H) $(RTL_H) $(FLAGS_H) $(TREE_H) $(MACHMODE_H) $(EMIT_RTL_H)
-OPTABS_H = optabs.h insn-codes.h
+OPTABS_H = optabs.h insn-codes.h insn-opinit.h
REGS_H = regs.h $(MACHMODE_H) hard-reg-set.h
SCHED_INT_H = sched-int.h $(INSN_ATTR_H) $(BASIC_BLOCK_H) $(RTL_H) $(DF_H) \
vecprim.h $(REGSET_H)
@@ -1484,7 +1484,7 @@ BACKEND = libbackend.a main.o @TREEBROWSER@ libcommon-target.a libcommon.a \
MOSTLYCLEANFILES = insn-flags.h insn-config.h insn-codes.h \
insn-output.c insn-recog.c insn-emit.c insn-extract.c insn-peep.c \
insn-attr.h insn-attr-common.h insn-attrtab.c insn-dfatab.c \
- insn-latencytab.c insn-opinit.c insn-preds.c insn-constants.h \
+ insn-latencytab.c insn-opinit.c insn-opinit.h insn-preds.c insn-constants.h \
tm-preds.h tm-constrs.h checksum-options \
tree-check.h min-insn-modes.c insn-modes.c insn-modes.h \
genrtl.h gt-*.h gtype-*.h gtype-desc.c gtyp-input.list \
@@ -3430,7 +3430,7 @@ insn-modes.o : insn-modes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(MACHMODE_H)
insn-opinit.o : insn-opinit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(RTL_H) $(TM_P_H) insn-config.h $(FLAGS_H) $(RECOG_H) \
- $(EXPR_H) $(OPTABS_H) reload.h
+ $(EXPR_H) $(OPTABS_H)
insn-output.o : insn-output.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(RTL_H) $(GGC_H) $(REGS_H) conditions.h \
hard-reg-set.h insn-config.h $(INSN_ATTR_H) $(EXPR_H) output.h \
@@ -3459,7 +3459,7 @@ simple_rtl_generated_h = insn-attr.h insn-attr-common.h insn-codes.h \
insn-config.h insn-flags.h
simple_rtl_generated_c = insn-automata.c insn-emit.c \
- insn-extract.c insn-opinit.c insn-output.c \
+ insn-extract.c insn-output.c \
insn-peep.c insn-recog.c
simple_generated_h = $(simple_rtl_generated_h) insn-constants.h
@@ -3506,6 +3506,15 @@ s-attrtab : $(MD_DEPS) build/genattrtab$(build_exeext) \
$(SHELL) $(srcdir)/../move-if-change tmp-latencytab.c insn-latencytab.c
$(STAMP) s-attrtab
+# genopinit produces two files.
+insn-opinit.c insn-opinit.h: s-opinit ; @true
+s-opinit: $(MD_DEPS) build/genopinit$(build_exeext) insn-conditions.md
+ $(RUN_GEN) build/genopinit$(build_exeext) $(md_file) \
+ insn-conditions.md -htmp-opinit.h -ctmp-opinit.c
+ $(SHELL) $(srcdir)/../move-if-change tmp-opinit.h insn-opinit.h
+ $(SHELL) $(srcdir)/../move-if-change tmp-opinit.c insn-opinit.c
+ $(STAMP) s-opinit
+
# gencondmd doesn't use the standard naming convention.
build/gencondmd.c: s-conditions; @true
s-conditions: $(MD_DEPS) build/genconditions$(build_exeext)
@@ -3859,7 +3868,7 @@ build/genmddeps.o: genmddeps.c $(BCONFIG_H) $(SYSTEM_H) coretypes.h \
build/genmodes.o : genmodes.c $(BCONFIG_H) $(SYSTEM_H) errors.h \
$(HASHTAB_H) machmode.def $(extra_modes_file)
build/genopinit.o : genopinit.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) \
- coretypes.h $(GTM_H) errors.h gensupport.h
+ coretypes.h $(GTM_H) errors.h gensupport.h optabs.def
build/genoutput.o : genoutput.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) \
coretypes.h $(GTM_H) errors.h $(READ_MD_H) gensupport.h
build/genpeep.o : genpeep.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) \
diff --git a/gcc/genopinit.c b/gcc/genopinit.c
index 2d6757ec688..52612794802 100644
--- a/gcc/genopinit.c
+++ b/gcc/genopinit.c
@@ -1,7 +1,5 @@
/* Generate code to initialize optabs from machine description.
- Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010, 2011
- Free Software Foundation, Inc.
+ Copyright (C) 1993-2012 Free Software Foundation, Inc.
This file is part of GCC.
@@ -29,542 +27,498 @@ along with GCC; see the file COPYING3. If not see
#include "gensupport.h"
-/* Many parts of GCC use arrays that are indexed by machine mode and
- contain the insn codes for pattern in the MD file that perform a given
- operation on operands of that mode.
+#define DEF_RTL_EXPR(V, N, X, C) #V,
- These patterns are present in the MD file with names that contain
- the mode(s) used and the name of the operation. This program
- writes a function `init_all_optabs' that initializes the optabs with
- all the insn codes of the relevant patterns present in the MD file.
+static const char * const rtx_upname[] = {
+#include "rtl.def"
+};
+
+#undef DEF_RTL_EXPR
+
+
+/* The entries in optabs.def are categorized:
+ C: A "conversion" optab, which uses two modes; has libcall data.
+ N: A "normal" optab, which uses one mode; has libcall data.
+ D: A "direct" optab, which uses one mode; does not have libcall data.
+ V: An "oVerflow" optab. Like N, but does not record its code in
+ code_to_optab.
- This array contains a list of optabs that need to be initialized. Within
- each string, the name of the pattern to be matched against is delimited
- with $( and $). In the string, $a and $b are used to match a short mode
- name (the part of the mode name not including `mode' and converted to
- lower-case). When writing out the initializer, the entire string is
- used. $A and $B are replaced with the full name of the mode; $a and $b
- are replaced with the short form of the name, as above.
+ CX, NX, VX: An extra pattern entry for a conversion or normal optab.
- If $N is present in the pattern, it means the two modes must be in
- the same mode class, and $b must be greater than $a (e.g, QImode
- and HImode).
+ These patterns may be present in the MD file with names that contain
+ the mode(s) used and the name of the operation. This array contains
+ a list of optabs that need to be initialized. Within each name,
+ $a and $b are used to match a short mode name (the part of the mode
+ name not including `mode' and converted to lower-case).
$I means that only full integer modes should be considered for the
next mode, and $F means that only float modes should be considered.
$P means that both full and partial integer modes should be considered.
$Q means that only fixed-point modes should be considered.
- $V means to emit 'v' if the first mode is a MODE_FLOAT mode.
-
- For some optabs, we store the operation by RTL codes. These are only
- used for comparisons. In that case, $c and $C are the lower-case and
- upper-case forms of the comparison, respectively. */
-
-static const char * const optabs[] =
-{ "set_convert_optab_handler (sext_optab, $B, $A, CODE_FOR_$(extend$a$b2$))",
- "set_convert_optab_handler (zext_optab, $B, $A, CODE_FOR_$(zero_extend$a$b2$))",
- "set_convert_optab_handler (sfix_optab, $B, $A, CODE_FOR_$(fix$F$a$I$b2$))",
- "set_convert_optab_handler (ufix_optab, $B, $A, CODE_FOR_$(fixuns$F$a$b2$))",
- "set_convert_optab_handler (sfixtrunc_optab, $B, $A, CODE_FOR_$(fix_trunc$F$a$I$b2$))",
- "set_convert_optab_handler (ufixtrunc_optab, $B, $A, CODE_FOR_$(fixuns_trunc$F$a$I$b2$))",
- "set_convert_optab_handler (sfloat_optab, $B, $A, CODE_FOR_$(float$I$a$F$b2$))",
- "set_convert_optab_handler (ufloat_optab, $B, $A, CODE_FOR_$(floatuns$I$a$F$b2$))",
- "set_convert_optab_handler (trunc_optab, $B, $A, CODE_FOR_$(trunc$a$b2$))",
- "set_convert_optab_handler (fract_optab, $B, $A, CODE_FOR_$(fract$a$b2$))",
- "set_convert_optab_handler (fractuns_optab, $B, $A, CODE_FOR_$(fractuns$I$a$Q$b2$))",
- "set_convert_optab_handler (fractuns_optab, $B, $A, CODE_FOR_$(fractuns$Q$a$I$b2$))",
- "set_convert_optab_handler (satfract_optab, $B, $A, CODE_FOR_$(satfract$a$Q$b2$))",
- "set_convert_optab_handler (satfractuns_optab, $B, $A, CODE_FOR_$(satfractuns$I$a$Q$b2$))",
- "set_convert_optab_handler (vec_load_lanes_optab, $A, $B, CODE_FOR_$(vec_load_lanes$a$b$))",
- "set_convert_optab_handler (vec_store_lanes_optab, $A, $B, CODE_FOR_$(vec_store_lanes$a$b$))",
- "set_optab_handler (add_optab, $A, CODE_FOR_$(add$P$a3$))",
- "set_optab_handler (addv_optab, $A, CODE_FOR_$(add$F$a3$)),\n\
- set_optab_handler (add_optab, $A, CODE_FOR_$(add$F$a3$))",
- "set_optab_handler (addv_optab, $A, CODE_FOR_$(addv$I$a3$))",
- "set_optab_handler (add_optab, $A, CODE_FOR_$(add$Q$a3$))",
- "set_optab_handler (ssadd_optab, $A, CODE_FOR_$(ssadd$Q$a3$))",
- "set_optab_handler (usadd_optab, $A, CODE_FOR_$(usadd$Q$a3$))",
- "set_optab_handler (sub_optab, $A, CODE_FOR_$(sub$P$a3$))",
- "set_optab_handler (subv_optab, $A, CODE_FOR_$(sub$F$a3$)),\n\
- set_optab_handler (sub_optab, $A, CODE_FOR_$(sub$F$a3$))",
- "set_optab_handler (subv_optab, $A, CODE_FOR_$(subv$I$a3$))",
- "set_optab_handler (sub_optab, $A, CODE_FOR_$(sub$Q$a3$))",
- "set_optab_handler (sssub_optab, $A, CODE_FOR_$(sssub$Q$a3$))",
- "set_optab_handler (ussub_optab, $A, CODE_FOR_$(ussub$Q$a3$))",
- "set_optab_handler (smul_optab, $A, CODE_FOR_$(mul$Q$a3$))",
- "set_optab_handler (ssmul_optab, $A, CODE_FOR_$(ssmul$Q$a3$))",
- "set_optab_handler (usmul_optab, $A, CODE_FOR_$(usmul$Q$a3$))",
- "set_optab_handler (smul_optab, $A, CODE_FOR_$(mul$P$a3$))",
- "set_optab_handler (smulv_optab, $A, CODE_FOR_$(mul$F$a3$)),\n\
- set_optab_handler (smul_optab, $A, CODE_FOR_$(mul$F$a3$))",
- "set_optab_handler (smulv_optab, $A, CODE_FOR_$(mulv$I$a3$))",
- "set_optab_handler (umul_highpart_optab, $A, CODE_FOR_$(umul$a3_highpart$))",
- "set_optab_handler (smul_highpart_optab, $A, CODE_FOR_$(smul$a3_highpart$))",
- "set_widening_optab_handler (smul_widen_optab, $B, $A, CODE_FOR_$(mul$a$b3$)$N)",
- "set_widening_optab_handler (umul_widen_optab, $B, $A, CODE_FOR_$(umul$a$b3$)$N)",
- "set_widening_optab_handler (usmul_widen_optab, $B, $A, CODE_FOR_$(usmul$a$b3$)$N)",
- "set_widening_optab_handler (smadd_widen_optab, $B, $A, CODE_FOR_$(madd$a$b4$)$N)",
- "set_widening_optab_handler (umadd_widen_optab, $B, $A, CODE_FOR_$(umadd$a$b4$)$N)",
- "set_widening_optab_handler (ssmadd_widen_optab, $B, $A, CODE_FOR_$(ssmadd$a$b4$)$N)",
- "set_widening_optab_handler (usmadd_widen_optab, $B, $A, CODE_FOR_$(usmadd$a$b4$)$N)",
- "set_widening_optab_handler (smsub_widen_optab, $B, $A, CODE_FOR_$(msub$a$b4$)$N)",
- "set_widening_optab_handler (umsub_widen_optab, $B, $A, CODE_FOR_$(umsub$a$b4$)$N)",
- "set_widening_optab_handler (ssmsub_widen_optab, $B, $A, CODE_FOR_$(ssmsub$a$b4$)$N)",
- "set_widening_optab_handler (usmsub_widen_optab, $B, $A, CODE_FOR_$(usmsub$a$b4$)$N)",
- "set_optab_handler (sdiv_optab, $A, CODE_FOR_$(div$a3$))",
- "set_optab_handler (ssdiv_optab, $A, CODE_FOR_$(ssdiv$Q$a3$))",
- "set_optab_handler (sdivv_optab, $A, CODE_FOR_$(div$V$I$a3$))",
- "set_optab_handler (udiv_optab, $A, CODE_FOR_$(udiv$I$a3$))",
- "set_optab_handler (udiv_optab, $A, CODE_FOR_$(udiv$Q$a3$))",
- "set_optab_handler (usdiv_optab, $A, CODE_FOR_$(usdiv$Q$a3$))",
- "set_optab_handler (sdivmod_optab, $A, CODE_FOR_$(divmod$a4$))",
- "set_optab_handler (udivmod_optab, $A, CODE_FOR_$(udivmod$a4$))",
- "set_optab_handler (smod_optab, $A, CODE_FOR_$(mod$a3$))",
- "set_optab_handler (umod_optab, $A, CODE_FOR_$(umod$a3$))",
- "set_optab_handler (fmod_optab, $A, CODE_FOR_$(fmod$a3$))",
- "set_optab_handler (remainder_optab, $A, CODE_FOR_$(remainder$a3$))",
- "set_optab_handler (ftrunc_optab, $A, CODE_FOR_$(ftrunc$F$a2$))",
- "set_optab_handler (and_optab, $A, CODE_FOR_$(and$a3$))",
- "set_optab_handler (ior_optab, $A, CODE_FOR_$(ior$a3$))",
- "set_optab_handler (xor_optab, $A, CODE_FOR_$(xor$a3$))",
- "set_optab_handler (ashl_optab, $A, CODE_FOR_$(ashl$a3$))",
- "set_optab_handler (ssashl_optab, $A, CODE_FOR_$(ssashl$Q$a3$))",
- "set_optab_handler (usashl_optab, $A, CODE_FOR_$(usashl$Q$a3$))",
- "set_optab_handler (ashr_optab, $A, CODE_FOR_$(ashr$a3$))",
- "set_optab_handler (lshr_optab, $A, CODE_FOR_$(lshr$a3$))",
- "set_optab_handler (rotl_optab, $A, CODE_FOR_$(rotl$a3$))",
- "set_optab_handler (rotr_optab, $A, CODE_FOR_$(rotr$a3$))",
- "set_optab_handler (vashr_optab, $A, CODE_FOR_$(vashr$a3$))",
- "set_optab_handler (vlshr_optab, $A, CODE_FOR_$(vlshr$a3$))",
- "set_optab_handler (vashl_optab, $A, CODE_FOR_$(vashl$a3$))",
- "set_optab_handler (vrotl_optab, $A, CODE_FOR_$(vrotl$a3$))",
- "set_optab_handler (vrotr_optab, $A, CODE_FOR_$(vrotr$a3$))",
- "set_optab_handler (smin_optab, $A, CODE_FOR_$(smin$a3$))",
- "set_optab_handler (smax_optab, $A, CODE_FOR_$(smax$a3$))",
- "set_optab_handler (umin_optab, $A, CODE_FOR_$(umin$I$a3$))",
- "set_optab_handler (umax_optab, $A, CODE_FOR_$(umax$I$a3$))",
- "set_optab_handler (pow_optab, $A, CODE_FOR_$(pow$a3$))",
- "set_optab_handler (atan2_optab, $A, CODE_FOR_$(atan2$a3$))",
- "set_optab_handler (neg_optab, $A, CODE_FOR_$(neg$P$a2$))",
- "set_optab_handler (negv_optab, $A, CODE_FOR_$(neg$F$a2$)),\n\
- set_optab_handler (neg_optab, $A, CODE_FOR_$(neg$F$a2$))",
- "set_optab_handler (negv_optab, $A, CODE_FOR_$(negv$I$a2$))",
- "set_optab_handler (neg_optab, $A, CODE_FOR_$(neg$Q$a2$))",
- "set_optab_handler (ssneg_optab, $A, CODE_FOR_$(ssneg$Q$a2$))",
- "set_optab_handler (usneg_optab, $A, CODE_FOR_$(usneg$Q$a2$))",
- "set_optab_handler (abs_optab, $A, CODE_FOR_$(abs$P$a2$))",
- "set_optab_handler (absv_optab, $A, CODE_FOR_$(abs$F$a2$)),\n\
- set_optab_handler (abs_optab, $A, CODE_FOR_$(abs$F$a2$))",
- "set_optab_handler (absv_optab, $A, CODE_FOR_$(absv$I$a2$))",
- "set_optab_handler (copysign_optab, $A, CODE_FOR_$(copysign$F$a3$))",
- "set_optab_handler (signbit_optab, $A, CODE_FOR_$(signbit$F$a2$))",
- "set_optab_handler (isinf_optab, $A, CODE_FOR_$(isinf$a2$))",
- "set_optab_handler (sqrt_optab, $A, CODE_FOR_$(sqrt$a2$))",
- "set_optab_handler (floor_optab, $A, CODE_FOR_$(floor$a2$))",
- "set_convert_optab_handler (lfloor_optab, $B, $A, CODE_FOR_$(lfloor$F$a$I$b2$))",
- "set_optab_handler (fma_optab, $A, CODE_FOR_$(fma$a4$))",
- "set_optab_handler (fms_optab, $A, CODE_FOR_$(fms$a4$))",
- "set_optab_handler (fnma_optab, $A, CODE_FOR_$(fnma$a4$))",
- "set_optab_handler (fnms_optab, $A, CODE_FOR_$(fnms$a4$))",
- "set_optab_handler (ceil_optab, $A, CODE_FOR_$(ceil$a2$))",
- "set_convert_optab_handler (lceil_optab, $B, $A, CODE_FOR_$(lceil$F$a$I$b2$))",
- "set_optab_handler (round_optab, $A, CODE_FOR_$(round$a2$))",
- "set_optab_handler (btrunc_optab, $A, CODE_FOR_$(btrunc$a2$))",
- "set_optab_handler (nearbyint_optab, $A, CODE_FOR_$(nearbyint$a2$))",
- "set_optab_handler (rint_optab, $A, CODE_FOR_$(rint$a2$))",
- "set_convert_optab_handler (lrint_optab, $B, $A, CODE_FOR_$(lrint$F$a$I$b2$))",
- "set_convert_optab_handler (lround_optab, $B, $A, CODE_FOR_$(lround$F$a$I$b2$))",
- "set_optab_handler (sincos_optab, $A, CODE_FOR_$(sincos$a3$))",
- "set_optab_handler (sin_optab, $A, CODE_FOR_$(sin$a2$))",
- "set_optab_handler (asin_optab, $A, CODE_FOR_$(asin$a2$))",
- "set_optab_handler (cos_optab, $A, CODE_FOR_$(cos$a2$))",
- "set_optab_handler (acos_optab, $A, CODE_FOR_$(acos$a2$))",
- "set_optab_handler (exp_optab, $A, CODE_FOR_$(exp$a2$))",
- "set_optab_handler (exp10_optab, $A, CODE_FOR_$(exp10$a2$))",
- "set_optab_handler (exp2_optab, $A, CODE_FOR_$(exp2$a2$))",
- "set_optab_handler (expm1_optab, $A, CODE_FOR_$(expm1$a2$))",
- "set_optab_handler (ldexp_optab, $A, CODE_FOR_$(ldexp$a3$))",
- "set_optab_handler (scalb_optab, $A, CODE_FOR_$(scalb$a3$))",
- "set_optab_handler (significand_optab, $A, CODE_FOR_$(significand$a2$))",
- "set_optab_handler (logb_optab, $A, CODE_FOR_$(logb$a2$))",
- "set_optab_handler (ilogb_optab, $A, CODE_FOR_$(ilogb$a2$))",
- "set_optab_handler (log_optab, $A, CODE_FOR_$(log$a2$))",
- "set_optab_handler (log10_optab, $A, CODE_FOR_$(log10$a2$))",
- "set_optab_handler (log2_optab, $A, CODE_FOR_$(log2$a2$))",
- "set_optab_handler (log1p_optab, $A, CODE_FOR_$(log1p$a2$))",
- "set_optab_handler (tan_optab, $A, CODE_FOR_$(tan$a2$))",
- "set_optab_handler (atan_optab, $A, CODE_FOR_$(atan$a2$))",
- "set_optab_handler (strlen_optab, $A, CODE_FOR_$(strlen$a$))",
- "set_optab_handler (one_cmpl_optab, $A, CODE_FOR_$(one_cmpl$a2$))",
- "set_optab_handler (bswap_optab, $A, CODE_FOR_$(bswap$a2$))",
- "set_optab_handler (ffs_optab, $A, CODE_FOR_$(ffs$a2$))",
- "set_optab_handler (clz_optab, $A, CODE_FOR_$(clz$a2$))",
- "set_optab_handler (ctz_optab, $A, CODE_FOR_$(ctz$a2$))",
- "set_optab_handler (clrsb_optab, $A, CODE_FOR_$(clrsb$a2$))",
- "set_optab_handler (popcount_optab, $A, CODE_FOR_$(popcount$a2$))",
- "set_optab_handler (parity_optab, $A, CODE_FOR_$(parity$a2$))",
- "set_optab_handler (mov_optab, $A, CODE_FOR_$(mov$a$))",
- "set_optab_handler (movstrict_optab, $A, CODE_FOR_$(movstrict$a$))",
- "set_optab_handler (movmisalign_optab, $A, CODE_FOR_$(movmisalign$a$))",
- "set_optab_handler (storent_optab, $A, CODE_FOR_$(storent$a$))",
- "set_optab_handler (addcc_optab, $A, CODE_FOR_$(add$acc$))",
- "set_direct_optab_handler (movcc_optab, $A, CODE_FOR_$(mov$acc$))",
- "set_optab_handler (cbranch_optab, $A, CODE_FOR_$(cbranch$a4$))",
- "set_optab_handler (cmov_optab, $A, CODE_FOR_$(cmov$a6$))",
- "set_optab_handler (cstore_optab, $A, CODE_FOR_$(cstore$a4$))",
- "set_optab_handler (ctrap_optab, $A, CODE_FOR_$(ctrap$a4$))",
- "set_optab_handler (push_optab, $A, CODE_FOR_$(push$a1$))",
- "set_direct_optab_handler (reload_in_optab, $A, CODE_FOR_$(reload_in$a$))",
- "set_direct_optab_handler (reload_out_optab, $A, CODE_FOR_$(reload_out$a$))",
- "set_direct_optab_handler (movmem_optab, $A, CODE_FOR_$(movmem$a$))",
- "set_direct_optab_handler (cmpstr_optab, $A, CODE_FOR_$(cmpstr$a$))",
- "set_direct_optab_handler (cmpstrn_optab, $A, CODE_FOR_$(cmpstrn$a$))",
- "set_direct_optab_handler (cmpmem_optab, $A, CODE_FOR_$(cmpmem$a$))",
- "set_direct_optab_handler (setmem_optab, $A, CODE_FOR_$(setmem$a$))",
- "set_direct_optab_handler (sync_add_optab, $A, CODE_FOR_$(sync_add$I$a$))",
- "set_direct_optab_handler (sync_sub_optab, $A, CODE_FOR_$(sync_sub$I$a$))",
- "set_direct_optab_handler (sync_ior_optab, $A, CODE_FOR_$(sync_ior$I$a$))",
- "set_direct_optab_handler (sync_and_optab, $A, CODE_FOR_$(sync_and$I$a$))",
- "set_direct_optab_handler (sync_xor_optab, $A, CODE_FOR_$(sync_xor$I$a$))",
- "set_direct_optab_handler (sync_nand_optab, $A, CODE_FOR_$(sync_nand$I$a$))",
- "set_optab_handler (sync_old_add_optab, $A, CODE_FOR_$(sync_old_add$I$a$))",
- "set_optab_handler (sync_old_sub_optab, $A, CODE_FOR_$(sync_old_sub$I$a$))",
- "set_optab_handler (sync_old_ior_optab, $A, CODE_FOR_$(sync_old_ior$I$a$))",
- "set_optab_handler (sync_old_and_optab, $A, CODE_FOR_$(sync_old_and$I$a$))",
- "set_optab_handler (sync_old_xor_optab, $A, CODE_FOR_$(sync_old_xor$I$a$))",
- "set_optab_handler (sync_old_nand_optab, $A, CODE_FOR_$(sync_old_nand$I$a$))",
- "set_optab_handler (sync_new_add_optab, $A, CODE_FOR_$(sync_new_add$I$a$))",
- "set_optab_handler (sync_new_sub_optab, $A, CODE_FOR_$(sync_new_sub$I$a$))",
- "set_optab_handler (sync_new_ior_optab, $A, CODE_FOR_$(sync_new_ior$I$a$))",
- "set_optab_handler (sync_new_and_optab, $A, CODE_FOR_$(sync_new_and$I$a$))",
- "set_optab_handler (sync_new_xor_optab, $A, CODE_FOR_$(sync_new_xor$I$a$))",
- "set_optab_handler (sync_new_nand_optab, $A, CODE_FOR_$(sync_new_nand$I$a$))",
- "set_optab_handler (sync_compare_and_swap_optab, $A, CODE_FOR_$(sync_compare_and_swap$I$a$))",
- "set_optab_handler (sync_lock_test_and_set_optab, $A, CODE_FOR_$(sync_lock_test_and_set$I$a$))",
- "set_direct_optab_handler (sync_lock_release_optab, $A, CODE_FOR_$(sync_lock_release$I$a$))",
- "set_direct_optab_handler (atomic_exchange_optab, $A, CODE_FOR_$(atomic_exchange$I$a$))",
- "set_direct_optab_handler (atomic_compare_and_swap_optab, $A, CODE_FOR_$(atomic_compare_and_swap$I$a$))",
- "set_direct_optab_handler (atomic_load_optab, $A, CODE_FOR_$(atomic_load$I$a$))",
- "set_direct_optab_handler (atomic_store_optab, $A, CODE_FOR_$(atomic_store$I$a$))",
- "set_direct_optab_handler (atomic_add_fetch_optab, $A, CODE_FOR_$(atomic_add_fetch$I$a$))",
- "set_direct_optab_handler (atomic_sub_fetch_optab, $A, CODE_FOR_$(atomic_sub_fetch$I$a$))",
- "set_direct_optab_handler (atomic_and_fetch_optab, $A, CODE_FOR_$(atomic_and_fetch$I$a$))",
- "set_direct_optab_handler (atomic_nand_fetch_optab, $A, CODE_FOR_$(atomic_nand_fetch$I$a$))",
- "set_direct_optab_handler (atomic_xor_fetch_optab, $A, CODE_FOR_$(atomic_xor_fetch$I$a$))",
- "set_direct_optab_handler (atomic_or_fetch_optab, $A, CODE_FOR_$(atomic_or_fetch$I$a$))",
- "set_direct_optab_handler (atomic_fetch_add_optab, $A, CODE_FOR_$(atomic_fetch_add$I$a$))",
- "set_direct_optab_handler (atomic_fetch_sub_optab, $A, CODE_FOR_$(atomic_fetch_sub$I$a$))",
- "set_direct_optab_handler (atomic_fetch_and_optab, $A, CODE_FOR_$(atomic_fetch_and$I$a$))",
- "set_direct_optab_handler (atomic_fetch_nand_optab, $A, CODE_FOR_$(atomic_fetch_nand$I$a$))",
- "set_direct_optab_handler (atomic_fetch_xor_optab, $A, CODE_FOR_$(atomic_fetch_xor$I$a$))",
- "set_direct_optab_handler (atomic_fetch_or_optab, $A, CODE_FOR_$(atomic_fetch_or$I$a$))",
- "set_direct_optab_handler (atomic_add_optab, $A, CODE_FOR_$(atomic_add$I$a$))",
- "set_direct_optab_handler (atomic_sub_optab, $A, CODE_FOR_$(atomic_sub$I$a$))",
- "set_direct_optab_handler (atomic_and_optab, $A, CODE_FOR_$(atomic_and$I$a$))",
- "set_direct_optab_handler (atomic_nand_optab, $A, CODE_FOR_$(atomic_nand$I$a$))",
- "set_direct_optab_handler (atomic_xor_optab, $A, CODE_FOR_$(atomic_xor$I$a$))",
- "set_direct_optab_handler (atomic_or_optab, $A, CODE_FOR_$(atomic_or$I$a$))",
- "set_optab_handler (vec_set_optab, $A, CODE_FOR_$(vec_set$a$))",
- "set_optab_handler (vec_extract_optab, $A, CODE_FOR_$(vec_extract$a$))",
- "set_optab_handler (vec_init_optab, $A, CODE_FOR_$(vec_init$a$))",
- "set_optab_handler (vec_shl_optab, $A, CODE_FOR_$(vec_shl_$a$))",
- "set_optab_handler (vec_shr_optab, $A, CODE_FOR_$(vec_shr_$a$))",
- "set_optab_handler (vec_realign_load_optab, $A, CODE_FOR_$(vec_realign_load_$a$))",
- "set_direct_optab_handler (vec_perm_optab, $A, CODE_FOR_$(vec_perm$a$))",
- "set_direct_optab_handler (vec_perm_const_optab, $A, CODE_FOR_$(vec_perm_const$a$))",
- "set_convert_optab_handler (vcond_optab, $A, $B, CODE_FOR_$(vcond$a$b$))",
- "set_convert_optab_handler (vcondu_optab, $A, $B, CODE_FOR_$(vcondu$a$b$))",
- "set_optab_handler (ssum_widen_optab, $A, CODE_FOR_$(widen_ssum$I$a3$))",
- "set_optab_handler (usum_widen_optab, $A, CODE_FOR_$(widen_usum$I$a3$))",
- "set_optab_handler (udot_prod_optab, $A, CODE_FOR_$(udot_prod$I$a$))",
- "set_optab_handler (sdot_prod_optab, $A, CODE_FOR_$(sdot_prod$I$a$))",
- "set_optab_handler (reduc_smax_optab, $A, CODE_FOR_$(reduc_smax_$a$))",
- "set_optab_handler (reduc_umax_optab, $A, CODE_FOR_$(reduc_umax_$a$))",
- "set_optab_handler (reduc_smin_optab, $A, CODE_FOR_$(reduc_smin_$a$))",
- "set_optab_handler (reduc_umin_optab, $A, CODE_FOR_$(reduc_umin_$a$))",
- "set_optab_handler (reduc_splus_optab, $A, CODE_FOR_$(reduc_splus_$a$))" ,
- "set_optab_handler (reduc_uplus_optab, $A, CODE_FOR_$(reduc_uplus_$a$))",
- "set_optab_handler (vec_widen_umult_hi_optab, $A, CODE_FOR_$(vec_widen_umult_hi_$a$))",
- "set_optab_handler (vec_widen_umult_lo_optab, $A, CODE_FOR_$(vec_widen_umult_lo_$a$))",
- "set_optab_handler (vec_widen_smult_hi_optab, $A, CODE_FOR_$(vec_widen_smult_hi_$a$))",
- "set_optab_handler (vec_widen_smult_lo_optab, $A, CODE_FOR_$(vec_widen_smult_lo_$a$))",
- "set_optab_handler (vec_widen_umult_even_optab, $A, CODE_FOR_$(vec_widen_umult_even_$a$))",
- "set_optab_handler (vec_widen_umult_odd_optab, $A, CODE_FOR_$(vec_widen_umult_odd_$a$))",
- "set_optab_handler (vec_widen_smult_even_optab, $A, CODE_FOR_$(vec_widen_smult_even_$a$))",
- "set_optab_handler (vec_widen_smult_odd_optab, $A, CODE_FOR_$(vec_widen_smult_odd_$a$))",
- "set_optab_handler (vec_widen_ushiftl_hi_optab, $A, CODE_FOR_$(vec_widen_ushiftl_hi_$a$))",
- "set_optab_handler (vec_widen_ushiftl_lo_optab, $A, CODE_FOR_$(vec_widen_ushiftl_lo_$a$))",
- "set_optab_handler (vec_widen_sshiftl_hi_optab, $A, CODE_FOR_$(vec_widen_sshiftl_hi_$a$))",
- "set_optab_handler (vec_widen_sshiftl_lo_optab, $A, CODE_FOR_$(vec_widen_sshiftl_lo_$a$))",
- "set_optab_handler (vec_unpacks_hi_optab, $A, CODE_FOR_$(vec_unpacks_hi_$a$))",
- "set_optab_handler (vec_unpacks_lo_optab, $A, CODE_FOR_$(vec_unpacks_lo_$a$))",
- "set_optab_handler (vec_unpacku_hi_optab, $A, CODE_FOR_$(vec_unpacku_hi_$a$))",
- "set_optab_handler (vec_unpacku_lo_optab, $A, CODE_FOR_$(vec_unpacku_lo_$a$))",
- "set_optab_handler (vec_unpacks_float_hi_optab, $A, CODE_FOR_$(vec_unpacks_float_hi_$a$))",
- "set_optab_handler (vec_unpacks_float_lo_optab, $A, CODE_FOR_$(vec_unpacks_float_lo_$a$))",
- "set_optab_handler (vec_unpacku_float_hi_optab, $A, CODE_FOR_$(vec_unpacku_float_hi_$a$))",
- "set_optab_handler (vec_unpacku_float_lo_optab, $A, CODE_FOR_$(vec_unpacku_float_lo_$a$))",
- "set_optab_handler (vec_pack_trunc_optab, $A, CODE_FOR_$(vec_pack_trunc_$a$))",
- "set_optab_handler (vec_pack_ssat_optab, $A, CODE_FOR_$(vec_pack_ssat_$a$))",
- "set_optab_handler (vec_pack_usat_optab, $A, CODE_FOR_$(vec_pack_usat_$a$))",
- "set_optab_handler (vec_pack_sfix_trunc_optab, $A, CODE_FOR_$(vec_pack_sfix_trunc_$a$))",
- "set_optab_handler (vec_pack_ufix_trunc_optab, $A, CODE_FOR_$(vec_pack_ufix_trunc_$a$))"
+ The pattern may be NULL if the optab exists only for the libcalls
+ that we plan to attach to it, and there are no named patterns in
+ the md files. */
+
+#define OPTAB_CL(name, pat, c, b, l) name,
+#define OPTAB_CX(name, pat)
+#define OPTAB_CD(name, pat) name,
+#define OPTAB_NL(name, pat, c, b, s, l) name,
+#define OPTAB_NC(name, pat, c) name,
+#define OPTAB_NX(name, pat)
+#define OPTAB_VL(name, pat, c, b, s, l) name,
+#define OPTAB_VC(name, pat, c) name,
+#define OPTAB_VX(name, pat)
+#define OPTAB_DC(name, pat, c) name,
+#define OPTAB_D(name, pat) name,
+
+typedef enum optab_tag {
+ unknown_optab,
+#include "optabs.def"
+ NUM_OPTABS
+} optab;
+
+#undef OPTAB_CL
+#undef OPTAB_CX
+#undef OPTAB_CD
+#undef OPTAB_NL
+#undef OPTAB_NC
+#undef OPTAB_NX
+#undef OPTAB_VL
+#undef OPTAB_VC
+#undef OPTAB_VX
+#undef OPTAB_DC
+#undef OPTAB_D
+
+#define NS "NULL"
+#define ZS "'\\0'"
+#define OPTAB_CL(o, p, c, b, l) { #o, p, #b, ZS, #l, o, c, UNKNOWN, 1 },
+#define OPTAB_CX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 1 },
+#define OPTAB_CD(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 2 },
+#define OPTAB_NL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, c, 3 },
+#define OPTAB_NC(o, p, c) { #o, p, NS, ZS, NS, o, c, c, 3 },
+#define OPTAB_NX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 },
+#define OPTAB_VL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, UNKNOWN, 3 },
+#define OPTAB_VC(o, p, c) { #o, p, NS, ZS, NS, o, c, UNKNOWN, 3 },
+#define OPTAB_VX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 },
+#define OPTAB_DC(o, p, c) { #o, p, NS, ZS, NS, o, c, c, 4 },
+#define OPTAB_D(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 4 },
+
+typedef struct optab_def_d
+{
+ const char *name;
+ const char *pattern;
+ const char *base;
+ const char *suffix;
+ const char *libcall;
+ unsigned int op;
+ enum rtx_code fcode;
+ enum rtx_code rcode;
+ unsigned int kind;
+} optab_def;
+
+static optab_def optabs[] = {
+ { "unknown_optab", NULL, NS, ZS, NS, unknown_optab, UNKNOWN, UNKNOWN, 0 },
+#include "optabs.def"
};
-static void gen_insn (rtx);
+#undef OPTAB_CL
+#undef OPTAB_CX
+#undef OPTAB_CD
+#undef OPTAB_NL
+#undef OPTAB_NC
+#undef OPTAB_NX
+#undef OPTAB_VL
+#undef OPTAB_VC
+#undef OPTAB_VX
+#undef OPTAB_DC
+#undef OPTAB_D
+
+/* Vector in which to collect insns that match. */
+
+typedef struct pattern_d
+{
+ const char *name;
+ unsigned int op;
+ unsigned int m1, m2;
+ unsigned int sort_num;
+} pattern;
+
+DEF_VEC_O(pattern);
+DEF_VEC_ALLOC_O(pattern, heap);
+
+static VEC(pattern, heap) *patterns;
+
+static bool
+match_pattern (pattern *p, const char *name, const char *pat)
+{
+ bool force_float = false;
+ bool force_int = false;
+ bool force_partial_int = false;
+ bool force_fixed = false;
+
+ if (pat == NULL)
+ return false;
+ for (; ; ++pat)
+ {
+ if (*pat != '$')
+ {
+ if (*pat != *name++)
+ return false;
+ if (*pat == '\0')
+ return true;
+ continue;
+ }
+ switch (*++pat)
+ {
+ case 'I':
+ force_int = 1;
+ break;
+ case 'P':
+ force_partial_int = 1;
+ break;
+ case 'F':
+ force_float = 1;
+ break;
+ case 'Q':
+ force_fixed = 1;
+ break;
+
+ case 'a':
+ case 'b':
+ {
+ int i;
+
+ /* This loop will stop at the first prefix match, so
+ look through the modes in reverse order, in case
+ there are extra CC modes and CC is a prefix of the
+ CC modes (as it should be). */
+ for (i = (MAX_MACHINE_MODE) - 1; i >= 0; i--)
+ {
+ const char *p, *q;
+ for (p = GET_MODE_NAME(i), q = name; *p; p++, q++)
+ if (TOLOWER (*p) != *q)
+ break;
+ if (*p == 0
+ && (! force_int || mode_class[i] == MODE_INT
+ || mode_class[i] == MODE_VECTOR_INT)
+ && (! force_partial_int
+ || mode_class[i] == MODE_INT
+ || mode_class[i] == MODE_PARTIAL_INT
+ || mode_class[i] == MODE_VECTOR_INT)
+ && (! force_float
+ || mode_class[i] == MODE_FLOAT
+ || mode_class[i] == MODE_DECIMAL_FLOAT
+ || mode_class[i] == MODE_COMPLEX_FLOAT
+ || mode_class[i] == MODE_VECTOR_FLOAT)
+ && (! force_fixed
+ || mode_class[i] == MODE_FRACT
+ || mode_class[i] == MODE_UFRACT
+ || mode_class[i] == MODE_ACCUM
+ || mode_class[i] == MODE_UACCUM
+ || mode_class[i] == MODE_VECTOR_FRACT
+ || mode_class[i] == MODE_VECTOR_UFRACT
+ || mode_class[i] == MODE_VECTOR_ACCUM
+ || mode_class[i] == MODE_VECTOR_UACCUM))
+ break;
+ }
+
+ if (i < 0)
+ return false;
+ name += strlen (GET_MODE_NAME (i));
+ if (*pat == 'a')
+ p->m1 = i;
+ else
+ p->m2 = i;
+
+ force_int = false;
+ force_partial_int = false;
+ force_float = false;
+ force_fixed = false;
+ }
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+ }
+}
static void
gen_insn (rtx insn)
{
const char *name = XSTR (insn, 0);
- int m1 = 0, m2 = 0, op = 0;
- size_t pindex;
- int i;
- const char *np, *pp, *p, *q;
-
- /* Don't mention instructions whose names are the null string.
- They are in the machine description just to be recognized. */
- if (*name == 0)
- return;
+ pattern p;
+ unsigned pindex;
- /* See if NAME matches one of the patterns we have for the optabs we know
- about. */
+ /* Don't mention "unnamed" instructions. */
+ if (*name == 0 || *name == '*')
+ return;
+ p.name = name;
+ /* See if NAME matches one of the patterns we have for the optabs
+ we know about. */
for (pindex = 0; pindex < ARRAY_SIZE (optabs); pindex++)
{
- int force_float = 0, force_int = 0, force_partial_int = 0;
- int force_fixed = 0;
- int force_wider = 0;
- int matches = 1;
-
- for (pp = optabs[pindex]; pp[0] != '$' || pp[1] != '('; pp++)
- ;
-
- for (pp += 2, np = name; matches && ! (pp[0] == '$' && pp[1] == ')');
- pp++)
+ p.m1 = p.m2 = 0;
+ if (match_pattern (&p, name, optabs[pindex].pattern))
{
- if (*pp != '$')
- {
- if (*pp != *np++)
- break;
- }
- else
- switch (*++pp)
- {
- case 'N':
- force_wider = 1;
- break;
- case 'I':
- force_int = 1;
- break;
- case 'P':
- force_partial_int = 1;
- break;
- case 'F':
- force_float = 1;
- break;
- case 'Q':
- force_fixed = 1;
- break;
- case 'V':
- break;
- case 'c':
- for (op = 0; op < NUM_RTX_CODE; op++)
- {
- for (p = GET_RTX_NAME(op), q = np; *p; p++, q++)
- if (*p != *q)
- break;
-
- /* We have to be concerned about matching "gt" and
- missing "gtu", e.g., so verify we have reached the
- end of thing we are to match. */
- if (*p == 0 && *q == 0
- && (GET_RTX_CLASS (op) == RTX_COMPARE
- || GET_RTX_CLASS (op) == RTX_COMM_COMPARE))
- break;
- }
-
- if (op == NUM_RTX_CODE)
- matches = 0;
- else
- np += strlen (GET_RTX_NAME(op));
- break;
- case 'a':
- case 'b':
- /* This loop will stop at the first prefix match, so
- look through the modes in reverse order, in case
- there are extra CC modes and CC is a prefix of the
- CC modes (as it should be). */
- for (i = (MAX_MACHINE_MODE) - 1; i >= 0; i--)
- {
- for (p = GET_MODE_NAME(i), q = np; *p; p++, q++)
- if (TOLOWER (*p) != *q)
- break;
-
- if (*p == 0
- && (! force_int || mode_class[i] == MODE_INT
- || mode_class[i] == MODE_VECTOR_INT)
- && (! force_partial_int
- || mode_class[i] == MODE_INT
- || mode_class[i] == MODE_PARTIAL_INT
- || mode_class[i] == MODE_VECTOR_INT)
- && (! force_float
- || mode_class[i] == MODE_FLOAT
- || mode_class[i] == MODE_DECIMAL_FLOAT
- || mode_class[i] == MODE_COMPLEX_FLOAT
- || mode_class[i] == MODE_VECTOR_FLOAT)
- && (! force_fixed
- || mode_class[i] == MODE_FRACT
- || mode_class[i] == MODE_UFRACT
- || mode_class[i] == MODE_ACCUM
- || mode_class[i] == MODE_UACCUM
- || mode_class[i] == MODE_VECTOR_FRACT
- || mode_class[i] == MODE_VECTOR_UFRACT
- || mode_class[i] == MODE_VECTOR_ACCUM
- || mode_class[i] == MODE_VECTOR_UACCUM)
- && (! force_wider
- || *pp == 'a'
- || m1 < i))
- break;
- }
-
- if (i < 0)
- matches = 0;
- else if (*pp == 'a')
- m1 = i, np += strlen (GET_MODE_NAME(i));
- else
- m2 = i, np += strlen (GET_MODE_NAME(i));
-
- force_int = force_partial_int = force_float = force_fixed = 0;
- break;
-
- default:
- gcc_unreachable ();
- }
+ p.op = optabs[pindex].op;
+ p.sort_num = (p.op << 16) | (p.m2 << 8) | p.m1;
+ VEC_safe_push (pattern, heap, patterns, &p);
+ return;
}
-
- if (matches && pp[0] == '$' && pp[1] == ')'
- && *np == 0)
- break;
}
+}
- if (pindex == ARRAY_SIZE (optabs))
- return;
+static int
+pattern_cmp (const void *va, const void *vb)
+{
+ const pattern *a = (const pattern *)va;
+ const pattern *b = (const pattern *)vb;
+ return a->sort_num - b->sort_num;
+}
- /* We found a match. If this pattern is only conditionally present,
- write out the "if" and two extra blanks. */
+static int
+optab_kind_cmp (const void *va, const void *vb)
+{
+ const optab_def *a = (const optab_def *)va;
+ const optab_def *b = (const optab_def *)vb;
+ int diff = a->kind - b->kind;
+ if (diff == 0)
+ diff = a->op - b->op;
+ return diff;
+}
- if (*XSTR (insn, 2) != 0)
- printf (" if (HAVE_%s)\n ", name);
+static int
+optab_rcode_cmp (const void *va, const void *vb)
+{
+ const optab_def *a = (const optab_def *)va;
+ const optab_def *b = (const optab_def *)vb;
+ return a->rcode - b->rcode;
+}
- printf (" ");
+static const char *header_file_name = "init-opinit.h";
+static const char *source_file_name = "init-opinit.c";
- /* Now write out the initialization, making all required substitutions. */
- for (pp = optabs[pindex]; *pp; pp++)
+static bool
+handle_arg (const char *arg)
+{
+ switch (arg[1])
{
- if (*pp != '$')
- putchar (*pp);
- else
- switch (*++pp)
- {
- case '(': case ')':
- case 'I': case 'F': case 'N':
- break;
- case 'V':
- if (SCALAR_FLOAT_MODE_P (m1))
- printf ("v");
- break;
- case 'a':
- for (np = GET_MODE_NAME(m1); *np; np++)
- putchar (TOLOWER (*np));
- break;
- case 'b':
- for (np = GET_MODE_NAME(m2); *np; np++)
- putchar (TOLOWER (*np));
- break;
- case 'A':
- printf ("%smode", GET_MODE_NAME(m1));
- break;
- case 'B':
- printf ("%smode", GET_MODE_NAME(m2));
- break;
- case 'c':
- printf ("%s", GET_RTX_NAME(op));
- break;
- case 'C':
- for (np = GET_RTX_NAME(op); *np; np++)
- putchar (TOUPPER (*np));
- break;
- }
+ case 'h':
+ header_file_name = &arg[2];
+ return true;
+ case 'c':
+ source_file_name = &arg[2];
+ return true;
+ default:
+ return false;
}
-
- printf (";\n");
}
-extern int main (int, char **);
+static FILE *
+open_outfile (const char *file_name)
+{
+ FILE *f = fopen (file_name, "w");
+ if (!f)
+ fatal ("cannot open file %s: %s", file_name, xstrerror (errno));
+ fprintf (f,
+ "/* Generated automatically by the program `genopinit'\n"
+ " from the machine description file `md'. */\n\n");
+ return f;
+}
int
main (int argc, char **argv)
{
- rtx desc;
+ FILE *h_file, *s_file;
+ unsigned int i, j, n, last_kind[5];
+ pattern *p;
progname = "genopinit";
- if (!init_rtx_reader_args (argc, argv))
+ if (NUM_OPTABS > 0xffff || MAX_MACHINE_MODE >= 0xff)
+ fatal ("genopinit range assumptions invalid");
+
+ if (!init_rtx_reader_args_cb (argc, argv, handle_arg))
return (FATAL_EXIT_CODE);
- printf ("/* Generated automatically by the program `genopinit'\n\
-from the machine description file `md'. */\n\n");
-
- printf ("#include \"config.h\"\n");
- printf ("#include \"system.h\"\n");
- printf ("#include \"coretypes.h\"\n");
- printf ("#include \"tm.h\"\n");
- printf ("#include \"rtl.h\"\n");
- printf ("#include \"tm_p.h\"\n");
- printf ("#include \"flags.h\"\n");
- printf ("#include \"insn-config.h\"\n");
- printf ("#include \"recog.h\"\n");
- printf ("#include \"expr.h\"\n");
- printf ("#include \"optabs.h\"\n");
- printf ("#include \"reload.h\"\n\n");
-
- printf ("void\ninit_all_optabs (void)\n{\n");
-
- puts ("\
-#ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC\n\
- int i, j;\n\
-#endif\n");
+ h_file = open_outfile (header_file_name);
+ s_file = open_outfile (source_file_name);
/* Read the machine description. */
-
while (1)
{
int line_no, insn_code_number = 0;
-
- desc = read_md_rtx (&line_no, &insn_code_number);
+ rtx desc = read_md_rtx (&line_no, &insn_code_number);
if (desc == NULL)
break;
-
if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
gen_insn (desc);
}
- puts ("\
-\n\
-#ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC\n\
- /* This flag says the same insns that convert to a signed fixnum\n\
- also convert validly to an unsigned one. */\n\
- for (i = 0; i < NUM_MACHINE_MODES; i++)\n\
- for (j = 0; j < NUM_MACHINE_MODES; j++)\n\
- set_convert_optab_handler\n\
- (ufixtrunc_optab, (enum machine_mode) i, (enum machine_mode) j,\n\
- convert_optab_handler (sfixtrunc_optab, (enum machine_mode) i,\n\
- (enum machine_mode) j));\n\
-#endif\n\
-}");
-
- fflush (stdout);
- return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
+ /* Sort the collected patterns. */
+ qsort (VEC_address (pattern, patterns), VEC_length (pattern, patterns),
+ sizeof (pattern), pattern_cmp);
+
+ /* Now that we've handled the "extra" patterns, eliminate them from
+ the optabs array. That way they don't get in the way below. */
+ n = ARRAY_SIZE (optabs);
+ for (i = 0; i < n; )
+ if (optabs[i].base == NULL)
+ optabs[i] = optabs[--n];
+ else
+ ++i;
+
+ /* Sort the (real) optabs. Better than forcing the optabs.def file to
+ remain sorted by kind. We also scrogged any real ordering with the
+ purging of the X patterns above. */
+ qsort (optabs, n, sizeof(optab_def), optab_kind_cmp);
+
+ /* Emit the optab enumeration for the header file. */
+ fprintf (h_file, "enum optab_tag {\n");
+ for (i = j = 0; i < n; ++i)
+ {
+ optabs[i].op = i;
+ fprintf (h_file, " %s,\n", optabs[i].name);
+ if (optabs[i].kind != j)
+ last_kind[j++] = i - 1;
+ }
+ fprintf (h_file, " FIRST_CONV_OPTAB = %s,\n", optabs[last_kind[0]+1].name);
+ fprintf (h_file, " LAST_CONVLIB_OPTAB = %s,\n", optabs[last_kind[1]].name);
+ fprintf (h_file, " LAST_CONV_OPTAB = %s,\n", optabs[last_kind[2]].name);
+ fprintf (h_file, " FIRST_NORM_OPTAB = %s,\n", optabs[last_kind[2]+1].name);
+ fprintf (h_file, " LAST_NORMLIB_OPTAB = %s,\n", optabs[last_kind[3]].name);
+ fprintf (h_file, " LAST_NORM_OPTAB = %s\n", optabs[i-1].name);
+ fprintf (h_file, "};\n\n");
+
+ fprintf (h_file, "#define NUM_OPTABS %u\n", n);
+ fprintf (h_file, "#define NUM_CONVLIB_OPTABS %u\n",
+ last_kind[1] - last_kind[0]);
+ fprintf (h_file, "#define NUM_NORMLIB_OPTABS %u\n",
+ last_kind[3] - last_kind[2]);
+ fprintf (h_file, "#define NUM_OPTAB_PATTERNS %u\n",
+ (unsigned) VEC_length (pattern, patterns));
+
+ fprintf (s_file,
+ "#include \"config.h\"\n"
+ "#include \"system.h\"\n"
+ "#include \"coretypes.h\"\n"
+ "#include \"tm.h\"\n"
+ "#include \"rtl.h\"\n"
+ "#include \"tm_p.h\"\n"
+ "#include \"flags.h\"\n"
+ "#include \"insn-config.h\"\n"
+ "#include \"expr.h\"\n"
+ "#include \"optabs.h\"\n"
+ "\n"
+ "struct optab_pat {\n"
+ " unsigned scode;\n"
+ " enum insn_code icode;\n"
+ "};\n\n");
+
+ fprintf (s_file,
+ "static const struct optab_pat pats[NUM_OPTAB_PATTERNS] = {\n");
+ for (i = 0; VEC_iterate (pattern, patterns, i, p); ++i)
+ fprintf (s_file, " { %#08x, CODE_FOR_%s },\n", p->sort_num, p->name);
+ fprintf (s_file, "};\n\n");
+
+ fprintf (s_file, "void\ninit_all_optabs (void)\n{\n");
+ fprintf (s_file, " bool *ena = this_target_optabs->pat_enable;\n");
+ for (i = 0; VEC_iterate (pattern, patterns, i, p); ++i)
+ fprintf (s_file, " ena[%u] = HAVE_%s;\n", i, p->name);
+ fprintf (s_file, "}\n\n");
+
+ /* Perform a binary search on a pre-encoded optab+mode*2. */
+ /* ??? Perhaps even better to generate a minimal perfect hash.
+ Using gperf directly is awkward since it's so geared to working
+ with strings. Plus we have no visibility into the ordering of
+ the hash entries, which complicates the pat_enable array. */
+ fprintf (s_file,
+ "static int\n"
+ "lookup_handler (unsigned scode)\n"
+ "{\n"
+ " int l = 0, h = ARRAY_SIZE (pats), m;\n"
+ " while (h > l)\n"
+ " {\n"
+ " m = (h + l) / 2;\n"
+ " if (scode == pats[m].scode)\n"
+ " return m;\n"
+ " else if (scode < pats[m].scode)\n"
+ " h = m;\n"
+ " else\n"
+ " l = m + 1;\n"
+ " }\n"
+ " return -1;\n"
+ "}\n\n");
+
+ fprintf (s_file,
+ "enum insn_code\n"
+ "raw_optab_handler (unsigned scode)\n"
+ "{\n"
+ " int i = lookup_handler (scode);\n"
+ " return (i >= 0 && this_target_optabs->pat_enable[i]\n"
+ " ? pats[i].icode : CODE_FOR_nothing);\n"
+ "}\n\n");
+
+ fprintf (s_file,
+ "bool\n"
+ "swap_optab_enable (optab op, enum machine_mode m, bool set)\n"
+ "{\n"
+ " unsigned scode = (op << 16) | m;\n"
+ " int i = lookup_handler (scode);\n"
+ " if (i >= 0)\n"
+ " {\n"
+ " bool ret = this_target_optabs->pat_enable[i];\n"
+ " this_target_optabs->pat_enable[i] = set;\n"
+ " return ret;\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ " gcc_assert (!set);\n"
+ " return false;\n"
+ " }\n"
+ "}\n\n");
+
+ /* C++ (even G++) does not support (non-trivial) designated initializers.
+ To work around that, generate these arrays programatically rather than
+ by our traditional multiple inclusion of def files. */
+
+ fprintf (s_file,
+ "const struct convert_optab_libcall_d "
+ "convlib_def[NUM_CONVLIB_OPTABS] = {\n");
+ for (i = last_kind[0] + 1; i <= last_kind[1]; ++i)
+ fprintf (s_file, " { %s, %s },\n", optabs[i].base, optabs[i].libcall);
+ fprintf (s_file, "};\n\n");
+
+ fprintf (s_file,
+ "const struct optab_libcall_d "
+ "normlib_def[NUM_NORMLIB_OPTABS] = {\n");
+ for (i = last_kind[2] + 1; i <= last_kind[3]; ++i)
+ fprintf (s_file, " { %s, %s, %s },\n",
+ optabs[i].suffix, optabs[i].base, optabs[i].libcall);
+ fprintf (s_file, "};\n\n");
+
+ fprintf (s_file, "enum rtx_code const optab_to_code_[NUM_OPTABS] = {\n");
+ for (i = 0; i < n; ++i)
+ fprintf (s_file, " %s,\n", rtx_upname[optabs[i].fcode]);
+ fprintf (s_file, "};\n\n");
+
+ qsort (optabs, n, sizeof (optab_def), optab_rcode_cmp);
+
+ fprintf (s_file, "const optab code_to_optab_[NUM_RTX_CODE] = {\n");
+ for (j = 0; optabs[j].rcode == UNKNOWN; ++j)
+ continue;
+ for (i = 0; i < NON_GENERATOR_NUM_RTX_CODE; ++i)
+ {
+ if (j < n && optabs[j].rcode == i)
+ fprintf (s_file, " %s,\n", optabs[j++].name);
+ else
+ fprintf (s_file, " unknown_optab,\n");
+ }
+ fprintf (s_file, "};\n\n");
+
+ return (fclose (h_file) == 0 && fclose (s_file) == 0
+ ? SUCCESS_EXIT_CODE : FATAL_EXIT_CODE);
}
diff --git a/gcc/libfuncs.h b/gcc/libfuncs.h
index bac49182bbf..75f7a69f532 100644
--- a/gcc/libfuncs.h
+++ b/gcc/libfuncs.h
@@ -52,7 +52,7 @@ enum libfunc_index
for normal optabs and conversion optabs. In the first case mode2
is unused. */
struct GTY(()) libfunc_entry {
- size_t optab;
+ optab op;
enum machine_mode mode1, mode2;
rtx libfunc;
};
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 83509f99877..022adfa22f8 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -54,9 +54,6 @@ struct target_libfuncs *this_target_libfuncs = &default_target_libfuncs;
#define libfunc_hash \
(this_target_libfuncs->x_libfunc_hash)
-/* Contains the optab used for each rtx code. */
-optab code_to_optab_[NUM_RTX_CODE + 1];
-
static void prepare_float_lib_cmp (rtx, rtx, enum rtx_code, rtx *,
enum machine_mode *);
static rtx expand_unop_direct (enum machine_mode, optab, rtx, rtx, int);
@@ -78,9 +75,7 @@ static hashval_t
hash_libfunc (const void *p)
{
const struct libfunc_entry *const e = (const struct libfunc_entry *) p;
-
- return (((int) e->mode1 + (int) e->mode2 * NUM_MACHINE_MODES)
- ^ e->optab);
+ return (((int) e->mode1 + (int) e->mode2 * NUM_MACHINE_MODES) ^ e->op);
}
/* Used for libfunc_hash. */
@@ -90,10 +85,7 @@ eq_libfunc (const void *p, const void *q)
{
const struct libfunc_entry *const e1 = (const struct libfunc_entry *) p;
const struct libfunc_entry *const e2 = (const struct libfunc_entry *) q;
-
- return (e1->optab == e2->optab
- && e1->mode1 == e2->mode1
- && e1->mode2 == e2->mode2);
+ return e1->op == e2->op && e1->mode1 == e2->mode1 && e1->mode2 == e2->mode2;
}
/* Return libfunc corresponding operation defined by OPTAB converting
@@ -106,22 +98,30 @@ convert_optab_libfunc (convert_optab optab, enum machine_mode mode1,
struct libfunc_entry e;
struct libfunc_entry **slot;
- e.optab = (size_t) (optab - &convert_optab_table[0]);
+ /* ??? This ought to be an assert, but not all of the places
+ that we expand optabs know about the optabs that got moved
+ to being direct. */
+ if (!(optab >= FIRST_CONV_OPTAB && optab <= LAST_CONVLIB_OPTAB))
+ return NULL_RTX;
+
+ e.op = optab;
e.mode1 = mode1;
e.mode2 = mode2;
- slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash, &e, NO_INSERT);
+ slot = (struct libfunc_entry **)
+ htab_find_slot (libfunc_hash, &e, NO_INSERT);
if (!slot)
{
- if (optab->libcall_gen)
- {
- optab->libcall_gen (optab, optab->libcall_basename, mode1, mode2);
- slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash, &e, NO_INSERT);
- if (slot)
- return (*slot)->libfunc;
- else
- return NULL;
- }
- return NULL;
+ const struct convert_optab_libcall_d *d
+ = &convlib_def[optab - FIRST_CONV_OPTAB];
+
+ if (d->libcall_gen == NULL)
+ return NULL;
+
+ d->libcall_gen (optab, d->libcall_basename, mode1, mode2);
+ slot = (struct libfunc_entry **)
+ htab_find_slot (libfunc_hash, &e, NO_INSERT);
+ if (!slot)
+ return NULL;
}
return (*slot)->libfunc;
}
@@ -135,24 +135,30 @@ optab_libfunc (optab optab, enum machine_mode mode)
struct libfunc_entry e;
struct libfunc_entry **slot;
- e.optab = (size_t) (optab - &optab_table[0]);
+ /* ??? This ought to be an assert, but not all of the places
+ that we expand optabs know about the optabs that got moved
+ to being direct. */
+ if (!(optab >= FIRST_NORM_OPTAB && optab <= LAST_NORMLIB_OPTAB))
+ return NULL_RTX;
+
+ e.op = optab;
e.mode1 = mode;
e.mode2 = VOIDmode;
- slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash, &e, NO_INSERT);
+ slot = (struct libfunc_entry **)
+ htab_find_slot (libfunc_hash, &e, NO_INSERT);
if (!slot)
{
- if (optab->libcall_gen)
- {
- optab->libcall_gen (optab, optab->libcall_basename,
- optab->libcall_suffix, mode);
- slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash,
- &e, NO_INSERT);
- if (slot)
- return (*slot)->libfunc;
- else
- return NULL;
- }
- return NULL;
+ const struct optab_libcall_d *d
+ = &normlib_def[optab - FIRST_NORM_OPTAB];
+
+ if (d->libcall_gen == NULL)
+ return NULL;
+
+ d->libcall_gen (optab, d->libcall_basename, d->libcall_suffix, mode);
+ slot = (struct libfunc_entry **)
+ htab_find_slot (libfunc_hash, &e, NO_INSERT);
+ if (!slot)
+ return NULL;
}
return (*slot)->libfunc;
}
@@ -2227,7 +2233,7 @@ sign_expand_binop (enum machine_mode mode, optab uoptab, optab soptab,
{
rtx temp;
optab direct_optab = unsignedp ? uoptab : soptab;
- struct optab_d wide_soptab;
+ bool save_enable;
/* Do it without widening, if possible. */
temp = expand_binop (mode, direct_optab, op0, op1, target,
@@ -2235,38 +2241,38 @@ sign_expand_binop (enum machine_mode mode, optab uoptab, optab soptab,
if (temp || methods == OPTAB_DIRECT)
return temp;
- /* Try widening to a signed int. Make a fake signed optab that
- hides any signed insn for direct use. */
- wide_soptab = *soptab;
- set_optab_handler (&wide_soptab, mode, CODE_FOR_nothing);
- /* We don't want to generate new hash table entries from this fake
- optab. */
- wide_soptab.libcall_gen = NULL;
+ /* Try widening to a signed int. Disable any direct use of any
+ signed insn in the current mode. */
+ save_enable = swap_optab_enable (soptab, mode, false);
- temp = expand_binop (mode, &wide_soptab, op0, op1, target,
+ temp = expand_binop (mode, soptab, op0, op1, target,
unsignedp, OPTAB_WIDEN);
/* For unsigned operands, try widening to an unsigned int. */
- if (temp == 0 && unsignedp)
+ if (!temp && unsignedp)
temp = expand_binop (mode, uoptab, op0, op1, target,
unsignedp, OPTAB_WIDEN);
if (temp || methods == OPTAB_WIDEN)
- return temp;
+ goto egress;
/* Use the right width libcall if that exists. */
- temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
+ temp = expand_binop (mode, direct_optab, op0, op1, target,
+ unsignedp, OPTAB_LIB);
if (temp || methods == OPTAB_LIB)
- return temp;
+ goto egress;
/* Must widen and use a libcall, use either signed or unsigned. */
- temp = expand_binop (mode, &wide_soptab, op0, op1, target,
+ temp = expand_binop (mode, soptab, op0, op1, target,
unsignedp, methods);
- if (temp != 0)
- return temp;
- if (unsignedp)
- return expand_binop (mode, uoptab, op0, op1, target,
+ if (!temp && unsignedp)
+ temp = expand_binop (mode, uoptab, op0, op1, target,
unsignedp, methods);
- return 0;
+
+ egress:
+ /* Undo the fiddling above. */
+ if (save_enable)
+ swap_optab_enable (soptab, mode, true);
+ return temp;
}
/* Generate code to perform an operation specified by UNOPPTAB
@@ -5415,39 +5421,6 @@ have_insn_for (enum rtx_code code, enum machine_mode mode)
!= CODE_FOR_nothing));
}
-/* Set all insn_code fields to CODE_FOR_nothing. */
-
-static void
-init_insn_codes (void)
-{
- memset (optab_table, 0, sizeof (optab_table));
- memset (convert_optab_table, 0, sizeof (convert_optab_table));
- memset (direct_optab_table, 0, sizeof (direct_optab_table));
-}
-
-/* Initialize OP's code to CODE, and write it into the code_to_optab table. */
-static inline void
-init_optab (optab op, enum rtx_code code)
-{
- op->code_ = code;
- code_to_optab_[(int) code] = op;
-}
-
-/* Same, but fill in its code as CODE, and do _not_ write it into
- the code_to_optab table. */
-static inline void
-init_optabv (optab op, enum rtx_code code)
-{
- op->code_ = code;
-}
-
-/* Conversion optabs never go in the code_to_optab table. */
-static void
-init_convert_optab (convert_optab op, enum rtx_code code)
-{
- op->code_ = code;
-}
-
/* Initialize the libfunc fields of an entire group of entries in some
optab. Each entry is set equal to a string consisting of a leading
pair of underscores followed by a generic operation name followed by
@@ -5463,7 +5436,8 @@ init_convert_optab (convert_optab op, enum rtx_code code)
*/
static void
-gen_libfunc (optab optable, const char *opname, int suffix, enum machine_mode mode)
+gen_libfunc (optab optable, const char *opname, int suffix,
+ enum machine_mode mode)
{
unsigned opname_len = strlen (opname);
const char *mname = GET_MODE_NAME (mode);
@@ -5497,7 +5471,7 @@ gen_libfunc (optab optable, const char *opname, int suffix, enum machine_mode mo
/* Like gen_libfunc, but verify that integer operation is involved. */
-static void
+void
gen_int_libfunc (optab optable, const char *opname, char suffix,
enum machine_mode mode)
{
@@ -5515,7 +5489,7 @@ gen_int_libfunc (optab optable, const char *opname, char suffix,
/* Like gen_libfunc, but verify that FP and set decimal prefix if needed. */
-static void
+void
gen_fp_libfunc (optab optable, const char *opname, char suffix,
enum machine_mode mode)
{
@@ -5536,7 +5510,7 @@ gen_fp_libfunc (optab optable, const char *opname, char suffix,
/* Like gen_libfunc, but verify that fixed-point operation is involved. */
-static void
+void
gen_fixed_libfunc (optab optable, const char *opname, char suffix,
enum machine_mode mode)
{
@@ -5548,7 +5522,7 @@ gen_fixed_libfunc (optab optable, const char *opname, char suffix,
/* Like gen_libfunc, but verify that signed fixed-point operation is
involved. */
-static void
+void
gen_signed_fixed_libfunc (optab optable, const char *opname, char suffix,
enum machine_mode mode)
{
@@ -5560,7 +5534,7 @@ gen_signed_fixed_libfunc (optab optable, const char *opname, char suffix,
/* Like gen_libfunc, but verify that unsigned fixed-point operation is
involved. */
-static void
+void
gen_unsigned_fixed_libfunc (optab optable, const char *opname, char suffix,
enum machine_mode mode)
{
@@ -5571,7 +5545,7 @@ gen_unsigned_fixed_libfunc (optab optable, const char *opname, char suffix,
/* Like gen_libfunc, but verify that FP or INT operation is involved. */
-static void
+void
gen_int_fp_libfunc (optab optable, const char *name, char suffix,
enum machine_mode mode)
{
@@ -5584,7 +5558,7 @@ gen_int_fp_libfunc (optab optable, const char *name, char suffix,
/* Like gen_libfunc, but verify that FP or INT operation is involved
and add 'v' suffix for integer operation. */
-static void
+void
gen_intv_fp_libfunc (optab optable, const char *name, char suffix,
enum machine_mode mode)
{
@@ -5604,7 +5578,7 @@ gen_intv_fp_libfunc (optab optable, const char *name, char suffix,
/* Like gen_libfunc, but verify that FP or INT or FIXED operation is
involved. */
-static void
+void
gen_int_fp_fixed_libfunc (optab optable, const char *name, char suffix,
enum machine_mode mode)
{
@@ -5619,7 +5593,7 @@ gen_int_fp_fixed_libfunc (optab optable, const char *name, char suffix,
/* Like gen_libfunc, but verify that FP or INT or signed FIXED operation is
involved. */
-static void
+void
gen_int_fp_signed_fixed_libfunc (optab optable, const char *name, char suffix,
enum machine_mode mode)
{
@@ -5634,7 +5608,7 @@ gen_int_fp_signed_fixed_libfunc (optab optable, const char *name, char suffix,
/* Like gen_libfunc, but verify that INT or FIXED operation is
involved. */
-static void
+void
gen_int_fixed_libfunc (optab optable, const char *name, char suffix,
enum machine_mode mode)
{
@@ -5647,7 +5621,7 @@ gen_int_fixed_libfunc (optab optable, const char *name, char suffix,
/* Like gen_libfunc, but verify that INT or signed FIXED operation is
involved. */
-static void
+void
gen_int_signed_fixed_libfunc (optab optable, const char *name, char suffix,
enum machine_mode mode)
{
@@ -5660,7 +5634,7 @@ gen_int_signed_fixed_libfunc (optab optable, const char *name, char suffix,
/* Like gen_libfunc, but verify that INT or unsigned FIXED operation is
involved. */
-static void
+void
gen_int_unsigned_fixed_libfunc (optab optable, const char *name, char suffix,
enum machine_mode mode)
{
@@ -5676,7 +5650,7 @@ gen_int_unsigned_fixed_libfunc (optab optable, const char *name, char suffix,
a mode name and an operand count these functions have two mode names
and no operand count. */
-static void
+void
gen_interclass_conv_libfunc (convert_optab tab,
const char *opname,
enum machine_mode tmode,
@@ -5748,7 +5722,7 @@ gen_interclass_conv_libfunc (convert_optab tab,
/* Same as gen_interclass_conv_libfunc but verify that we are producing
int->fp conversion. */
-static void
+void
gen_int_to_fp_conv_libfunc (convert_optab tab,
const char *opname,
enum machine_mode tmode,
@@ -5764,7 +5738,7 @@ gen_int_to_fp_conv_libfunc (convert_optab tab,
/* ufloat_optab is special by using floatun for FP and floatuns decimal fp
naming scheme. */
-static void
+void
gen_ufloat_conv_libfunc (convert_optab tab,
const char *opname ATTRIBUTE_UNUSED,
enum machine_mode tmode,
@@ -5779,7 +5753,7 @@ gen_ufloat_conv_libfunc (convert_optab tab,
/* Same as gen_interclass_conv_libfunc but verify that we are producing
fp->int conversion. */
-static void
+void
gen_int_to_fp_nondecimal_conv_libfunc (convert_optab tab,
const char *opname,
enum machine_mode tmode,
@@ -5795,7 +5769,7 @@ gen_int_to_fp_nondecimal_conv_libfunc (convert_optab tab,
/* Same as gen_interclass_conv_libfunc but verify that we are producing
fp->int conversion with no decimal floating point involved. */
-static void
+void
gen_fp_to_int_conv_libfunc (convert_optab tab,
const char *opname,
enum machine_mode tmode,
@@ -5812,7 +5786,7 @@ gen_fp_to_int_conv_libfunc (convert_optab tab,
The string formation rules are
similar to the ones for init_libfunc, above. */
-static void
+void
gen_intraclass_conv_libfunc (convert_optab tab, const char *opname,
enum machine_mode tmode, enum machine_mode fmode)
{
@@ -5882,7 +5856,7 @@ gen_intraclass_conv_libfunc (convert_optab tab, const char *opname,
/* Pick proper libcall for trunc_optab. We need to chose if we do
truncation or extension and interclass or intraclass. */
-static void
+void
gen_trunc_conv_libfunc (convert_optab tab,
const char *opname,
enum machine_mode tmode,
@@ -5911,7 +5885,7 @@ gen_trunc_conv_libfunc (convert_optab tab,
/* Pick proper libcall for extend_optab. We need to chose if we do
truncation or extension and interclass or intraclass. */
-static void
+void
gen_extend_conv_libfunc (convert_optab tab,
const char *opname ATTRIBUTE_UNUSED,
enum machine_mode tmode,
@@ -5940,7 +5914,7 @@ gen_extend_conv_libfunc (convert_optab tab,
/* Pick proper libcall for fract_optab. We need to chose if we do
interclass or intraclass. */
-static void
+void
gen_fract_conv_libfunc (convert_optab tab,
const char *opname,
enum machine_mode tmode,
@@ -5959,7 +5933,7 @@ gen_fract_conv_libfunc (convert_optab tab,
/* Pick proper libcall for fractuns_optab. */
-static void
+void
gen_fractuns_conv_libfunc (convert_optab tab,
const char *opname,
enum machine_mode tmode,
@@ -5980,7 +5954,7 @@ gen_fractuns_conv_libfunc (convert_optab tab,
/* Pick proper libcall for satfract_optab. We need to chose if we do
interclass or intraclass. */
-static void
+void
gen_satfract_conv_libfunc (convert_optab tab,
const char *opname,
enum machine_mode tmode,
@@ -6000,7 +5974,7 @@ gen_satfract_conv_libfunc (convert_optab tab,
/* Pick proper libcall for satfractuns_optab. */
-static void
+void
gen_satfractuns_conv_libfunc (convert_optab tab,
const char *opname,
enum machine_mode tmode,
@@ -6101,12 +6075,13 @@ set_user_assembler_libfunc (const char *name, const char *asmspec)
/* Call this to reset the function entry for one optab (OPTABLE) in mode
MODE to NAME, which should be either 0 or a string constant. */
void
-set_optab_libfunc (optab optable, enum machine_mode mode, const char *name)
+set_optab_libfunc (optab op, enum machine_mode mode, const char *name)
{
rtx val;
struct libfunc_entry e;
struct libfunc_entry **slot;
- e.optab = (size_t) (optable - &optab_table[0]);
+
+ e.op = op;
e.mode1 = mode;
e.mode2 = VOIDmode;
@@ -6117,7 +6092,7 @@ set_optab_libfunc (optab optable, enum machine_mode mode, const char *name)
slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash, &e, INSERT);
if (*slot == NULL)
*slot = ggc_alloc_libfunc_entry ();
- (*slot)->optab = (size_t) (optable - &optab_table[0]);
+ (*slot)->op = op;
(*slot)->mode1 = mode;
(*slot)->mode2 = VOIDmode;
(*slot)->libfunc = val;
@@ -6127,13 +6102,14 @@ set_optab_libfunc (optab optable, enum machine_mode mode, const char *name)
(OPTABLE) from mode FMODE to mode TMODE to NAME, which should be
either 0 or a string constant. */
void
-set_conv_libfunc (convert_optab optable, enum machine_mode tmode,
+set_conv_libfunc (convert_optab optab, enum machine_mode tmode,
enum machine_mode fmode, const char *name)
{
rtx val;
struct libfunc_entry e;
struct libfunc_entry **slot;
- e.optab = (size_t) (optable - &convert_optab_table[0]);
+
+ e.op = optab;
e.mode1 = tmode;
e.mode2 = fmode;
@@ -6144,7 +6120,7 @@ set_conv_libfunc (convert_optab optable, enum machine_mode tmode,
slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash, &e, INSERT);
if (*slot == NULL)
*slot = ggc_alloc_libfunc_entry ();
- (*slot)->optab = (size_t) (optable - &convert_optab_table[0]);
+ (*slot)->op = optab;
(*slot)->mode1 = tmode;
(*slot)->mode2 = fmode;
(*slot)->libfunc = val;
@@ -6157,421 +6133,13 @@ void
init_optabs (void)
{
if (libfunc_hash)
- {
- htab_empty (libfunc_hash);
- /* We statically initialize the insn_codes with the equivalent of
- CODE_FOR_nothing. Repeat the process if reinitialising. */
- init_insn_codes ();
- }
+ htab_empty (libfunc_hash);
else
libfunc_hash = htab_create_ggc (10, hash_libfunc, eq_libfunc, NULL);
- init_optab (add_optab, PLUS);
- init_optabv (addv_optab, PLUS);
- init_optab (sub_optab, MINUS);
- init_optabv (subv_optab, MINUS);
- init_optab (ssadd_optab, SS_PLUS);
- init_optab (usadd_optab, US_PLUS);
- init_optab (sssub_optab, SS_MINUS);
- init_optab (ussub_optab, US_MINUS);
- init_optab (smul_optab, MULT);
- init_optab (ssmul_optab, SS_MULT);
- init_optab (usmul_optab, US_MULT);
- init_optabv (smulv_optab, MULT);
- init_optab (smul_highpart_optab, UNKNOWN);
- init_optab (umul_highpart_optab, UNKNOWN);
- init_optab (smul_widen_optab, UNKNOWN);
- init_optab (umul_widen_optab, UNKNOWN);
- init_optab (usmul_widen_optab, UNKNOWN);
- init_optab (smadd_widen_optab, UNKNOWN);
- init_optab (umadd_widen_optab, UNKNOWN);
- init_optab (ssmadd_widen_optab, UNKNOWN);
- init_optab (usmadd_widen_optab, UNKNOWN);
- init_optab (smsub_widen_optab, UNKNOWN);
- init_optab (umsub_widen_optab, UNKNOWN);
- init_optab (ssmsub_widen_optab, UNKNOWN);
- init_optab (usmsub_widen_optab, UNKNOWN);
- init_optab (sdiv_optab, DIV);
- init_optab (ssdiv_optab, SS_DIV);
- init_optab (usdiv_optab, US_DIV);
- init_optabv (sdivv_optab, DIV);
- init_optab (sdivmod_optab, UNKNOWN);
- init_optab (udiv_optab, UDIV);
- init_optab (udivmod_optab, UNKNOWN);
- init_optab (smod_optab, MOD);
- init_optab (umod_optab, UMOD);
- init_optab (fmod_optab, UNKNOWN);
- init_optab (remainder_optab, UNKNOWN);
- init_optab (ftrunc_optab, UNKNOWN);
- init_optab (and_optab, AND);
- init_optab (ior_optab, IOR);
- init_optab (xor_optab, XOR);
- init_optab (ashl_optab, ASHIFT);
- init_optab (ssashl_optab, SS_ASHIFT);
- init_optab (usashl_optab, US_ASHIFT);
- init_optab (ashr_optab, ASHIFTRT);
- init_optab (lshr_optab, LSHIFTRT);
- init_optabv (vashl_optab, ASHIFT);
- init_optabv (vashr_optab, ASHIFTRT);
- init_optabv (vlshr_optab, LSHIFTRT);
- init_optab (rotl_optab, ROTATE);
- init_optab (rotr_optab, ROTATERT);
- init_optab (smin_optab, SMIN);
- init_optab (smax_optab, SMAX);
- init_optab (umin_optab, UMIN);
- init_optab (umax_optab, UMAX);
- init_optab (pow_optab, UNKNOWN);
- init_optab (atan2_optab, UNKNOWN);
- init_optab (fma_optab, FMA);
- init_optab (fms_optab, UNKNOWN);
- init_optab (fnma_optab, UNKNOWN);
- init_optab (fnms_optab, UNKNOWN);
-
- /* These three have codes assigned exclusively for the sake of
- have_insn_for. */
- init_optab (mov_optab, SET);
- init_optab (movstrict_optab, STRICT_LOW_PART);
- init_optab (cbranch_optab, COMPARE);
-
- init_optab (cmov_optab, UNKNOWN);
- init_optab (cstore_optab, UNKNOWN);
- init_optab (ctrap_optab, UNKNOWN);
-
- init_optab (storent_optab, UNKNOWN);
-
- init_optab (cmp_optab, UNKNOWN);
- init_optab (ucmp_optab, UNKNOWN);
-
- init_optab (eq_optab, EQ);
- init_optab (ne_optab, NE);
- init_optab (gt_optab, GT);
- init_optab (ge_optab, GE);
- init_optab (lt_optab, LT);
- init_optab (le_optab, LE);
- init_optab (unord_optab, UNORDERED);
-
- init_optab (neg_optab, NEG);
- init_optab (ssneg_optab, SS_NEG);
- init_optab (usneg_optab, US_NEG);
- init_optabv (negv_optab, NEG);
- init_optab (abs_optab, ABS);
- init_optabv (absv_optab, ABS);
- init_optab (addcc_optab, UNKNOWN);
- init_optab (one_cmpl_optab, NOT);
- init_optab (bswap_optab, BSWAP);
- init_optab (ffs_optab, FFS);
- init_optab (clz_optab, CLZ);
- init_optab (ctz_optab, CTZ);
- init_optab (clrsb_optab, CLRSB);
- init_optab (popcount_optab, POPCOUNT);
- init_optab (parity_optab, PARITY);
- init_optab (sqrt_optab, SQRT);
- init_optab (floor_optab, UNKNOWN);
- init_optab (ceil_optab, UNKNOWN);
- init_optab (round_optab, UNKNOWN);
- init_optab (btrunc_optab, UNKNOWN);
- init_optab (nearbyint_optab, UNKNOWN);
- init_optab (rint_optab, UNKNOWN);
- init_optab (sincos_optab, UNKNOWN);
- init_optab (sin_optab, UNKNOWN);
- init_optab (asin_optab, UNKNOWN);
- init_optab (cos_optab, UNKNOWN);
- init_optab (acos_optab, UNKNOWN);
- init_optab (exp_optab, UNKNOWN);
- init_optab (exp10_optab, UNKNOWN);
- init_optab (exp2_optab, UNKNOWN);
- init_optab (expm1_optab, UNKNOWN);
- init_optab (ldexp_optab, UNKNOWN);
- init_optab (scalb_optab, UNKNOWN);
- init_optab (significand_optab, UNKNOWN);
- init_optab (logb_optab, UNKNOWN);
- init_optab (ilogb_optab, UNKNOWN);
- init_optab (log_optab, UNKNOWN);
- init_optab (log10_optab, UNKNOWN);
- init_optab (log2_optab, UNKNOWN);
- init_optab (log1p_optab, UNKNOWN);
- init_optab (tan_optab, UNKNOWN);
- init_optab (atan_optab, UNKNOWN);
- init_optab (copysign_optab, UNKNOWN);
- init_optab (signbit_optab, UNKNOWN);
-
- init_optab (isinf_optab, UNKNOWN);
-
- init_optab (strlen_optab, UNKNOWN);
- init_optab (push_optab, UNKNOWN);
-
- init_optab (reduc_smax_optab, UNKNOWN);
- init_optab (reduc_umax_optab, UNKNOWN);
- init_optab (reduc_smin_optab, UNKNOWN);
- init_optab (reduc_umin_optab, UNKNOWN);
- init_optab (reduc_splus_optab, UNKNOWN);
- init_optab (reduc_uplus_optab, UNKNOWN);
-
- init_optab (ssum_widen_optab, UNKNOWN);
- init_optab (usum_widen_optab, UNKNOWN);
- init_optab (sdot_prod_optab, UNKNOWN);
- init_optab (udot_prod_optab, UNKNOWN);
-
- init_optab (vec_extract_optab, UNKNOWN);
- init_optab (vec_set_optab, UNKNOWN);
- init_optab (vec_init_optab, UNKNOWN);
- init_optab (vec_shl_optab, UNKNOWN);
- init_optab (vec_shr_optab, UNKNOWN);
- init_optab (vec_realign_load_optab, UNKNOWN);
- init_optab (movmisalign_optab, UNKNOWN);
- init_optab (vec_widen_umult_hi_optab, UNKNOWN);
- init_optab (vec_widen_umult_lo_optab, UNKNOWN);
- init_optab (vec_widen_smult_hi_optab, UNKNOWN);
- init_optab (vec_widen_smult_lo_optab, UNKNOWN);
- init_optab (vec_widen_ushiftl_hi_optab, UNKNOWN);
- init_optab (vec_widen_ushiftl_lo_optab, UNKNOWN);
- init_optab (vec_widen_sshiftl_hi_optab, UNKNOWN);
- init_optab (vec_widen_sshiftl_lo_optab, UNKNOWN);
- init_optab (vec_unpacks_hi_optab, UNKNOWN);
- init_optab (vec_unpacks_lo_optab, UNKNOWN);
- init_optab (vec_unpacku_hi_optab, UNKNOWN);
- init_optab (vec_unpacku_lo_optab, UNKNOWN);
- init_optab (vec_unpacks_float_hi_optab, UNKNOWN);
- init_optab (vec_unpacks_float_lo_optab, UNKNOWN);
- init_optab (vec_unpacku_float_hi_optab, UNKNOWN);
- init_optab (vec_unpacku_float_lo_optab, UNKNOWN);
- init_optab (vec_pack_trunc_optab, UNKNOWN);
- init_optab (vec_pack_usat_optab, UNKNOWN);
- init_optab (vec_pack_ssat_optab, UNKNOWN);
- init_optab (vec_pack_ufix_trunc_optab, UNKNOWN);
- init_optab (vec_pack_sfix_trunc_optab, UNKNOWN);
-
- init_optab (powi_optab, UNKNOWN);
-
- /* Conversions. */
- init_convert_optab (sext_optab, SIGN_EXTEND);
- init_convert_optab (zext_optab, ZERO_EXTEND);
- init_convert_optab (trunc_optab, TRUNCATE);
- init_convert_optab (sfix_optab, FIX);
- init_convert_optab (ufix_optab, UNSIGNED_FIX);
- init_convert_optab (sfixtrunc_optab, UNKNOWN);
- init_convert_optab (ufixtrunc_optab, UNKNOWN);
- init_convert_optab (sfloat_optab, FLOAT);
- init_convert_optab (ufloat_optab, UNSIGNED_FLOAT);
- init_convert_optab (lrint_optab, UNKNOWN);
- init_convert_optab (lround_optab, UNKNOWN);
- init_convert_optab (lfloor_optab, UNKNOWN);
- init_convert_optab (lceil_optab, UNKNOWN);
-
- init_convert_optab (fract_optab, FRACT_CONVERT);
- init_convert_optab (fractuns_optab, UNSIGNED_FRACT_CONVERT);
- init_convert_optab (satfract_optab, SAT_FRACT);
- init_convert_optab (satfractuns_optab, UNSIGNED_SAT_FRACT);
-
/* Fill in the optabs with the insns we support. */
init_all_optabs ();
- /* Initialize the optabs with the names of the library functions. */
- add_optab->libcall_basename = "add";
- add_optab->libcall_suffix = '3';
- add_optab->libcall_gen = gen_int_fp_fixed_libfunc;
- addv_optab->libcall_basename = "add";
- addv_optab->libcall_suffix = '3';
- addv_optab->libcall_gen = gen_intv_fp_libfunc;
- ssadd_optab->libcall_basename = "ssadd";
- ssadd_optab->libcall_suffix = '3';
- ssadd_optab->libcall_gen = gen_signed_fixed_libfunc;
- usadd_optab->libcall_basename = "usadd";
- usadd_optab->libcall_suffix = '3';
- usadd_optab->libcall_gen = gen_unsigned_fixed_libfunc;
- sub_optab->libcall_basename = "sub";
- sub_optab->libcall_suffix = '3';
- sub_optab->libcall_gen = gen_int_fp_fixed_libfunc;
- subv_optab->libcall_basename = "sub";
- subv_optab->libcall_suffix = '3';
- subv_optab->libcall_gen = gen_intv_fp_libfunc;
- sssub_optab->libcall_basename = "sssub";
- sssub_optab->libcall_suffix = '3';
- sssub_optab->libcall_gen = gen_signed_fixed_libfunc;
- ussub_optab->libcall_basename = "ussub";
- ussub_optab->libcall_suffix = '3';
- ussub_optab->libcall_gen = gen_unsigned_fixed_libfunc;
- smul_optab->libcall_basename = "mul";
- smul_optab->libcall_suffix = '3';
- smul_optab->libcall_gen = gen_int_fp_fixed_libfunc;
- smulv_optab->libcall_basename = "mul";
- smulv_optab->libcall_suffix = '3';
- smulv_optab->libcall_gen = gen_intv_fp_libfunc;
- ssmul_optab->libcall_basename = "ssmul";
- ssmul_optab->libcall_suffix = '3';
- ssmul_optab->libcall_gen = gen_signed_fixed_libfunc;
- usmul_optab->libcall_basename = "usmul";
- usmul_optab->libcall_suffix = '3';
- usmul_optab->libcall_gen = gen_unsigned_fixed_libfunc;
- sdiv_optab->libcall_basename = "div";
- sdiv_optab->libcall_suffix = '3';
- sdiv_optab->libcall_gen = gen_int_fp_signed_fixed_libfunc;
- sdivv_optab->libcall_basename = "divv";
- sdivv_optab->libcall_suffix = '3';
- sdivv_optab->libcall_gen = gen_int_libfunc;
- ssdiv_optab->libcall_basename = "ssdiv";
- ssdiv_optab->libcall_suffix = '3';
- ssdiv_optab->libcall_gen = gen_signed_fixed_libfunc;
- udiv_optab->libcall_basename = "udiv";
- udiv_optab->libcall_suffix = '3';
- udiv_optab->libcall_gen = gen_int_unsigned_fixed_libfunc;
- usdiv_optab->libcall_basename = "usdiv";
- usdiv_optab->libcall_suffix = '3';
- usdiv_optab->libcall_gen = gen_unsigned_fixed_libfunc;
- sdivmod_optab->libcall_basename = "divmod";
- sdivmod_optab->libcall_suffix = '4';
- sdivmod_optab->libcall_gen = gen_int_libfunc;
- udivmod_optab->libcall_basename = "udivmod";
- udivmod_optab->libcall_suffix = '4';
- udivmod_optab->libcall_gen = gen_int_libfunc;
- smod_optab->libcall_basename = "mod";
- smod_optab->libcall_suffix = '3';
- smod_optab->libcall_gen = gen_int_libfunc;
- umod_optab->libcall_basename = "umod";
- umod_optab->libcall_suffix = '3';
- umod_optab->libcall_gen = gen_int_libfunc;
- ftrunc_optab->libcall_basename = "ftrunc";
- ftrunc_optab->libcall_suffix = '2';
- ftrunc_optab->libcall_gen = gen_fp_libfunc;
- and_optab->libcall_basename = "and";
- and_optab->libcall_suffix = '3';
- and_optab->libcall_gen = gen_int_libfunc;
- ior_optab->libcall_basename = "ior";
- ior_optab->libcall_suffix = '3';
- ior_optab->libcall_gen = gen_int_libfunc;
- xor_optab->libcall_basename = "xor";
- xor_optab->libcall_suffix = '3';
- xor_optab->libcall_gen = gen_int_libfunc;
- ashl_optab->libcall_basename = "ashl";
- ashl_optab->libcall_suffix = '3';
- ashl_optab->libcall_gen = gen_int_fixed_libfunc;
- ssashl_optab->libcall_basename = "ssashl";
- ssashl_optab->libcall_suffix = '3';
- ssashl_optab->libcall_gen = gen_signed_fixed_libfunc;
- usashl_optab->libcall_basename = "usashl";
- usashl_optab->libcall_suffix = '3';
- usashl_optab->libcall_gen = gen_unsigned_fixed_libfunc;
- ashr_optab->libcall_basename = "ashr";
- ashr_optab->libcall_suffix = '3';
- ashr_optab->libcall_gen = gen_int_signed_fixed_libfunc;
- lshr_optab->libcall_basename = "lshr";
- lshr_optab->libcall_suffix = '3';
- lshr_optab->libcall_gen = gen_int_unsigned_fixed_libfunc;
- smin_optab->libcall_basename = "min";
- smin_optab->libcall_suffix = '3';
- smin_optab->libcall_gen = gen_int_fp_libfunc;
- smax_optab->libcall_basename = "max";
- smax_optab->libcall_suffix = '3';
- smax_optab->libcall_gen = gen_int_fp_libfunc;
- umin_optab->libcall_basename = "umin";
- umin_optab->libcall_suffix = '3';
- umin_optab->libcall_gen = gen_int_libfunc;
- umax_optab->libcall_basename = "umax";
- umax_optab->libcall_suffix = '3';
- umax_optab->libcall_gen = gen_int_libfunc;
- neg_optab->libcall_basename = "neg";
- neg_optab->libcall_suffix = '2';
- neg_optab->libcall_gen = gen_int_fp_fixed_libfunc;
- ssneg_optab->libcall_basename = "ssneg";
- ssneg_optab->libcall_suffix = '2';
- ssneg_optab->libcall_gen = gen_signed_fixed_libfunc;
- usneg_optab->libcall_basename = "usneg";
- usneg_optab->libcall_suffix = '2';
- usneg_optab->libcall_gen = gen_unsigned_fixed_libfunc;
- negv_optab->libcall_basename = "neg";
- negv_optab->libcall_suffix = '2';
- negv_optab->libcall_gen = gen_intv_fp_libfunc;
- one_cmpl_optab->libcall_basename = "one_cmpl";
- one_cmpl_optab->libcall_suffix = '2';
- one_cmpl_optab->libcall_gen = gen_int_libfunc;
- ffs_optab->libcall_basename = "ffs";
- ffs_optab->libcall_suffix = '2';
- ffs_optab->libcall_gen = gen_int_libfunc;
- clz_optab->libcall_basename = "clz";
- clz_optab->libcall_suffix = '2';
- clz_optab->libcall_gen = gen_int_libfunc;
- ctz_optab->libcall_basename = "ctz";
- ctz_optab->libcall_suffix = '2';
- ctz_optab->libcall_gen = gen_int_libfunc;
- clrsb_optab->libcall_basename = "clrsb";
- clrsb_optab->libcall_suffix = '2';
- clrsb_optab->libcall_gen = gen_int_libfunc;
- popcount_optab->libcall_basename = "popcount";
- popcount_optab->libcall_suffix = '2';
- popcount_optab->libcall_gen = gen_int_libfunc;
- parity_optab->libcall_basename = "parity";
- parity_optab->libcall_suffix = '2';
- parity_optab->libcall_gen = gen_int_libfunc;
-
- /* Comparison libcalls for integers MUST come in pairs,
- signed/unsigned. */
- cmp_optab->libcall_basename = "cmp";
- cmp_optab->libcall_suffix = '2';
- cmp_optab->libcall_gen = gen_int_fp_fixed_libfunc;
- ucmp_optab->libcall_basename = "ucmp";
- ucmp_optab->libcall_suffix = '2';
- ucmp_optab->libcall_gen = gen_int_libfunc;
-
- /* EQ etc are floating point only. */
- eq_optab->libcall_basename = "eq";
- eq_optab->libcall_suffix = '2';
- eq_optab->libcall_gen = gen_fp_libfunc;
- ne_optab->libcall_basename = "ne";
- ne_optab->libcall_suffix = '2';
- ne_optab->libcall_gen = gen_fp_libfunc;
- gt_optab->libcall_basename = "gt";
- gt_optab->libcall_suffix = '2';
- gt_optab->libcall_gen = gen_fp_libfunc;
- ge_optab->libcall_basename = "ge";
- ge_optab->libcall_suffix = '2';
- ge_optab->libcall_gen = gen_fp_libfunc;
- lt_optab->libcall_basename = "lt";
- lt_optab->libcall_suffix = '2';
- lt_optab->libcall_gen = gen_fp_libfunc;
- le_optab->libcall_basename = "le";
- le_optab->libcall_suffix = '2';
- le_optab->libcall_gen = gen_fp_libfunc;
- unord_optab->libcall_basename = "unord";
- unord_optab->libcall_suffix = '2';
- unord_optab->libcall_gen = gen_fp_libfunc;
-
- powi_optab->libcall_basename = "powi";
- powi_optab->libcall_suffix = '2';
- powi_optab->libcall_gen = gen_fp_libfunc;
-
- /* Conversions. */
- sfloat_optab->libcall_basename = "float";
- sfloat_optab->libcall_gen = gen_int_to_fp_conv_libfunc;
- ufloat_optab->libcall_gen = gen_ufloat_conv_libfunc;
- sfix_optab->libcall_basename = "fix";
- sfix_optab->libcall_gen = gen_fp_to_int_conv_libfunc;
- ufix_optab->libcall_basename = "fixuns";
- ufix_optab->libcall_gen = gen_fp_to_int_conv_libfunc;
- lrint_optab->libcall_basename = "lrint";
- lrint_optab->libcall_gen = gen_int_to_fp_nondecimal_conv_libfunc;
- lround_optab->libcall_basename = "lround";
- lround_optab->libcall_gen = gen_int_to_fp_nondecimal_conv_libfunc;
- lfloor_optab->libcall_basename = "lfloor";
- lfloor_optab->libcall_gen = gen_int_to_fp_nondecimal_conv_libfunc;
- lceil_optab->libcall_basename = "lceil";
- lceil_optab->libcall_gen = gen_int_to_fp_nondecimal_conv_libfunc;
-
- /* trunc_optab is also used for FLOAT_EXTEND. */
- sext_optab->libcall_basename = "extend";
- sext_optab->libcall_gen = gen_extend_conv_libfunc;
- trunc_optab->libcall_basename = "trunc";
- trunc_optab->libcall_gen = gen_trunc_conv_libfunc;
-
- /* Conversions for fixed-point modes and other modes. */
- fract_optab->libcall_basename = "fract";
- fract_optab->libcall_gen = gen_fract_conv_libfunc;
- satfract_optab->libcall_basename = "satfract";
- satfract_optab->libcall_gen = gen_satfract_conv_libfunc;
- fractuns_optab->libcall_basename = "fractuns";
- fractuns_optab->libcall_gen = gen_fractuns_conv_libfunc;
- satfractuns_optab->libcall_basename = "satfractuns";
- satfractuns_optab->libcall_gen = gen_satfractuns_conv_libfunc;
-
/* The ffs function operates on `int'. Fall back on it if we do not
have a libgcc2 function for that width. */
if (INT_TYPE_SIZE < BITS_PER_WORD)
@@ -6594,7 +6162,8 @@ init_optabs (void)
/* Use cabs for double complex abs, since systems generally have cabs.
Don't define any libcall for float complex, so that cabs will be used. */
if (complex_double_type_node)
- set_optab_libfunc (abs_optab, TYPE_MODE (complex_double_type_node), "cabs");
+ set_optab_libfunc (abs_optab, TYPE_MODE (complex_double_type_node),
+ "cabs");
abort_libfunc = init_one_libfunc ("abort");
memcpy_libfunc = init_one_libfunc ("memcpy");
@@ -6686,45 +6255,35 @@ init_sync_libfuncs (int max)
DEBUG_FUNCTION void
debug_optab_libfuncs (void)
{
- int i;
- int j;
- int k;
+ int i, j, k;
/* Dump the arithmetic optabs. */
- for (i = 0; i != (int) OTI_MAX; i++)
+ for (i = FIRST_NORM_OPTAB; i <= LAST_NORMLIB_OPTAB; ++i)
for (j = 0; j < NUM_MACHINE_MODES; ++j)
{
- optab o;
- rtx l;
-
- o = &optab_table[i];
- l = optab_libfunc (o, (enum machine_mode) j);
+ rtx l = optab_libfunc ((optab) i, (enum machine_mode) j);
if (l)
{
gcc_assert (GET_CODE (l) == SYMBOL_REF);
fprintf (stderr, "%s\t%s:\t%s\n",
- GET_RTX_NAME (optab_to_code (o)),
+ GET_RTX_NAME (optab_to_code ((optab) i)),
GET_MODE_NAME (j),
XSTR (l, 0));
}
}
/* Dump the conversion optabs. */
- for (i = 0; i < (int) COI_MAX; ++i)
+ for (i = FIRST_CONV_OPTAB; i <= LAST_CONVLIB_OPTAB; ++i)
for (j = 0; j < NUM_MACHINE_MODES; ++j)
for (k = 0; k < NUM_MACHINE_MODES; ++k)
{
- convert_optab o;
- rtx l;
-
- o = &convert_optab_table[i];
- l = convert_optab_libfunc (o, (enum machine_mode) j,
- (enum machine_mode) k);
+ rtx l = convert_optab_libfunc ((optab) i, (enum machine_mode) j,
+ (enum machine_mode) k);
if (l)
{
gcc_assert (GET_CODE (l) == SYMBOL_REF);
fprintf (stderr, "%s\t%s\t%s:\t%s\n",
- GET_RTX_NAME (optab_to_code (o)),
+ GET_RTX_NAME (optab_to_code ((optab) i)),
GET_MODE_NAME (j),
GET_MODE_NAME (k),
XSTR (l, 0));
diff --git a/gcc/optabs.def b/gcc/optabs.def
new file mode 100644
index 00000000000..9f6b29cd3e5
--- /dev/null
+++ b/gcc/optabs.def
@@ -0,0 +1,308 @@
+/* Definitions for operation tables, or "optabs".
+ Copyright (C) 1987-2012 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+/* Entries here are categorized C, D, N, V. See genopinit.c for details
+ on the meaning of the categories and for the pattern dollar codes. */
+
+/* The extension libcalls are used for float extension. */
+OPTAB_CL(sext_optab, "extend$b$a2", SIGN_EXTEND, "extend", gen_extend_conv_libfunc)
+OPTAB_CL(trunc_optab, "trunc$b$a2", TRUNCATE, "trunc", gen_trunc_conv_libfunc)
+OPTAB_CL(zext_optab, "zero_extend$b$a2", ZERO_EXTEND, NULL, NULL)
+
+OPTAB_CL(sfix_optab, "fix$F$b$I$a2", FIX, "fix", gen_fp_to_int_conv_libfunc)
+OPTAB_CL(ufix_optab, "fixuns$F$b$a2", UNSIGNED_FIX, "fixuns", gen_fp_to_int_conv_libfunc)
+OPTAB_CL(sfloat_optab, "float$I$b$F$a2", FLOAT, "float", gen_int_to_fp_conv_libfunc)
+OPTAB_CL(ufloat_optab, "floatuns$I$b$F$a2", UNSIGNED_FLOAT, NULL, gen_ufloat_conv_libfunc)
+
+OPTAB_CL(lrint_optab, "lrint$F$b$I$a2", UNKNOWN, "lrint", gen_int_to_fp_nondecimal_conv_libfunc)
+OPTAB_CL(lround_optab, "lround$F$b$I$a2", UNKNOWN, "lround", gen_int_to_fp_nondecimal_conv_libfunc)
+OPTAB_CL(lfloor_optab, "lfloor$F$b$I$a2", UNKNOWN, "lfloor", gen_int_to_fp_nondecimal_conv_libfunc)
+OPTAB_CL(lceil_optab, "lceil$F$b$I$a2", UNKNOWN, "lceil", gen_int_to_fp_nondecimal_conv_libfunc)
+
+/* Conversions for fixed-point modes and other modes. */
+OPTAB_CL(fract_optab, "fract$b$a2", FRACT_CONVERT, "fract", gen_fract_conv_libfunc)
+OPTAB_CL(fractuns_optab, "fractuns$I$b$Q$a2", UNSIGNED_FRACT_CONVERT, "fractuns", gen_fractuns_conv_libfunc)
+OPTAB_CX(fractuns_optab, "fractuns$Q$b$I$a2")
+OPTAB_CL(satfract_optab, "satfract$b$Q$a2", SAT_FRACT, "satfract", gen_satfract_conv_libfunc)
+OPTAB_CL(satfractuns_optab, "satfractuns$I$b$Q$a2", UNSIGNED_SAT_FRACT, "satfractuns", gen_satfractuns_conv_libfunc)
+
+OPTAB_CD(sfixtrunc_optab, "fix_trunc$F$b$I$a2")
+OPTAB_CD(ufixtrunc_optab, "fixuns_trunc$F$b$I$a2")
+
+/* Misc optabs that use two modes; model them as "conversions". */
+OPTAB_CD(smul_widen_optab, "mul$b$a3")
+OPTAB_CD(umul_widen_optab, "umul$b$a3")
+OPTAB_CD(usmul_widen_optab, "usmul$b$a3")
+OPTAB_CD(smadd_widen_optab, "madd$b$a4")
+OPTAB_CD(umadd_widen_optab, "umadd$b$a4")
+OPTAB_CD(ssmadd_widen_optab, "ssmadd$b$a4")
+OPTAB_CD(usmadd_widen_optab, "usmadd$b$a4")
+OPTAB_CD(smsub_widen_optab, "msub$b$a4")
+OPTAB_CD(umsub_widen_optab, "umsub$b$a4")
+OPTAB_CD(ssmsub_widen_optab, "ssmsub$b$a4")
+OPTAB_CD(usmsub_widen_optab, "usmsub$a$b4")
+OPTAB_CD(vec_load_lanes_optab, "vec_load_lanes$a$b")
+OPTAB_CD(vec_store_lanes_optab, "vec_store_lanes$a$b")
+OPTAB_CD(vcond_optab, "vcond$a$b")
+OPTAB_CD(vcondu_optab, "vcondu$a$b")
+
+OPTAB_NL(add_optab, "add$P$a3", PLUS, "add", '3', gen_int_fp_fixed_libfunc)
+OPTAB_NX(add_optab, "add$F$a3")
+OPTAB_NX(add_optab, "add$Q$a3")
+OPTAB_VL(addv_optab, "addv$I$a3", PLUS, "add", '3', gen_intv_fp_libfunc)
+OPTAB_VX(addv_optab, "add$F$a3")
+OPTAB_NL(ssadd_optab, "ssadd$Q$a3", SS_PLUS, "ssadd", '3', gen_signed_fixed_libfunc)
+OPTAB_NL(usadd_optab, "usadd$Q$a3", US_PLUS, "usadd", '3', gen_unsigned_fixed_libfunc)
+OPTAB_NL(sub_optab, "sub$P$a3", MINUS, "sub", '3', gen_int_fp_fixed_libfunc)
+OPTAB_NX(sub_optab, "sub$F$a3")
+OPTAB_NX(sub_optab, "sub$Q$a3")
+OPTAB_VL(subv_optab, "subv$I$a3", MINUS, "sub", '3', gen_intv_fp_libfunc)
+OPTAB_VX(subv_optab, "sub$F$a3")
+OPTAB_NL(sssub_optab, "sssub$Q$a3", SS_MINUS, "sssub", '3', gen_signed_fixed_libfunc)
+OPTAB_NL(ussub_optab, "ussub$Q$a3", US_MINUS, "ussub", '3', gen_unsigned_fixed_libfunc)
+OPTAB_NL(smul_optab, "mul$Q$a3", MULT, "mul", '3', gen_int_fp_fixed_libfunc)
+OPTAB_NX(smul_optab, "mul$P$a3")
+OPTAB_NX(smul_optab, "mul$F$a3")
+OPTAB_VL(smulv_optab, "mulv$I$a3", MULT, "mul", '3', gen_intv_fp_libfunc)
+OPTAB_VX(smulv_optab, "mul$F$a3")
+OPTAB_NL(ssmul_optab, "ssmul$Q$a3", SS_MULT, "ssmul", '3', gen_signed_fixed_libfunc)
+OPTAB_NL(usmul_optab, "usmul$Q$a3", US_MULT, "usmul", '3', gen_unsigned_fixed_libfunc)
+OPTAB_NL(sdiv_optab, "div$a3", DIV, "div", '3', gen_int_fp_signed_fixed_libfunc)
+OPTAB_VL(sdivv_optab, "divv$I$a3", DIV, "divv", '3', gen_int_libfunc)
+OPTAB_VX(sdivv_optab, "div$F$a3")
+OPTAB_NL(ssdiv_optab, "ssdiv$Q$a3", SS_DIV, "ssdiv", '3', gen_signed_fixed_libfunc)
+OPTAB_NL(udiv_optab, "udiv$I$a3", UDIV, "udiv", '3', gen_int_unsigned_fixed_libfunc)
+OPTAB_NX(udiv_optab, "udiv$Q$a3")
+OPTAB_NL(usdiv_optab, "usdiv$Q$a3", US_DIV, "usdiv", '3', gen_unsigned_fixed_libfunc)
+OPTAB_NL(sdivmod_optab, "divmod$a4", UNKNOWN, "divmod", '4', gen_int_libfunc)
+OPTAB_NL(udivmod_optab, "udivmod$a4", UNKNOWN, "udivmod", '4', gen_int_libfunc)
+OPTAB_NL(smod_optab, "mod$a3", MOD, "mod", '3', gen_int_libfunc)
+OPTAB_NL(umod_optab, "umod$a3", UMOD, "umod", '3', gen_int_libfunc)
+OPTAB_NL(ftrunc_optab, "ftrunc$F$a2", UNKNOWN, "ftrunc", '2', gen_fp_libfunc)
+OPTAB_NL(and_optab, "and$a3", AND, "and", '3', gen_int_libfunc)
+OPTAB_NL(ior_optab, "ior$a3", IOR, "ior", '3', gen_int_libfunc)
+OPTAB_NL(xor_optab, "xor$a3", XOR, "xor", '3', gen_int_libfunc)
+OPTAB_NL(ashl_optab, "ashl$a3", ASHIFT, "ashl", '3', gen_int_fixed_libfunc)
+OPTAB_NL(ssashl_optab, "ssashl$Q$a3", SS_ASHIFT, "ssashl", '3', gen_signed_fixed_libfunc)
+OPTAB_NL(usashl_optab, "usashl$Q$a3", US_ASHIFT, "usashl", '3', gen_unsigned_fixed_libfunc)
+OPTAB_NL(ashr_optab, "ashr$a3", ASHIFTRT, "ashr", '3', gen_int_signed_fixed_libfunc)
+OPTAB_NL(lshr_optab, "lshr$a3", LSHIFTRT, "lshr", '3', gen_int_unsigned_fixed_libfunc)
+OPTAB_NC(rotl_optab, "rotl$a3", ROTATE)
+OPTAB_NC(rotr_optab, "rotr$a3", ROTATERT)
+OPTAB_VC(vashl_optab, "vashl$a3", ASHIFT)
+OPTAB_VC(vashr_optab, "vashr$a3", ASHIFTRT)
+OPTAB_VC(vlshr_optab, "vlshr$a3", LSHIFTRT)
+OPTAB_VC(vrotl_optab, "vrotl$a3", ROTATE)
+OPTAB_VC(vrotr_optab, "vrotr$a3", ROTATERT)
+OPTAB_NL(smin_optab, "smin$a3", SMIN, "min", '3', gen_int_fp_libfunc)
+OPTAB_NL(smax_optab, "smax$a3", SMAX, "max", '3', gen_int_fp_libfunc)
+OPTAB_NL(umin_optab, "umin$I$a3", UMIN, "umin", '3', gen_int_libfunc)
+OPTAB_NL(umax_optab, "umax$I$a3", UMAX, "umax", '3', gen_int_libfunc)
+
+OPTAB_NL(neg_optab, "neg$P$a2", NEG, "neg", '2', gen_int_fp_fixed_libfunc)
+OPTAB_NX(neg_optab, "neg$F$a2")
+OPTAB_NX(neg_optab, "neg$Q$a2")
+OPTAB_VL(negv_optab, "negv$I$a2", NEG, "neg", '2', gen_intv_fp_libfunc)
+OPTAB_VX(negv_optab, "neg$F$a2")
+OPTAB_NL(ssneg_optab, "ssneg$Q$a2", SS_NEG, "ssneg", '2', gen_signed_fixed_libfunc)
+OPTAB_NL(usneg_optab, "usneg$Q$a2", US_NEG, "usneg", '2', gen_unsigned_fixed_libfunc)
+OPTAB_NC(abs_optab, "abs$P$a2", ABS)
+OPTAB_NX(abs_optab, "abs$F$a2")
+OPTAB_VC(absv_optab, "absv$I$a2", ABS)
+OPTAB_VX(absv_optab, "abs$F$a2")
+OPTAB_NL(one_cmpl_optab, "one_cmpl$a2", NOT, "one_cmpl", '2', gen_int_libfunc)
+OPTAB_NC(bswap_optab, "bswap$a2", BSWAP)
+OPTAB_NL(ffs_optab, "ffs$a2", FFS, "ffs", '2', gen_int_libfunc)
+OPTAB_NL(clz_optab, "clz$a2", CLZ, "clz", '2', gen_int_libfunc)
+OPTAB_NL(ctz_optab, "ctz$a2", CTZ, "ctz", '2', gen_int_libfunc)
+OPTAB_NL(clrsb_optab, "clrsb$a2", CLRSB, "clrsb", '2', gen_int_libfunc)
+OPTAB_NL(popcount_optab, "popcount$a2", POPCOUNT, "popcount", '2', gen_int_libfunc)
+OPTAB_NL(parity_optab, "parity$a2", PARITY, "parity", '2', gen_int_libfunc)
+
+/* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
+OPTAB_NL(cmp_optab, NULL, UNKNOWN, "cmp", '2', gen_int_fp_fixed_libfunc)
+OPTAB_NL(ucmp_optab, NULL, UNKNOWN, "ucmp", '2', gen_int_libfunc)
+
+/* EQ etc are floating point comparisons. */
+OPTAB_NL(eq_optab, NULL, EQ, "eq", '2', gen_fp_libfunc)
+OPTAB_NL(ne_optab, NULL, NE, "ne", '2', gen_fp_libfunc)
+OPTAB_NL(gt_optab, NULL, GT, "gt", '2', gen_fp_libfunc)
+OPTAB_NL(ge_optab, NULL, GE, "ge", '2', gen_fp_libfunc)
+OPTAB_NL(lt_optab, NULL, LT, "lt", '2', gen_fp_libfunc)
+OPTAB_NL(le_optab, NULL, LE, "le", '2', gen_fp_libfunc)
+OPTAB_NL(unord_optab, NULL, UNORDERED, "unord", '2', gen_fp_libfunc)
+
+OPTAB_NL(powi_optab, NULL, UNKNOWN, "powi", '2', gen_fp_libfunc)
+
+/* These are all initialized individually, on a per-host basis. */
+OPTAB_NC(sqrt_optab, "sqrt$a2", SQRT)
+OPTAB_NC(sync_old_add_optab, "sync_old_add$I$a", UNKNOWN)
+OPTAB_NC(sync_old_sub_optab, "sync_old_sub$I$a", UNKNOWN)
+OPTAB_NC(sync_old_ior_optab, "sync_old_ior$I$a", UNKNOWN)
+OPTAB_NC(sync_old_and_optab, "sync_old_and$I$a", UNKNOWN)
+OPTAB_NC(sync_old_xor_optab, "sync_old_xor$I$a", UNKNOWN)
+OPTAB_NC(sync_old_nand_optab, "sync_old_nand$I$a", UNKNOWN)
+OPTAB_NC(sync_new_add_optab, "sync_new_add$I$a", UNKNOWN)
+OPTAB_NC(sync_new_sub_optab, "sync_new_sub$I$a", UNKNOWN)
+OPTAB_NC(sync_new_ior_optab, "sync_new_ior$I$a", UNKNOWN)
+OPTAB_NC(sync_new_and_optab, "sync_new_and$I$a", UNKNOWN)
+OPTAB_NC(sync_new_xor_optab, "sync_new_xor$I$a", UNKNOWN)
+OPTAB_NC(sync_new_nand_optab, "sync_new_nand$I$a", UNKNOWN)
+OPTAB_NC(sync_compare_and_swap_optab, "sync_compare_and_swap$I$a", UNKNOWN)
+OPTAB_NC(sync_lock_test_and_set_optab, "sync_lock_test_and_set$I$a", UNKNOWN)
+
+OPTAB_DC(mov_optab, "mov$a", SET)
+OPTAB_DC(movstrict_optab, "movstrict$a", STRICT_LOW_PART)
+OPTAB_D (movmisalign_optab, "movmisalign$a")
+OPTAB_D (storent_optab, "storent$a")
+OPTAB_D (push_optab, "push$a1")
+OPTAB_D (reload_in_optab, "reload_in$a")
+OPTAB_D (reload_out_optab, "reload_out$a")
+
+OPTAB_DC(cbranch_optab, "cbranch$a4", COMPARE)
+OPTAB_D (addcc_optab, "add$acc")
+OPTAB_D (movcc_optab, "mov$acc")
+OPTAB_D (cmov_optab, "cmov$a6")
+OPTAB_D (cstore_optab, "cstore$a4")
+OPTAB_D (ctrap_optab, "ctrap$a4")
+
+OPTAB_D (smul_highpart_optab, "smul$a3_highpart")
+OPTAB_D (umul_highpart_optab, "umul$a3_highpart")
+
+OPTAB_D (cmpmem_optab, "cmpmem$a")
+OPTAB_D (cmpstr_optab, "cmpstr$a")
+OPTAB_D (cmpstrn_optab, "cmpstrn$a")
+OPTAB_D (movmem_optab, "movmem$a")
+OPTAB_D (setmem_optab, "setmem$a")
+OPTAB_D (strlen_optab, "strlen$a")
+
+OPTAB_DC(fma_optab, "fma$a4", FMA)
+OPTAB_D (fms_optab, "fms$a4")
+OPTAB_D (fnma_optab, "fnma$a4")
+OPTAB_D (fnms_optab, "fnms$a4")
+
+OPTAB_D (rint_optab, "rint$a2")
+OPTAB_D (round_optab, "round$a2")
+OPTAB_D (floor_optab, "floor$a2")
+OPTAB_D (ceil_optab, "ceil$a2")
+OPTAB_D (btrunc_optab, "btrunc$a2")
+OPTAB_D (nearbyint_optab, "nearbyint$a2")
+
+OPTAB_D (acos_optab, "acos$a2")
+OPTAB_D (asin_optab, "asin$a2")
+OPTAB_D (atan2_optab, "atan2$a3")
+OPTAB_D (atan_optab, "atan$a2")
+OPTAB_D (copysign_optab, "copysign$F$a3")
+OPTAB_D (cos_optab, "cos$a2")
+OPTAB_D (exp10_optab, "exp10$a2")
+OPTAB_D (exp2_optab, "exp2$a2")
+OPTAB_D (exp_optab, "exp$a2")
+OPTAB_D (expm1_optab, "expm1$a2")
+OPTAB_D (fmod_optab, "fmod$a3")
+OPTAB_D (ilogb_optab, "ilogb$a2")
+OPTAB_D (isinf_optab, "isinf$a2")
+OPTAB_D (ldexp_optab, "ldexp$a3")
+OPTAB_D (log10_optab, "log10$a2")
+OPTAB_D (log1p_optab, "log1p$a2")
+OPTAB_D (log2_optab, "log2$a2")
+OPTAB_D (log_optab, "log$a2")
+OPTAB_D (logb_optab, "logb$a2")
+OPTAB_D (pow_optab, "pow$a3")
+OPTAB_D (remainder_optab, "remainder$a3")
+OPTAB_D (scalb_optab, "scalb$a3")
+OPTAB_D (signbit_optab, "signbit$F$a2")
+OPTAB_D (significand_optab, "significand$a2")
+OPTAB_D (sin_optab, "sin$a2")
+OPTAB_D (sincos_optab, "sincos$a3")
+OPTAB_D (tan_optab, "tan$a2")
+
+OPTAB_D (reduc_smax_optab, "reduc_smax_$a")
+OPTAB_D (reduc_smin_optab, "reduc_smin_$a")
+OPTAB_D (reduc_splus_optab, "reduc_splus_$a")
+OPTAB_D (reduc_umax_optab, "reduc_umax_$a")
+OPTAB_D (reduc_umin_optab, "reduc_umin_$a")
+OPTAB_D (reduc_uplus_optab, "reduc_uplus_$a")
+OPTAB_D (sdot_prod_optab, "sdot_prod$I$a")
+OPTAB_D (ssum_widen_optab, "widen_ssum$I$a3")
+OPTAB_D (udot_prod_optab, "udot_prod$I$a")
+OPTAB_D (usum_widen_optab, "widen_usum$I$a3")
+OPTAB_D (vec_extract_optab, "vec_extract$a")
+OPTAB_D (vec_init_optab, "vec_init$a")
+OPTAB_D (vec_pack_sfix_trunc_optab, "vec_pack_sfix_trunc_$a")
+OPTAB_D (vec_pack_ssat_optab, "vec_pack_ssat_$a")
+OPTAB_D (vec_pack_trunc_optab, "vec_pack_trunc_$a")
+OPTAB_D (vec_pack_ufix_trunc_optab, "vec_pack_ufix_trunc_$a")
+OPTAB_D (vec_pack_usat_optab, "vec_pack_usat_$a")
+OPTAB_D (vec_perm_const_optab, "vec_perm_const$a")
+OPTAB_D (vec_perm_optab, "vec_perm$a")
+OPTAB_D (vec_realign_load_optab, "vec_realign_load_$a")
+OPTAB_D (vec_set_optab, "vec_set$a")
+OPTAB_D (vec_shl_optab, "vec_shl_$a")
+OPTAB_D (vec_shr_optab, "vec_shr_$a")
+OPTAB_D (vec_unpacks_float_hi_optab, "vec_unpacks_float_hi_$a")
+OPTAB_D (vec_unpacks_float_lo_optab, "vec_unpacks_float_lo_$a")
+OPTAB_D (vec_unpacks_hi_optab, "vec_unpacks_hi_$a")
+OPTAB_D (vec_unpacks_lo_optab, "vec_unpacks_lo_$a")
+OPTAB_D (vec_unpacku_float_hi_optab, "vec_unpacku_float_hi_$a")
+OPTAB_D (vec_unpacku_float_lo_optab, "vec_unpacku_float_lo_$a")
+OPTAB_D (vec_unpacku_hi_optab, "vec_unpacku_hi_$a")
+OPTAB_D (vec_unpacku_lo_optab, "vec_unpacku_lo_$a")
+OPTAB_D (vec_widen_smult_even_optab, "vec_widen_smult_even_$a")
+OPTAB_D (vec_widen_smult_hi_optab, "vec_widen_smult_hi_$a")
+OPTAB_D (vec_widen_smult_lo_optab, "vec_widen_smult_lo_$a")
+OPTAB_D (vec_widen_smult_odd_optab, "vec_widen_smult_odd_$a")
+OPTAB_D (vec_widen_sshiftl_hi_optab, "vec_widen_sshiftl_hi_$a")
+OPTAB_D (vec_widen_sshiftl_lo_optab, "vec_widen_sshiftl_lo_$a")
+OPTAB_D (vec_widen_umult_even_optab, "vec_widen_umult_even_$a")
+OPTAB_D (vec_widen_umult_hi_optab, "vec_widen_umult_hi_$a")
+OPTAB_D (vec_widen_umult_lo_optab, "vec_widen_umult_lo_$a")
+OPTAB_D (vec_widen_umult_odd_optab, "vec_widen_umult_odd_$a")
+OPTAB_D (vec_widen_ushiftl_hi_optab, "vec_widen_ushiftl_hi_$a")
+OPTAB_D (vec_widen_ushiftl_lo_optab, "vec_widen_ushiftl_lo_$a")
+
+OPTAB_D (sync_add_optab, "sync_add$I$a")
+OPTAB_D (sync_and_optab, "sync_and$I$a")
+OPTAB_D (sync_ior_optab, "sync_ior$I$a")
+OPTAB_D (sync_lock_release_optab, "sync_lock_release$I$a")
+OPTAB_D (sync_nand_optab, "sync_nand$I$a")
+OPTAB_D (sync_sub_optab, "sync_sub$I$a")
+OPTAB_D (sync_xor_optab, "sync_xor$I$a")
+
+OPTAB_D (atomic_add_fetch_optab, "atomic_add_fetch$I$a")
+OPTAB_D (atomic_add_optab, "atomic_add$I$a")
+OPTAB_D (atomic_and_fetch_optab, "atomic_and_fetch$I$a")
+OPTAB_D (atomic_and_optab, "atomic_and$I$a")
+OPTAB_D (atomic_compare_and_swap_optab, "atomic_compare_and_swap$I$a")
+OPTAB_D (atomic_exchange_optab, "atomic_exchange$I$a")
+OPTAB_D (atomic_fetch_add_optab, "atomic_fetch_add$I$a")
+OPTAB_D (atomic_fetch_and_optab, "atomic_fetch_and$I$a")
+OPTAB_D (atomic_fetch_nand_optab, "atomic_fetch_nand$I$a")
+OPTAB_D (atomic_fetch_or_optab, "atomic_fetch_or$I$a")
+OPTAB_D (atomic_fetch_sub_optab, "atomic_fetch_sub$I$a")
+OPTAB_D (atomic_fetch_xor_optab, "atomic_fetch_xor$I$a")
+OPTAB_D (atomic_load_optab, "atomic_load$I$a")
+OPTAB_D (atomic_nand_fetch_optab, "atomic_nand_fetch$I$a")
+OPTAB_D (atomic_nand_optab, "atomic_nand$I$a")
+OPTAB_D (atomic_or_fetch_optab, "atomic_or_fetch$I$a")
+OPTAB_D (atomic_or_optab, "atomic_or$I$a")
+OPTAB_D (atomic_store_optab, "atomic_store$I$a")
+OPTAB_D (atomic_sub_fetch_optab, "atomic_sub_fetch$I$a")
+OPTAB_D (atomic_sub_optab, "atomic_sub$I$a")
+OPTAB_D (atomic_xor_fetch_optab, "atomic_xor_fetch$I$a")
+OPTAB_D (atomic_xor_optab, "atomic_xor$I$a")
diff --git a/gcc/optabs.h b/gcc/optabs.h
index 60f83cff8a5..e0be2bac4fd 100644
--- a/gcc/optabs.h
+++ b/gcc/optabs.h
@@ -22,656 +22,34 @@ along with GCC; see the file COPYING3. If not see
#define GCC_OPTABS_H
#include "insn-codes.h"
+#include "insn-opinit.h"
-/* Optabs are tables saying how to generate insn bodies
- for various machine modes and numbers of operands.
- Each optab applies to one operation.
+typedef enum optab_tag optab;
+typedef enum optab_tag convert_optab;
+typedef enum optab_tag direct_optab;
- For example, add_optab applies to addition.
-
- The insn_code slot is the enum insn_code that says how to
- generate an insn for this operation on a particular machine mode.
- It is CODE_FOR_nothing if there is no such insn on the target machine.
-
- The `lib_call' slot is the name of the library function that
- can be used to perform the operation.
-
- A few optabs, such as move_optab, are used by special code. */
-
-struct optab_handlers
-{
- enum insn_code insn_code;
-};
-
-struct widening_optab_handlers
-{
- struct optab_handlers handlers[NUM_MACHINE_MODES][NUM_MACHINE_MODES];
-};
-
-struct optab_d
+struct optab_libcall_d
{
- enum rtx_code code_;
char libcall_suffix;
const char *libcall_basename;
- void (*libcall_gen)(struct optab_d *, const char *name, char suffix,
- enum machine_mode);
- struct optab_handlers handlers[NUM_MACHINE_MODES];
- struct widening_optab_handlers *widening;
+ void (*libcall_gen) (optab, const char *name,
+ char suffix, enum machine_mode);
};
-typedef struct optab_d * optab;
-/* A convert_optab is for some sort of conversion operation between
- modes. The first array index is the destination mode, the second
- is the source mode. */
-struct convert_optab_d
+struct convert_optab_libcall_d
{
- enum rtx_code code_;
const char *libcall_basename;
- void (*libcall_gen)(struct convert_optab_d *, const char *name,
- enum machine_mode,
- enum machine_mode);
- struct optab_handlers handlers[NUM_MACHINE_MODES][NUM_MACHINE_MODES];
+ void (*libcall_gen) (convert_optab, const char *name,
+ enum machine_mode, enum machine_mode);
};
-typedef struct convert_optab_d *convert_optab;
/* Given an enum insn_code, access the function to construct
the body of that kind of insn. */
#define GEN_FCN(CODE) (insn_data[CODE].genfun)
-/* Enumeration of valid indexes into optab_table. */
-enum optab_index
-{
- /* Fixed-point operators with signed/unsigned saturation */
- OTI_ssadd,
- OTI_usadd,
- OTI_sssub,
- OTI_ussub,
- OTI_ssmul,
- OTI_usmul,
- OTI_ssdiv,
- OTI_usdiv,
- OTI_ssneg,
- OTI_usneg,
- OTI_ssashl,
- OTI_usashl,
-
- OTI_add,
- OTI_addv,
- OTI_sub,
- OTI_subv,
-
- /* Signed and fp multiply */
- OTI_smul,
- OTI_smulv,
- /* Signed multiply, return high word */
- OTI_smul_highpart,
- OTI_umul_highpart,
- /* Signed multiply with result one machine mode wider than args */
- OTI_smul_widen,
- OTI_umul_widen,
- /* Widening multiply of one unsigned and one signed operand. */
- OTI_usmul_widen,
- /* Signed multiply and add with the result and addend one machine mode
- wider than the multiplicand and multiplier. */
- OTI_smadd_widen,
- /* Unsigned multiply and add with the result and addend one machine mode
- wider than the multiplicand and multiplier. */
- OTI_umadd_widen,
- /* Signed multiply and add with the result and addend one machine mode
- wider than the multiplicand and multiplier.
- All involved operations are saturating. */
- OTI_ssmadd_widen,
- /* Unsigned multiply and add with the result and addend one machine mode
- wider than the multiplicand and multiplier.
- All involved operations are saturating. */
- OTI_usmadd_widen,
- /* Signed multiply and subtract the result and minuend one machine mode
- wider than the multiplicand and multiplier. */
- OTI_smsub_widen,
- /* Unsigned multiply and subtract the result and minuend one machine mode
- wider than the multiplicand and multiplier. */
- OTI_umsub_widen,
- /* Signed multiply and subtract the result and minuend one machine mode
- wider than the multiplicand and multiplier.
- All involved operations are saturating. */
- OTI_ssmsub_widen,
- /* Unsigned multiply and subtract the result and minuend one machine mode
- wider than the multiplicand and multiplier.
- All involved operations are saturating. */
- OTI_usmsub_widen,
-
- /* Signed divide */
- OTI_sdiv,
- OTI_sdivv,
- /* Signed divide-and-remainder in one */
- OTI_sdivmod,
- OTI_udiv,
- OTI_udivmod,
- /* Signed remainder */
- OTI_smod,
- OTI_umod,
- /* Floating point remainder functions */
- OTI_fmod,
- OTI_remainder,
- /* Convert float to integer in float fmt */
- OTI_ftrunc,
-
- /* Logical and */
- OTI_and,
- /* Logical or */
- OTI_ior,
- /* Logical xor */
- OTI_xor,
-
- /* Arithmetic shift left */
- OTI_ashl,
- /* Logical shift right */
- OTI_lshr,
- /* Arithmetic shift right */
- OTI_ashr,
- /* Rotate left */
- OTI_rotl,
- /* Rotate right */
- OTI_rotr,
-
- /* Arithmetic shift left of vector by vector */
- OTI_vashl,
- /* Logical shift right of vector by vector */
- OTI_vlshr,
- /* Arithmetic shift right of vector by vector */
- OTI_vashr,
- /* Rotate left of vector by vector */
- OTI_vrotl,
- /* Rotate right of vector by vector */
- OTI_vrotr,
-
- /* Signed and floating-point minimum value */
- OTI_smin,
- /* Signed and floating-point maximum value */
- OTI_smax,
- /* Unsigned minimum value */
- OTI_umin,
- /* Unsigned maximum value */
- OTI_umax,
- /* Power */
- OTI_pow,
- /* Arc tangent of y/x */
- OTI_atan2,
- /* Floating multiply/add */
- OTI_fma,
- OTI_fms,
- OTI_fnma,
- OTI_fnms,
-
- /* Move instruction. */
- OTI_mov,
- /* Move, preserving high part of register. */
- OTI_movstrict,
- /* Move, with a misaligned memory. */
- OTI_movmisalign,
- /* Nontemporal store. */
- OTI_storent,
-
- /* Unary operations */
- /* Negation */
- OTI_neg,
- OTI_negv,
- /* Abs value */
- OTI_abs,
- OTI_absv,
- /* Byteswap */
- OTI_bswap,
- /* Bitwise not */
- OTI_one_cmpl,
- /* Bit scanning and counting */
- OTI_ffs,
- OTI_clz,
- OTI_ctz,
- OTI_clrsb,
- OTI_popcount,
- OTI_parity,
- /* Square root */
- OTI_sqrt,
- /* Sine-Cosine */
- OTI_sincos,
- /* Sine */
- OTI_sin,
- /* Inverse sine */
- OTI_asin,
- /* Cosine */
- OTI_cos,
- /* Inverse cosine */
- OTI_acos,
- /* Exponential */
- OTI_exp,
- /* Base-10 Exponential */
- OTI_exp10,
- /* Base-2 Exponential */
- OTI_exp2,
- /* Exponential - 1*/
- OTI_expm1,
- /* Load exponent of a floating point number */
- OTI_ldexp,
- /* Multiply floating-point number by integral power of radix */
- OTI_scalb,
- /* Mantissa of a floating-point number */
- OTI_significand,
- /* Radix-independent exponent */
- OTI_logb,
- OTI_ilogb,
- /* Natural Logarithm */
- OTI_log,
- /* Base-10 Logarithm */
- OTI_log10,
- /* Base-2 Logarithm */
- OTI_log2,
- /* logarithm of 1 plus argument */
- OTI_log1p,
- /* Rounding functions */
- OTI_floor,
- OTI_ceil,
- OTI_btrunc,
- OTI_round,
- OTI_nearbyint,
- OTI_rint,
- /* Tangent */
- OTI_tan,
- /* Inverse tangent */
- OTI_atan,
- /* Copy sign */
- OTI_copysign,
- /* Signbit */
- OTI_signbit,
- /* Test for infinite value */
- OTI_isinf,
-
- /* Compare insn; two operands. Used only for libcalls. */
- OTI_cmp,
- OTI_ucmp,
-
- /* Floating point comparison optabs - used primarily for libfuncs */
- OTI_eq,
- OTI_ne,
- OTI_gt,
- OTI_ge,
- OTI_lt,
- OTI_le,
- OTI_unord,
-
- /* String length */
- OTI_strlen,
-
- /* Combined compare & jump/move/store flags/trap operations. */
- OTI_cbranch,
- OTI_cmov,
- OTI_cstore,
- OTI_ctrap,
-
- /* Push instruction. */
- OTI_push,
-
- /* Conditional add instruction. */
- OTI_addcc,
-
- /* Reduction operations on a vector operand. */
- OTI_reduc_smax,
- OTI_reduc_umax,
- OTI_reduc_smin,
- OTI_reduc_umin,
- OTI_reduc_splus,
- OTI_reduc_uplus,
-
- /* Summation, with result machine mode one or more wider than args. */
- OTI_ssum_widen,
- OTI_usum_widen,
-
- /* Dot product, with result machine mode one or more wider than args. */
- OTI_sdot_prod,
- OTI_udot_prod,
-
- /* Set specified field of vector operand. */
- OTI_vec_set,
- /* Extract specified field of vector operand. */
- OTI_vec_extract,
- /* Initialize vector operand. */
- OTI_vec_init,
- /* Whole vector shift. The shift amount is in bits. */
- OTI_vec_shl,
- OTI_vec_shr,
- /* Extract specified elements from vectors, for vector load. */
- OTI_vec_realign_load,
- /* Widening multiplication. The high/low/even/odd part of the
- resulting vector of products is returned. */
- OTI_vec_widen_umult_hi,
- OTI_vec_widen_umult_lo,
- OTI_vec_widen_smult_hi,
- OTI_vec_widen_smult_lo,
- OTI_vec_widen_umult_even,
- OTI_vec_widen_umult_odd,
- OTI_vec_widen_smult_even,
- OTI_vec_widen_smult_odd,
- /* Widening shift left.
- The high/low part of the resulting vector is returned. */
- OTI_vec_widen_ushiftl_hi,
- OTI_vec_widen_ushiftl_lo,
- OTI_vec_widen_sshiftl_hi,
- OTI_vec_widen_sshiftl_lo,
- /* Extract and widen the high/low part of a vector of signed or
- floating point elements. */
- OTI_vec_unpacks_hi,
- OTI_vec_unpacks_lo,
- /* Extract and widen the high/low part of a vector of unsigned
- elements. */
- OTI_vec_unpacku_hi,
- OTI_vec_unpacku_lo,
-
- /* Extract, convert to floating point and widen the high/low part of
- a vector of signed or unsigned integer elements. */
- OTI_vec_unpacks_float_hi,
- OTI_vec_unpacks_float_lo,
- OTI_vec_unpacku_float_hi,
- OTI_vec_unpacku_float_lo,
-
- /* Narrow (demote) and merge the elements of two vectors. */
- OTI_vec_pack_trunc,
- OTI_vec_pack_usat,
- OTI_vec_pack_ssat,
-
- /* Convert to signed/unsigned integer, narrow and merge elements
- of two vectors of floating point elements. */
- OTI_vec_pack_sfix_trunc,
- OTI_vec_pack_ufix_trunc,
-
- /* Perform a raise to the power of integer. */
- OTI_powi,
-
- /* Atomic compare and swap. */
- OTI_sync_compare_and_swap,
-
- /* Atomic exchange with acquire semantics. */
- OTI_sync_lock_test_and_set,
-
- /* This second set is atomic operations in which we return the value
- that existed in memory before the operation. */
- OTI_sync_old_add,
- OTI_sync_old_sub,
- OTI_sync_old_ior,
- OTI_sync_old_and,
- OTI_sync_old_xor,
- OTI_sync_old_nand,
-
- /* This third set is atomic operations in which we return the value
- that resulted after performing the operation. */
- OTI_sync_new_add,
- OTI_sync_new_sub,
- OTI_sync_new_ior,
- OTI_sync_new_and,
- OTI_sync_new_xor,
- OTI_sync_new_nand,
-
- OTI_MAX
-};
-
-#define unknown_optab NULL
-
-#define ssadd_optab (&optab_table[OTI_ssadd])
-#define usadd_optab (&optab_table[OTI_usadd])
-#define sssub_optab (&optab_table[OTI_sssub])
-#define ussub_optab (&optab_table[OTI_ussub])
-#define ssmul_optab (&optab_table[OTI_ssmul])
-#define usmul_optab (&optab_table[OTI_usmul])
-#define ssdiv_optab (&optab_table[OTI_ssdiv])
-#define usdiv_optab (&optab_table[OTI_usdiv])
-#define ssneg_optab (&optab_table[OTI_ssneg])
-#define usneg_optab (&optab_table[OTI_usneg])
-#define ssashl_optab (&optab_table[OTI_ssashl])
-#define usashl_optab (&optab_table[OTI_usashl])
-
-#define add_optab (&optab_table[OTI_add])
-#define sub_optab (&optab_table[OTI_sub])
-#define smul_optab (&optab_table[OTI_smul])
-#define addv_optab (&optab_table[OTI_addv])
-#define subv_optab (&optab_table[OTI_subv])
-#define smul_highpart_optab (&optab_table[OTI_smul_highpart])
-#define umul_highpart_optab (&optab_table[OTI_umul_highpart])
-#define smul_widen_optab (&optab_table[OTI_smul_widen])
-#define umul_widen_optab (&optab_table[OTI_umul_widen])
-#define usmul_widen_optab (&optab_table[OTI_usmul_widen])
-#define smadd_widen_optab (&optab_table[OTI_smadd_widen])
-#define umadd_widen_optab (&optab_table[OTI_umadd_widen])
-#define ssmadd_widen_optab (&optab_table[OTI_ssmadd_widen])
-#define usmadd_widen_optab (&optab_table[OTI_usmadd_widen])
-#define smsub_widen_optab (&optab_table[OTI_smsub_widen])
-#define umsub_widen_optab (&optab_table[OTI_umsub_widen])
-#define ssmsub_widen_optab (&optab_table[OTI_ssmsub_widen])
-#define usmsub_widen_optab (&optab_table[OTI_usmsub_widen])
-#define sdiv_optab (&optab_table[OTI_sdiv])
-#define smulv_optab (&optab_table[OTI_smulv])
-#define sdivv_optab (&optab_table[OTI_sdivv])
-#define sdivmod_optab (&optab_table[OTI_sdivmod])
-#define udiv_optab (&optab_table[OTI_udiv])
-#define udivmod_optab (&optab_table[OTI_udivmod])
-#define smod_optab (&optab_table[OTI_smod])
-#define umod_optab (&optab_table[OTI_umod])
-#define fmod_optab (&optab_table[OTI_fmod])
-#define remainder_optab (&optab_table[OTI_remainder])
-#define ftrunc_optab (&optab_table[OTI_ftrunc])
-#define and_optab (&optab_table[OTI_and])
-#define ior_optab (&optab_table[OTI_ior])
-#define xor_optab (&optab_table[OTI_xor])
-#define ashl_optab (&optab_table[OTI_ashl])
-#define lshr_optab (&optab_table[OTI_lshr])
-#define ashr_optab (&optab_table[OTI_ashr])
-#define rotl_optab (&optab_table[OTI_rotl])
-#define rotr_optab (&optab_table[OTI_rotr])
-#define vashl_optab (&optab_table[OTI_vashl])
-#define vlshr_optab (&optab_table[OTI_vlshr])
-#define vashr_optab (&optab_table[OTI_vashr])
-#define vrotl_optab (&optab_table[OTI_vrotl])
-#define vrotr_optab (&optab_table[OTI_vrotr])
-#define smin_optab (&optab_table[OTI_smin])
-#define smax_optab (&optab_table[OTI_smax])
-#define umin_optab (&optab_table[OTI_umin])
-#define umax_optab (&optab_table[OTI_umax])
-#define pow_optab (&optab_table[OTI_pow])
-#define atan2_optab (&optab_table[OTI_atan2])
-#define fma_optab (&optab_table[OTI_fma])
-#define fms_optab (&optab_table[OTI_fms])
-#define fnma_optab (&optab_table[OTI_fnma])
-#define fnms_optab (&optab_table[OTI_fnms])
-
-#define mov_optab (&optab_table[OTI_mov])
-#define movstrict_optab (&optab_table[OTI_movstrict])
-#define movmisalign_optab (&optab_table[OTI_movmisalign])
-#define storent_optab (&optab_table[OTI_storent])
-
-#define neg_optab (&optab_table[OTI_neg])
-#define negv_optab (&optab_table[OTI_negv])
-#define abs_optab (&optab_table[OTI_abs])
-#define absv_optab (&optab_table[OTI_absv])
-#define one_cmpl_optab (&optab_table[OTI_one_cmpl])
-#define bswap_optab (&optab_table[OTI_bswap])
-#define ffs_optab (&optab_table[OTI_ffs])
-#define clz_optab (&optab_table[OTI_clz])
-#define ctz_optab (&optab_table[OTI_ctz])
-#define clrsb_optab (&optab_table[OTI_clrsb])
-#define popcount_optab (&optab_table[OTI_popcount])
-#define parity_optab (&optab_table[OTI_parity])
-#define sqrt_optab (&optab_table[OTI_sqrt])
-#define sincos_optab (&optab_table[OTI_sincos])
-#define sin_optab (&optab_table[OTI_sin])
-#define asin_optab (&optab_table[OTI_asin])
-#define cos_optab (&optab_table[OTI_cos])
-#define acos_optab (&optab_table[OTI_acos])
-#define exp_optab (&optab_table[OTI_exp])
-#define exp10_optab (&optab_table[OTI_exp10])
-#define exp2_optab (&optab_table[OTI_exp2])
-#define expm1_optab (&optab_table[OTI_expm1])
-#define ldexp_optab (&optab_table[OTI_ldexp])
-#define scalb_optab (&optab_table[OTI_scalb])
-#define significand_optab (&optab_table[OTI_significand])
-#define logb_optab (&optab_table[OTI_logb])
-#define ilogb_optab (&optab_table[OTI_ilogb])
-#define log_optab (&optab_table[OTI_log])
-#define log10_optab (&optab_table[OTI_log10])
-#define log2_optab (&optab_table[OTI_log2])
-#define log1p_optab (&optab_table[OTI_log1p])
-#define floor_optab (&optab_table[OTI_floor])
-#define ceil_optab (&optab_table[OTI_ceil])
-#define btrunc_optab (&optab_table[OTI_btrunc])
-#define round_optab (&optab_table[OTI_round])
-#define nearbyint_optab (&optab_table[OTI_nearbyint])
-#define rint_optab (&optab_table[OTI_rint])
-#define tan_optab (&optab_table[OTI_tan])
-#define atan_optab (&optab_table[OTI_atan])
-#define copysign_optab (&optab_table[OTI_copysign])
-#define signbit_optab (&optab_table[OTI_signbit])
-#define isinf_optab (&optab_table[OTI_isinf])
-
-#define cmp_optab (&optab_table[OTI_cmp])
-#define ucmp_optab (&optab_table[OTI_ucmp])
-
-#define eq_optab (&optab_table[OTI_eq])
-#define ne_optab (&optab_table[OTI_ne])
-#define gt_optab (&optab_table[OTI_gt])
-#define ge_optab (&optab_table[OTI_ge])
-#define lt_optab (&optab_table[OTI_lt])
-#define le_optab (&optab_table[OTI_le])
-#define unord_optab (&optab_table[OTI_unord])
-
-#define strlen_optab (&optab_table[OTI_strlen])
-
-#define cbranch_optab (&optab_table[OTI_cbranch])
-#define cmov_optab (&optab_table[OTI_cmov])
-#define cstore_optab (&optab_table[OTI_cstore])
-#define ctrap_optab (&optab_table[OTI_ctrap])
-
-#define push_optab (&optab_table[OTI_push])
-#define addcc_optab (&optab_table[OTI_addcc])
-
-#define reduc_smax_optab (&optab_table[OTI_reduc_smax])
-#define reduc_umax_optab (&optab_table[OTI_reduc_umax])
-#define reduc_smin_optab (&optab_table[OTI_reduc_smin])
-#define reduc_umin_optab (&optab_table[OTI_reduc_umin])
-#define reduc_splus_optab (&optab_table[OTI_reduc_splus])
-#define reduc_uplus_optab (&optab_table[OTI_reduc_uplus])
-
-#define ssum_widen_optab (&optab_table[OTI_ssum_widen])
-#define usum_widen_optab (&optab_table[OTI_usum_widen])
-#define sdot_prod_optab (&optab_table[OTI_sdot_prod])
-#define udot_prod_optab (&optab_table[OTI_udot_prod])
-
-#define vec_set_optab (&optab_table[OTI_vec_set])
-#define vec_extract_optab (&optab_table[OTI_vec_extract])
-#define vec_init_optab (&optab_table[OTI_vec_init])
-#define vec_shl_optab (&optab_table[OTI_vec_shl])
-#define vec_shr_optab (&optab_table[OTI_vec_shr])
-#define vec_realign_load_optab (&optab_table[OTI_vec_realign_load])
-#define vec_widen_umult_hi_optab (&optab_table[OTI_vec_widen_umult_hi])
-#define vec_widen_umult_lo_optab (&optab_table[OTI_vec_widen_umult_lo])
-#define vec_widen_smult_hi_optab (&optab_table[OTI_vec_widen_smult_hi])
-#define vec_widen_smult_lo_optab (&optab_table[OTI_vec_widen_smult_lo])
-#define vec_widen_umult_even_optab (&optab_table[OTI_vec_widen_umult_even])
-#define vec_widen_umult_odd_optab (&optab_table[OTI_vec_widen_umult_odd])
-#define vec_widen_smult_even_optab (&optab_table[OTI_vec_widen_smult_even])
-#define vec_widen_smult_odd_optab (&optab_table[OTI_vec_widen_smult_odd])
-#define vec_widen_ushiftl_hi_optab (&optab_table[OTI_vec_widen_ushiftl_hi])
-#define vec_widen_ushiftl_lo_optab (&optab_table[OTI_vec_widen_ushiftl_lo])
-#define vec_widen_sshiftl_hi_optab (&optab_table[OTI_vec_widen_sshiftl_hi])
-#define vec_widen_sshiftl_lo_optab (&optab_table[OTI_vec_widen_sshiftl_lo])
-#define vec_unpacks_hi_optab (&optab_table[OTI_vec_unpacks_hi])
-#define vec_unpacks_lo_optab (&optab_table[OTI_vec_unpacks_lo])
-#define vec_unpacku_hi_optab (&optab_table[OTI_vec_unpacku_hi])
-#define vec_unpacku_lo_optab (&optab_table[OTI_vec_unpacku_lo])
-#define vec_unpacks_float_hi_optab (&optab_table[OTI_vec_unpacks_float_hi])
-#define vec_unpacks_float_lo_optab (&optab_table[OTI_vec_unpacks_float_lo])
-#define vec_unpacku_float_hi_optab (&optab_table[OTI_vec_unpacku_float_hi])
-#define vec_unpacku_float_lo_optab (&optab_table[OTI_vec_unpacku_float_lo])
-#define vec_pack_trunc_optab (&optab_table[OTI_vec_pack_trunc])
-#define vec_pack_ssat_optab (&optab_table[OTI_vec_pack_ssat])
-#define vec_pack_usat_optab (&optab_table[OTI_vec_pack_usat])
-#define vec_pack_sfix_trunc_optab (&optab_table[OTI_vec_pack_sfix_trunc])
-#define vec_pack_ufix_trunc_optab (&optab_table[OTI_vec_pack_ufix_trunc])
-
-#define powi_optab (&optab_table[OTI_powi])
-
-#define sync_compare_and_swap_optab \
- (&optab_table[(int) OTI_sync_compare_and_swap])
-#define sync_lock_test_and_set_optab \
- (&optab_table[(int) OTI_sync_lock_test_and_set])
-#define sync_old_add_optab (&optab_table[(int) OTI_sync_old_add])
-#define sync_old_sub_optab (&optab_table[(int) OTI_sync_old_sub])
-#define sync_old_ior_optab (&optab_table[(int) OTI_sync_old_ior])
-#define sync_old_and_optab (&optab_table[(int) OTI_sync_old_and])
-#define sync_old_xor_optab (&optab_table[(int) OTI_sync_old_xor])
-#define sync_old_nand_optab (&optab_table[(int) OTI_sync_old_nand])
-#define sync_new_add_optab (&optab_table[(int) OTI_sync_new_add])
-#define sync_new_sub_optab (&optab_table[(int) OTI_sync_new_sub])
-#define sync_new_ior_optab (&optab_table[(int) OTI_sync_new_ior])
-#define sync_new_and_optab (&optab_table[(int) OTI_sync_new_and])
-#define sync_new_xor_optab (&optab_table[(int) OTI_sync_new_xor])
-#define sync_new_nand_optab (&optab_table[(int) OTI_sync_new_nand])
-
-/* Conversion optabs have their own table and indexes. */
-enum convert_optab_index
-{
- COI_sext,
- COI_zext,
- COI_trunc,
-
- COI_sfix,
- COI_ufix,
-
- COI_sfixtrunc,
- COI_ufixtrunc,
-
- COI_sfloat,
- COI_ufloat,
-
- COI_lrint,
- COI_lround,
- COI_lfloor,
- COI_lceil,
-
- COI_fract,
- COI_fractuns,
- COI_satfract,
- COI_satfractuns,
-
- COI_vec_load_lanes,
- COI_vec_store_lanes,
-
- /* Vector conditional operations. */
- COI_vcond,
- COI_vcondu,
-
- COI_MAX
-};
-
-#define sext_optab (&convert_optab_table[COI_sext])
-#define zext_optab (&convert_optab_table[COI_zext])
-#define trunc_optab (&convert_optab_table[COI_trunc])
-#define sfix_optab (&convert_optab_table[COI_sfix])
-#define ufix_optab (&convert_optab_table[COI_ufix])
-#define sfixtrunc_optab (&convert_optab_table[COI_sfixtrunc])
-#define ufixtrunc_optab (&convert_optab_table[COI_ufixtrunc])
-#define sfloat_optab (&convert_optab_table[COI_sfloat])
-#define ufloat_optab (&convert_optab_table[COI_ufloat])
-#define lrint_optab (&convert_optab_table[COI_lrint])
-#define lround_optab (&convert_optab_table[COI_lround])
-#define lfloor_optab (&convert_optab_table[COI_lfloor])
-#define lceil_optab (&convert_optab_table[COI_lceil])
-#define fract_optab (&convert_optab_table[COI_fract])
-#define fractuns_optab (&convert_optab_table[COI_fractuns])
-#define satfract_optab (&convert_optab_table[COI_satfract])
-#define satfractuns_optab (&convert_optab_table[COI_satfractuns])
-#define vec_load_lanes_optab (&convert_optab_table[COI_vec_load_lanes])
-#define vec_store_lanes_optab (&convert_optab_table[COI_vec_store_lanes])
-#define vcond_optab (&convert_optab_table[(int) COI_vcond])
-#define vcondu_optab (&convert_optab_table[(int) COI_vcondu])
-
-/* Contains the optab used for each rtx code. */
-extern optab code_to_optab_[NUM_RTX_CODE + 1];
+/* Contains the optab used for each rtx code, and vice-versa. */
+extern const optab code_to_optab_[NUM_RTX_CODE];
+extern const enum rtx_code optab_to_code_[NUM_OPTABS];
static inline optab
code_to_optab (enum rtx_code code)
@@ -679,176 +57,23 @@ code_to_optab (enum rtx_code code)
return code_to_optab_[code];
}
-#define optab_to_code(op) ((op)->code_)
-
-
-typedef rtx (*rtxfun) (rtx);
-
-/* Enumerates operations that have a named .md pattern associated
- with them, but which are not implemented as library functions. */
-enum direct_optab_index
+static inline enum rtx_code
+optab_to_code (optab op)
{
-#ifdef HAVE_conditional_move
- /* Conditional move operations. */
- DOI_movcc,
-#endif
+ return optab_to_code_[op];
+}
- /* Operations that use a scratch register to perform input and output
- reloads of special objects. */
- DOI_reload_in,
- DOI_reload_out,
-
- /* Block move operation. */
- DOI_movmem,
-
- /* Block set operation. */
- DOI_setmem,
-
- /* Various types of block compare operation. */
- DOI_cmpstr,
- DOI_cmpstrn,
- DOI_cmpmem,
-
- /* Atomic clear with release semantics. */
- DOI_sync_lock_release,
-
- /* Atomic operation with no resulting value. */
- DOI_sync_add,
- DOI_sync_sub,
- DOI_sync_ior,
- DOI_sync_and,
- DOI_sync_xor,
- DOI_sync_nand,
-
- /* Atomic operations with memory model parameters. */
- DOI_atomic_exchange,
- DOI_atomic_compare_and_swap,
- DOI_atomic_load,
- DOI_atomic_store,
- DOI_atomic_add_fetch,
- DOI_atomic_sub_fetch,
- DOI_atomic_and_fetch,
- DOI_atomic_nand_fetch,
- DOI_atomic_xor_fetch,
- DOI_atomic_or_fetch,
- DOI_atomic_fetch_add,
- DOI_atomic_fetch_sub,
- DOI_atomic_fetch_and,
- DOI_atomic_fetch_nand,
- DOI_atomic_fetch_xor,
- DOI_atomic_fetch_or,
- DOI_atomic_add,
- DOI_atomic_sub,
- DOI_atomic_and,
- DOI_atomic_nand,
- DOI_atomic_xor,
- DOI_atomic_or,
- DOI_atomic_always_lock_free,
- DOI_atomic_is_lock_free,
- DOI_atomic_thread_fence,
- DOI_atomic_signal_fence,
-
- /* Vector permutation. */
- DOI_vec_perm,
- DOI_vec_perm_const,
-
- DOI_MAX
-};
+extern const struct convert_optab_libcall_d convlib_def[NUM_CONVLIB_OPTABS];
+extern const struct optab_libcall_d normlib_def[NUM_NORMLIB_OPTABS];
-/* A structure that says which insn should be used to perform an operation
- in a particular mode. */
-struct direct_optab_d
-{
- struct optab_handlers handlers[NUM_MACHINE_MODES];
-};
-typedef struct direct_optab_d *direct_optab;
+/* Returns the active icode for the given (encoded) optab. */
+extern enum insn_code raw_optab_handler (unsigned);
+extern bool swap_optab_enable (optab, enum machine_mode, bool);
-#ifdef HAVE_conditional_move
-#define movcc_optab (&direct_optab_table[(int) DOI_movcc])
-#endif
-#define reload_in_optab (&direct_optab_table[(int) DOI_reload_in])
-#define reload_out_optab (&direct_optab_table[(int) DOI_reload_out])
-#define movmem_optab (&direct_optab_table[(int) DOI_movmem])
-#define setmem_optab (&direct_optab_table[(int) DOI_setmem])
-#define cmpstr_optab (&direct_optab_table[(int) DOI_cmpstr])
-#define cmpstrn_optab (&direct_optab_table[(int) DOI_cmpstrn])
-#define cmpmem_optab (&direct_optab_table[(int) DOI_cmpmem])
-#define sync_lock_release_optab \
- (&direct_optab_table[(int) DOI_sync_lock_release])
-#define sync_add_optab (&direct_optab_table[(int) DOI_sync_add])
-#define sync_sub_optab (&direct_optab_table[(int) DOI_sync_sub])
-#define sync_ior_optab (&direct_optab_table[(int) DOI_sync_ior])
-#define sync_and_optab (&direct_optab_table[(int) DOI_sync_and])
-#define sync_xor_optab (&direct_optab_table[(int) DOI_sync_xor])
-#define sync_nand_optab (&direct_optab_table[(int) DOI_sync_nand])
-
-#define atomic_exchange_optab \
- (&direct_optab_table[(int) DOI_atomic_exchange])
-#define atomic_compare_and_swap_optab \
- (&direct_optab_table[(int) DOI_atomic_compare_and_swap])
-#define atomic_load_optab \
- (&direct_optab_table[(int) DOI_atomic_load])
-#define atomic_store_optab \
- (&direct_optab_table[(int) DOI_atomic_store])
-#define atomic_add_fetch_optab \
- (&direct_optab_table[(int) DOI_atomic_add_fetch])
-#define atomic_sub_fetch_optab \
- (&direct_optab_table[(int) DOI_atomic_sub_fetch])
-#define atomic_and_fetch_optab \
- (&direct_optab_table[(int) DOI_atomic_and_fetch])
-#define atomic_nand_fetch_optab \
- (&direct_optab_table[(int) DOI_atomic_nand_fetch])
-#define atomic_xor_fetch_optab \
- (&direct_optab_table[(int) DOI_atomic_xor_fetch])
-#define atomic_or_fetch_optab \
- (&direct_optab_table[(int) DOI_atomic_or_fetch])
-#define atomic_fetch_add_optab \
- (&direct_optab_table[(int) DOI_atomic_fetch_add])
-#define atomic_fetch_sub_optab \
- (&direct_optab_table[(int) DOI_atomic_fetch_sub])
-#define atomic_fetch_and_optab \
- (&direct_optab_table[(int) DOI_atomic_fetch_and])
-#define atomic_fetch_nand_optab \
- (&direct_optab_table[(int) DOI_atomic_fetch_nand])
-#define atomic_fetch_xor_optab \
- (&direct_optab_table[(int) DOI_atomic_fetch_xor])
-#define atomic_fetch_or_optab \
- (&direct_optab_table[(int) DOI_atomic_fetch_or])
-#define atomic_add_optab \
- (&direct_optab_table[(int) DOI_atomic_add])
-#define atomic_sub_optab \
- (&direct_optab_table[(int) DOI_atomic_sub])
-#define atomic_and_optab \
- (&direct_optab_table[(int) DOI_atomic_and])
-#define atomic_nand_optab \
- (&direct_optab_table[(int) DOI_atomic_nand])
-#define atomic_xor_optab \
- (&direct_optab_table[(int) DOI_atomic_xor])
-#define atomic_or_optab \
- (&direct_optab_table[(int) DOI_atomic_or])
-#define atomic_always_lock_free_optab \
- (&direct_optab_table[(int) DOI_atomic_always_lock_free])
-#define atomic_is_lock_free_optab \
- (&direct_optab_table[(int) DOI_atomic_is_lock_free])
-#define atomic_thread_fence_optab \
- (&direct_optab_table[(int) DOI_atomic_thread_fence])
-#define atomic_signal_fence_optab \
- (&direct_optab_table[(int) DOI_atomic_signal_fence])
-
-#define vec_perm_optab (&direct_optab_table[DOI_vec_perm])
-#define vec_perm_const_optab (&direct_optab_table[(int) DOI_vec_perm_const])
-
/* Target-dependent globals. */
struct target_optabs {
- /* Tables of patterns that may have an associated libcall. */
- struct optab_d x_optab_table[(int) OTI_MAX];
-
- /* Tables of patterns for converting one mode to another. */
- struct convert_optab_d x_convert_optab_table[(int) COI_MAX];
-
- /* Tables of patterns for direct optabs (i.e. those which cannot be
- implemented using a libcall). */
- struct direct_optab_d x_direct_optab_table[(int) DOI_MAX];
+ /* Patterns that are used by optabs that are enabled for this target. */
+ bool pat_enable[NUM_OPTAB_PATTERNS];
};
extern struct target_optabs default_target_optabs;
@@ -857,13 +82,6 @@ extern struct target_optabs *this_target_optabs;
#else
#define this_target_optabs (&default_target_optabs)
#endif
-
-#define optab_table \
- (this_target_optabs->x_optab_table)
-#define convert_optab_table \
- (this_target_optabs->x_convert_optab_table)
-#define direct_optab_table \
- (this_target_optabs->x_direct_optab_table)
/* Define functions given in optabs.c. */
@@ -1036,49 +254,9 @@ extern rtx expand_mult_highpart (enum machine_mode, rtx, rtx, rtx, bool);
static inline enum insn_code
optab_handler (optab op, enum machine_mode mode)
{
- return op->handlers[(int) mode].insn_code;
-}
-
-/* Like optab_handler, but for widening_operations that have a TO_MODE and
- a FROM_MODE. */
-
-static inline enum insn_code
-widening_optab_handler (optab op, enum machine_mode to_mode,
- enum machine_mode from_mode)
-{
- if (to_mode == from_mode || from_mode == VOIDmode)
- return optab_handler (op, to_mode);
-
- if (op->widening)
- return op->widening->handlers[(int) to_mode][(int) from_mode].insn_code;
-
- return CODE_FOR_nothing;
-}
-
-/* Record that insn CODE should be used to implement mode MODE of OP. */
-
-static inline void
-set_optab_handler (optab op, enum machine_mode mode, enum insn_code code)
-{
- op->handlers[(int) mode].insn_code = code;
-}
-
-/* Like set_optab_handler, but for widening operations that have a TO_MODE
- and a FROM_MODE. */
-
-static inline void
-set_widening_optab_handler (optab op, enum machine_mode to_mode,
- enum machine_mode from_mode, enum insn_code code)
-{
- if (to_mode == from_mode)
- set_optab_handler (op, to_mode, code);
- else
- {
- if (op->widening == NULL)
- op->widening = XCNEW (struct widening_optab_handlers);
-
- op->widening->handlers[(int) to_mode][(int) from_mode].insn_code = code;
- }
+ unsigned scode = (op << 16) | mode;
+ gcc_assert (op > LAST_CONV_OPTAB);
+ return raw_optab_handler (scode);
}
/* Return the insn used to perform conversion OP from mode FROM_MODE
@@ -1089,17 +267,28 @@ static inline enum insn_code
convert_optab_handler (convert_optab op, enum machine_mode to_mode,
enum machine_mode from_mode)
{
- return op->handlers[(int) to_mode][(int) from_mode].insn_code;
+ unsigned scode = (op << 16) | (from_mode << 8) | to_mode;
+ gcc_assert (op > unknown_optab && op <= LAST_CONV_OPTAB);
+ return raw_optab_handler (scode);
}
-/* Record that insn CODE should be used to perform conversion OP
- from mode FROM_MODE to mode TO_MODE. */
+/* Like optab_handler, but for widening_operations that have a
+ TO_MODE and a FROM_MODE. */
-static inline void
-set_convert_optab_handler (convert_optab op, enum machine_mode to_mode,
- enum machine_mode from_mode, enum insn_code code)
+static inline enum insn_code
+widening_optab_handler (optab op, enum machine_mode to_mode,
+ enum machine_mode from_mode)
{
- op->handlers[(int) to_mode][(int) from_mode].insn_code = code;
+ unsigned scode = (op << 16) | to_mode;
+ if (to_mode != from_mode && from_mode != VOIDmode)
+ {
+ /* ??? Why does find_widening_optab_handler_and_mode attempt to
+ widen things that can't be widened? E.g. add_optab... */
+ if (op > LAST_CONV_OPTAB)
+ return CODE_FOR_nothing;
+ scode |= from_mode << 8;
+ }
+ return raw_optab_handler (scode);
}
/* Return the insn used to implement mode MODE of OP, or CODE_FOR_nothing
@@ -1108,16 +297,7 @@ set_convert_optab_handler (convert_optab op, enum machine_mode to_mode,
static inline enum insn_code
direct_optab_handler (direct_optab op, enum machine_mode mode)
{
- return op->handlers[(int) mode].insn_code;
-}
-
-/* Record that insn CODE should be used to implement mode MODE of OP. */
-
-static inline void
-set_direct_optab_handler (direct_optab op, enum machine_mode mode,
- enum insn_code code)
-{
- op->handlers[(int) mode].insn_code = code;
+ return optab_handler (op, mode);
}
/* Return true if UNOPTAB is for a trapping-on-overflow operation. */
@@ -1292,4 +472,52 @@ extern void expand_jump_insn (enum insn_code icode, unsigned int nops,
extern rtx prepare_operand (enum insn_code, rtx, int, enum machine_mode,
enum machine_mode, int);
+extern void gen_int_libfunc (optab, const char *, char, enum machine_mode);
+extern void gen_fp_libfunc (optab, const char *, char, enum machine_mode);
+extern void gen_fixed_libfunc (optab, const char *, char, enum machine_mode);
+extern void gen_signed_fixed_libfunc (optab, const char *, char,
+ enum machine_mode);
+extern void gen_unsigned_fixed_libfunc (optab, const char *, char,
+ enum machine_mode);
+extern void gen_int_fp_libfunc (optab, const char *, char, enum machine_mode);
+extern void gen_intv_fp_libfunc (optab, const char *, char, enum machine_mode);
+extern void gen_int_fp_fixed_libfunc (optab, const char *, char,
+ enum machine_mode);
+extern void gen_int_fp_signed_fixed_libfunc (optab, const char *, char,
+ enum machine_mode);
+extern void gen_int_fixed_libfunc (optab, const char *, char,
+ enum machine_mode);
+extern void gen_int_signed_fixed_libfunc (optab, const char *, char,
+ enum machine_mode);
+extern void gen_int_unsigned_fixed_libfunc (optab, const char *, char,
+ enum machine_mode);
+
+extern void gen_interclass_conv_libfunc (convert_optab, const char *,
+ enum machine_mode, enum machine_mode);
+extern void gen_int_to_fp_conv_libfunc (convert_optab, const char *,
+ enum machine_mode, enum machine_mode);
+extern void gen_ufloat_conv_libfunc (convert_optab, const char *,
+ enum machine_mode, enum machine_mode);
+extern void gen_int_to_fp_nondecimal_conv_libfunc (convert_optab,
+ const char *,
+ enum machine_mode,
+ enum machine_mode);
+extern void gen_fp_to_int_conv_libfunc (convert_optab, const char *,
+ enum machine_mode, enum machine_mode);
+extern void gen_intraclass_conv_libfunc (convert_optab, const char *,
+ enum machine_mode, enum machine_mode);
+extern void gen_trunc_conv_libfunc (convert_optab, const char *,
+ enum machine_mode, enum machine_mode);
+extern void gen_extend_conv_libfunc (convert_optab, const char *,
+ enum machine_mode, enum machine_mode);
+extern void gen_fract_conv_libfunc (convert_optab, const char *,
+ enum machine_mode, enum machine_mode);
+extern void gen_fractuns_conv_libfunc (convert_optab, const char *,
+ enum machine_mode, enum machine_mode);
+extern void gen_satfract_conv_libfunc (convert_optab, const char *,
+ enum machine_mode, enum machine_mode);
+extern void gen_satfractuns_conv_libfunc (convert_optab, const char *,
+ enum machine_mode,
+ enum machine_mode);
+
#endif /* GCC_OPTABS_H */
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 1b136597452..f942c5903b7 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -55,8 +55,13 @@ enum rtx_code {
NUM_RTX_CODE.
Assumes default enum value assignment. */
+/* The cast here, saves many elsewhere. */
#define NUM_RTX_CODE ((int) LAST_AND_UNUSED_RTX_CODE)
- /* The cast here, saves many elsewhere. */
+
+/* Similar, but since generator files get more entries... */
+#ifdef GENERATOR_FILE
+# define NON_GENERATOR_NUM_RTX_CODE ((int) MATCH_OPERAND)
+#endif
/* Register Transfer Language EXPRESSIONS CODE CLASSES */