From: rth Date: Tue, 24 Jul 2012 18:28:15 +0000 (+0000) Subject: Reduce the size of optabs representation X-Git-Tag: upstream/4.9.2~11470 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ee65118b7cf6bdb7a115ba1a7e01a94f1617d5a4;p=platform%2Fupstream%2Flinaro-gcc.git Reduce the size of optabs representation git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@189821 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a5f9ee7..ee809e0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,139 @@ +2012-07-24 Richard Henderson + + * 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 * bitmap.c (bitmap_descriptor): Adjust order of parameters to diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 81dc312..40f7c4d 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 2d6757e..5261279 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 bac4918..75f7a69 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 83509f9..022adfa 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 0000000..9f6b29c --- /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 +. */ + +/* 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 60f83cf..e0be2ba 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 1b13659..f942c59 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 */