From ad99e708993275cfd0d666486d9c1b8bc7107416 Mon Sep 17 00:00:00 2001 From: zack Date: Sat, 18 Aug 2001 19:59:46 +0000 Subject: [PATCH] * optabs.h (OTI_flodiv, flodiv_optab): Kill. * genopinit.c: Put floating point divide insns in sdiv_optab. * expr.c (expand_expr): Use sdiv_optab, not flodiv_optab. * config/gofast.h, config/c4x/c4x.h, config/ia64/hpux_longdouble.h, config/mips/mips.h, config/pa/long_double.h, config/rs6000/sysv4.h, config/sparc/sparc.h: Put floating point divide libcalls in sdiv_optab. * optabs.c (init_optab): Break into new_optab, init_optab, init_optabv. (init_optabs): Use init_optabv for overflow-trapping optabs. Don't init flodiv_optab. Give mov_optab, movstrict_optab, and cmp_optab RTX codes so have_insn_for can find them. * optabs.c (expand_simple_binop, expand_simple_unop, have_insn_for, gen_sub3_insn): New interfaces. * expr.h: Prototype new functions. (enum optab_methods): Move here from optabs.h. * builtins.c, combine.c, doloop.c, function.c, ifcvt.c, loop.c, profile.c, simplify-rtx.c, stmt.c, unroll.c: Use new functions instead of working directly with optabs. * doloop.c, ifcvt.c, loop.c, profile.c, simplify-rtx.c, unroll.c: Don't include optabs.h. * caller-save.c, combine.c, function.c, stmt.c: Just include insn-codes.h, not optabs.h. * Makefile.in: Update dependencies. * combine.c (make_compound_operation, simplify_comparison): Fix typos testing for this or that instruction. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@45008 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 31 ++++++++++ gcc/Makefile.in | 20 +++--- gcc/builtins.c | 10 ++- gcc/caller-save.c | 2 +- gcc/combine.c | 27 ++++---- gcc/config/c4x/c4x.h | 4 +- gcc/config/gofast.h | 4 +- gcc/config/ia64/hpux_longdouble.h | 2 +- gcc/config/mips/mips.h | 4 +- gcc/config/pa/long_double.h | 2 +- gcc/config/rs6000/sysv4.h | 2 +- gcc/config/sparc/sparc.h | 2 +- gcc/doloop.c | 39 ++++++------ gcc/expr.c | 2 +- gcc/expr.h | 29 +++++++++ gcc/function.c | 29 ++++----- gcc/genopinit.c | 3 +- gcc/ifcvt.c | 68 ++++++++++---------- gcc/loop.c | 37 ++++------- gcc/optabs.c | 127 +++++++++++++++++++++++++++++++++----- gcc/optabs.h | 18 ------ gcc/profile.c | 5 +- gcc/simplify-rtx.c | 4 +- gcc/stmt.c | 17 +++-- gcc/unroll.c | 23 ++++--- 25 files changed, 311 insertions(+), 200 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 315fa200d1b..2a9ca2ff2e2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,34 @@ +2001-08-18 Zack Weinberg + + * optabs.h (OTI_flodiv, flodiv_optab): Kill. + * genopinit.c: Put floating point divide insns in sdiv_optab. + * expr.c (expand_expr): Use sdiv_optab, not flodiv_optab. + * config/gofast.h, config/c4x/c4x.h, + config/ia64/hpux_longdouble.h, config/mips/mips.h, + config/pa/long_double.h, config/rs6000/sysv4.h, + config/sparc/sparc.h: Put floating point divide libcalls in sdiv_optab. + * optabs.c (init_optab): Break into new_optab, init_optab, init_optabv. + (init_optabs): Use init_optabv for overflow-trapping optabs. + Don't init flodiv_optab. Give mov_optab, movstrict_optab, and + cmp_optab RTX codes so have_insn_for can find them. + + * optabs.c (expand_simple_binop, expand_simple_unop, + have_insn_for, gen_sub3_insn): New interfaces. + * expr.h: Prototype new functions. + (enum optab_methods): Move here from optabs.h. + + * builtins.c, combine.c, doloop.c, function.c, ifcvt.c, + loop.c, profile.c, simplify-rtx.c, stmt.c, unroll.c: + Use new functions instead of working directly with optabs. + * doloop.c, ifcvt.c, loop.c, profile.c, simplify-rtx.c, + unroll.c: Don't include optabs.h. + * caller-save.c, combine.c, function.c, stmt.c: Just include + insn-codes.h, not optabs.h. + * Makefile.in: Update dependencies. + + * combine.c (make_compound_operation, simplify_comparison): + Fix typos testing for this or that instruction. + 2001-08-18 Herman A.J. ten Brugge * mklibgcc.in: Prefer LIB1ASMFUNCS over LIB2_DIVMOD_FUNCS when diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 6f748ca71e3..aa9f7ad4df6 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1380,10 +1380,10 @@ varasm.o : varasm.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) flags.h \ output.h c-pragma.h toplev.h xcoffout.h debug.h $(GGC_H) $(TM_P_H) \ $(HASHTAB_H) $(TARGET_H) function.o : function.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \ - function.h $(EXPR_H) $(OPTABS_H) libfuncs.h $(REGS_H) hard-reg-set.h \ + function.h insn-codes.h $(EXPR_H) libfuncs.h $(REGS_H) hard-reg-set.h \ insn-config.h $(RECOG_H) output.h toplev.h except.h hash.h $(GGC_H) $(TM_P_H) stmt.o : stmt.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h function.h \ - insn-config.h hard-reg-set.h $(EXPR_H) $(OPTABS_H) libfuncs.h except.h \ + insn-config.h insn-codes.h hard-reg-set.h $(EXPR_H) libfuncs.h except.h \ $(LOOP_H) $(RECOG_H) toplev.h output.h varray.h $(GGC_H) $(TM_P_H) except.o : except.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \ except.h function.h $(EXPR_H) libfuncs.h integrate.h \ @@ -1442,7 +1442,7 @@ jump.o : jump.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h hard-reg-set.h $(REGS_H simplify-rtx.o : simplify-rtx.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(REGS_H) \ hard-reg-set.h flags.h real.h insn-config.h $(RECOG_H) $(EXPR_H) toplev.h \ - $(OPTABS_H) output.h function.h $(GGC_H) $(OBSTACK_H) $(TM_P_H) + output.h function.h $(GGC_H) $(OBSTACK_H) $(TM_P_H) cselib.o : cselib.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(REGS_H) \ hard-reg-set.h flags.h real.h insn-config.h $(RECOG_H) $(EXPR_H) toplev.h \ output.h function.h cselib.h $(GGC_H) $(OBSTACK_H) $(TM_P_H) @@ -1473,24 +1473,24 @@ df.o : df.c $(CONFIG_H) system.h $(RTL_H) insn-config.h $(RECOG_H) \ conflict.o : conflict.c $(CONFIG_H) $(SYSTEM_H) $(OBSTACK_H) $(HASHTAB_H) \ $(RTL_H) hard-reg-set.h $(BASIC_BLOCK_H) profile.o : profile.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \ - insn-config.h output.h $(REGS_H) $(EXPR_H) $(OPTABS_H) function.h \ + insn-config.h output.h $(REGS_H) $(EXPR_H) function.h \ gcov-io.h toplev.h $(GGC_H) hard-reg-set.h $(BASIC_BLOCK_H) $(TARGET_H) loop.o : loop.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h $(LOOP_H) \ insn-config.h $(REGS_H) hard-reg-set.h $(RECOG_H) $(EXPR_H) \ - $(OPTABS_H) real.h $(PREDICT_H) $(BASIC_BLOCK_H) function.h \ + real.h $(PREDICT_H) $(BASIC_BLOCK_H) function.h \ toplev.h varray.h except.h cselib.h $(TM_P_H) doloop.o : doloop.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h $(LOOP_H) \ - $(EXPR_H) $(OPTABS_H) hard-reg-set.h $(BASIC_BLOCK_H) $(TM_P_H) toplev.h + $(EXPR_H) hard-reg-set.h $(BASIC_BLOCK_H) $(TM_P_H) toplev.h unroll.o : unroll.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) insn-config.h function.h \ $(INTEGRATE_H) $(REGS_H) $(RECOG_H) flags.h $(EXPR_H) $(LOOP_H) toplev.h \ - hard-reg-set.h varray.h $(BASIC_BLOCK_H) $(TM_P_H) $(PREDICT_H) $(OPTABS_H) + hard-reg-set.h varray.h $(BASIC_BLOCK_H) $(TM_P_H) $(PREDICT_H) flow.o : flow.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h insn-config.h \ $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h $(RECOG_H) \ function.h except.h $(EXPR_H) ssa.h $(GGC_H) $(TM_P_H) dominance.o : dominance.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) hard-reg-set.h \ $(BASIC_BLOCK_H) combine.o : combine.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h function.h \ - insn-config.h $(INSN_ATTR_H) $(OPTABS_H) $(REGS_H) $(EXPR_H) \ + insn-config.h insn-codes.h $(INSN_ATTR_H) $(REGS_H) $(EXPR_H) \ $(BASIC_BLOCK_H) $(RECOG_H) real.h hard-reg-set.h toplev.h $(TM_P_H) regclass.o : regclass.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) hard-reg-set.h flags.h \ $(BASIC_BLOCK_H) $(REGS_H) insn-config.h $(RECOG_H) reload.h real.h \ @@ -1515,7 +1515,7 @@ reload1.o : reload1.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) real.h flags.h \ except.h caller-save.o : caller-save.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h \ $(REGS_H) hard-reg-set.h insn-config.h $(BASIC_BLOCK_H) function.h \ - $(RECOG_H) reload.h $(EXPR_H) $(OPTABS_H) toplev.h $(TM_P_H) + $(RECOG_H) reload.h $(EXPR_H) insn-codes.h toplev.h $(TM_P_H) reorg.o : reorg.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) conditions.h hard-reg-set.h \ $(BASIC_BLOCK_H) $(REGS_H) insn-config.h $(INSN_ATTR_H) \ $(RECOG_H) function.h flags.h output.h $(EXPR_H) toplev.h $(PARAMS_H) $(TM_P_H) @@ -1562,7 +1562,7 @@ regrename.o : regrename.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) insn-config.h \ resource.h $(OBSTACK_H) flags.h $(TM_P_H) ifcvt.o : ifcvt.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(REGS_H) toplev.h \ flags.h insn-config.h function.h $(RECOG_H) $(BASIC_BLOCK_H) $(EXPR_H) \ - $(OPTABS_H) output.h $(TM_P_H) + output.h $(TM_P_H) dependence.o : dependence.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) \ $(C_COMMON_H) flags.h varray.h $(EXPR_H) params.o : params.c $(CONFIG_H) $(SYSTEM_H) $(PARAMS_H) toplev.h diff --git a/gcc/builtins.c b/gcc/builtins.c index c427f57fa2d..b2f4a6bf737 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -844,8 +844,7 @@ apply_args_size () mode != VOIDmode; mode = GET_MODE_WIDER_MODE (mode)) if (HARD_REGNO_MODE_OK (regno, mode) - && (mov_optab->handlers[(int) mode].insn_code - != CODE_FOR_nothing)) + && have_insn_for (SET, mode)) best_mode = mode; mode = best_mode; @@ -901,8 +900,7 @@ apply_result_size () mode != VOIDmode; mode = GET_MODE_WIDER_MODE (mode)) if (HARD_REGNO_MODE_OK (regno, mode) - && (mov_optab->handlers[(int) mode].insn_code - != CODE_FOR_nothing)) + && have_insn_for (SET, mode)) best_mode = mode; mode = best_mode; @@ -1072,8 +1070,8 @@ expand_builtin_apply (function, arguments, argsize) emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments)); #ifndef STACK_GROWS_DOWNWARD - incoming_args = expand_binop (Pmode, sub_optab, incoming_args, argsize, - incoming_args, 0, OPTAB_LIB_WIDEN); + incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize, + incoming_args, 0, OPTAB_LIB_WIDEN); #endif /* Perform postincrements before actually calling the function. */ diff --git a/gcc/caller-save.c b/gcc/caller-save.c index 48153d07594..2cf2cf0ff83 100644 --- a/gcc/caller-save.c +++ b/gcc/caller-save.c @@ -31,7 +31,7 @@ Boston, MA 02111-1307, USA. */ #include "reload.h" #include "function.h" #include "expr.h" -#include "optabs.h" +#include "insn-codes.h" #include "toplev.h" #include "tm_p.h" diff --git a/gcc/combine.c b/gcc/combine.c index b6ea18b0abd..b45339661fb 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -83,10 +83,10 @@ Boston, MA 02111-1307, USA. */ #include "hard-reg-set.h" #include "basic-block.h" #include "insn-config.h" +#include "insn-codes.h" #include "function.h" /* Include expr.h after insn-config.h so we get HAVE_conditional_move. */ #include "expr.h" -#include "optabs.h" #include "insn-attr.h" #include "recog.h" #include "real.h" @@ -5882,8 +5882,7 @@ make_extraction (mode, inner, pos, pos_rtx, len, && GET_CODE (inner) != MEM && (! in_dest || (GET_CODE (inner) == REG - && (movstrict_optab->handlers[(int) tmode].insn_code - != CODE_FOR_nothing)))) + && have_insn_for (STRICT_LOW_PART, tmode)))) || (GET_CODE (inner) == MEM && pos_rtx == 0 && (pos % (STRICT_ALIGNMENT ? GET_MODE_ALIGNMENT (tmode) @@ -6383,10 +6382,9 @@ make_compound_operation (x, in_code) /* On machines without logical shifts, if the operand of the AND is a logical shift and our mask turns off all the propagated sign bits, we can replace the logical shift with an arithmetic shift. */ - else if (ashr_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing - && (lshr_optab->handlers[(int) mode].insn_code - == CODE_FOR_nothing) - && GET_CODE (XEXP (x, 0)) == LSHIFTRT + else if (GET_CODE (XEXP (x, 0)) == LSHIFTRT + && !have_insn_for (LSHIFTRT, mode) + && have_insn_for (ASHIFTRT, mode) && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT && INTVAL (XEXP (XEXP (x, 0), 1)) >= 0 && INTVAL (XEXP (XEXP (x, 0), 1)) < HOST_BITS_PER_WIDE_INT @@ -6427,8 +6425,8 @@ make_compound_operation (x, in_code) case LSHIFTRT: /* If the sign bit is known to be zero, replace this with an arithmetic shift. */ - if (ashr_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing - && lshr_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing + if (have_insn_for (ASHIFTRT, mode) + && ! have_insn_for (LSHIFTRT, mode) && mode_width <= HOST_BITS_PER_WIDE_INT && (nonzero_bits (XEXP (x, 0), mode) & (1 << (mode_width - 1))) == 0) { @@ -6611,9 +6609,7 @@ force_to_mode (x, mode, mask, reg, just_select) that the operation is valid in MODE, in which case we do the operation in MODE. */ op_mode = ((GET_MODE_CLASS (mode) == GET_MODE_CLASS (GET_MODE (x)) - && code_to_optab[(int) code] != 0 - && (code_to_optab[(int) code]->handlers[(int) mode].insn_code - != CODE_FOR_nothing)) + && have_insn_for (code, mode)) ? mode : GET_MODE (x)); /* It is not valid to do a right-shift in a narrower mode @@ -10893,12 +10889,12 @@ simplify_comparison (code, pop0, pop1) mode = GET_MODE (op0); if (mode != VOIDmode && GET_MODE_CLASS (mode) == MODE_INT && GET_MODE_SIZE (mode) < UNITS_PER_WORD - && cmp_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) + && ! have_insn_for (COMPARE, mode)) for (tmode = GET_MODE_WIDER_MODE (mode); (tmode != VOIDmode && GET_MODE_BITSIZE (tmode) <= HOST_BITS_PER_WIDE_INT); tmode = GET_MODE_WIDER_MODE (tmode)) - if (cmp_optab->handlers[(int) tmode].insn_code != CODE_FOR_nothing) + if (have_insn_for (COMPARE, tmode)) { /* If the only nonzero bits in OP0 and OP1 are those in the narrower mode and this is an equality or unsigned comparison, @@ -10916,8 +10912,7 @@ simplify_comparison (code, pop0, pop1) /* If OP0 is an AND and we don't have an AND in MODE either, make a new AND in the proper mode. */ if (GET_CODE (op0) == AND - && (add_optab->handlers[(int) mode].insn_code - == CODE_FOR_nothing)) + && !have_insn_for (AND, mode)) op0 = gen_binary (AND, tmode, gen_lowpart_for_combine (tmode, XEXP (op0, 0)), diff --git a/gcc/config/c4x/c4x.h b/gcc/config/c4x/c4x.h index 607bc48b6e8..e2c483dc54b 100644 --- a/gcc/config/c4x/c4x.h +++ b/gcc/config/c4x/c4x.h @@ -1502,11 +1502,11 @@ CUMULATIVE_ARGS; = init_one_libfunc (MODQI3_LIBCALL); \ umod_optab->handlers[(int) QImode].libfunc \ = init_one_libfunc (UMODQI3_LIBCALL); \ - flodiv_optab->handlers[(int) QFmode].libfunc \ + sdiv_optab->handlers[(int) QFmode].libfunc \ = init_one_libfunc (DIVQF3_LIBCALL); \ smul_optab->handlers[(int) HFmode].libfunc \ = init_one_libfunc (MULHF3_LIBCALL); \ - flodiv_optab->handlers[(int) HFmode].libfunc \ + sdiv_optab->handlers[(int) HFmode].libfunc \ = init_one_libfunc (DIVHF3_LIBCALL); \ smul_optab->handlers[(int) HImode].libfunc \ = init_one_libfunc (MULHI3_LIBCALL); \ diff --git a/gcc/config/gofast.h b/gcc/config/gofast.h index dd09ea11b14..4c3c0ea9ae8 100644 --- a/gcc/config/gofast.h +++ b/gcc/config/gofast.h @@ -50,8 +50,8 @@ Boston, MA 02111-1307, USA. */ sub_optab->handlers[(int) DFmode].libfunc = init_one_libfunc ("dpsub"); \ smul_optab->handlers[(int) SFmode].libfunc = init_one_libfunc ("fpmul"); \ smul_optab->handlers[(int) DFmode].libfunc = init_one_libfunc ("dpmul"); \ - flodiv_optab->handlers[(int) SFmode].libfunc = init_one_libfunc ("fpdiv"); \ - flodiv_optab->handlers[(int) DFmode].libfunc = init_one_libfunc ("dpdiv"); \ + sdiv_optab->handlers[(int) SFmode].libfunc = init_one_libfunc ("fpdiv"); \ + sdiv_optab->handlers[(int) DFmode].libfunc = init_one_libfunc ("dpdiv"); \ cmp_optab->handlers[(int) SFmode].libfunc = init_one_libfunc ("fpcmp"); \ cmp_optab->handlers[(int) DFmode].libfunc = init_one_libfunc ("dpcmp"); \ \ diff --git a/gcc/config/ia64/hpux_longdouble.h b/gcc/config/ia64/hpux_longdouble.h index 27717ddce0b..bfc12d4fc70 100644 --- a/gcc/config/ia64/hpux_longdouble.h +++ b/gcc/config/ia64/hpux_longdouble.h @@ -59,7 +59,7 @@ Boston, MA 02111-1307, USA. */ = gen_rtx_SYMBOL_REF (Pmode, SUBTF3_LIBCALL); \ smul_optab->handlers[(int) TFmode].libfunc \ = gen_rtx_SYMBOL_REF (Pmode, MULTF3_LIBCALL); \ - flodiv_optab->handlers[(int) TFmode].libfunc \ + sdiv_optab->handlers[(int) TFmode].libfunc \ = gen_rtx_SYMBOL_REF (Pmode, DIVTF3_LIBCALL); \ smin_optab->handlers[(int) TFmode].libfunc \ = gen_rtx_SYMBOL_REF (Pmode, SMINTF3_LIBCALL); \ diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index b3c4dd40321..a3500eed39e 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -4572,7 +4572,7 @@ do \ init_one_libfunc ("__mips16_subsf3"); \ smul_optab->handlers[(int) SFmode].libfunc = \ init_one_libfunc ("__mips16_mulsf3"); \ - flodiv_optab->handlers[(int) SFmode].libfunc = \ + sdiv_optab->handlers[(int) SFmode].libfunc = \ init_one_libfunc ("__mips16_divsf3"); \ \ eqsf2_libfunc = init_one_libfunc ("__mips16_eqsf2"); \ @@ -4595,7 +4595,7 @@ do \ init_one_libfunc ("__mips16_subdf3"); \ smul_optab->handlers[(int) DFmode].libfunc = \ init_one_libfunc ("__mips16_muldf3"); \ - flodiv_optab->handlers[(int) DFmode].libfunc = \ + sdiv_optab->handlers[(int) DFmode].libfunc = \ init_one_libfunc ("__mips16_divdf3"); \ \ extendsfdf2_libfunc = \ diff --git a/gcc/config/pa/long_double.h b/gcc/config/pa/long_double.h index e65f15f9345..fa7a71054ba 100644 --- a/gcc/config/pa/long_double.h +++ b/gcc/config/pa/long_double.h @@ -70,7 +70,7 @@ do { long value[4]; \ = gen_rtx_SYMBOL_REF (Pmode, SUBTF3_LIBCALL); \ smul_optab->handlers[(int) TFmode].libfunc \ = gen_rtx_SYMBOL_REF (Pmode, MULTF3_LIBCALL); \ - flodiv_optab->handlers[(int) TFmode].libfunc \ + sdiv_optab->handlers[(int) TFmode].libfunc \ = gen_rtx_SYMBOL_REF (Pmode, DIVTF3_LIBCALL); \ smin_optab->handlers[(int) TFmode].libfunc \ = gen_rtx_SYMBOL_REF (Pmode, SMINTF3_LIBCALL); \ diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h index d916ad5866d..b8158ccf15b 100644 --- a/gcc/config/rs6000/sysv4.h +++ b/gcc/config/rs6000/sysv4.h @@ -1518,7 +1518,7 @@ ncrtn.o%s" = init_one_libfunc (NEGTF2_LIBCALL); \ smul_optab->handlers[(int) TFmode].libfunc \ = init_one_libfunc (MULTF3_LIBCALL); \ - flodiv_optab->handlers[(int) TFmode].libfunc \ + sdiv_optab->handlers[(int) TFmode].libfunc \ = init_one_libfunc (DIVTF3_LIBCALL); \ eqtf2_libfunc = init_one_libfunc (EQTF2_LIBCALL); \ netf2_libfunc = init_one_libfunc (NETF2_LIBCALL); \ diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index 6aa72d1d958..e24b0f99472 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -2771,7 +2771,7 @@ do { \ = init_one_libfunc (NEGTF2_LIBCALL); \ smul_optab->handlers[(int) TFmode].libfunc \ = init_one_libfunc (MULTF3_LIBCALL); \ - flodiv_optab->handlers[(int) TFmode].libfunc \ + sdiv_optab->handlers[(int) TFmode].libfunc \ = init_one_libfunc (DIVTF3_LIBCALL); \ eqtf2_libfunc = init_one_libfunc (EQTF2_LIBCALL); \ netf2_libfunc = init_one_libfunc (NETF2_LIBCALL); \ diff --git a/gcc/doloop.c b/gcc/doloop.c index 6ccc53941a9..289da282fb9 100644 --- a/gcc/doloop.c +++ b/gcc/doloop.c @@ -24,7 +24,6 @@ Boston, MA 02111-1307, USA. */ #include "rtl.h" #include "flags.h" #include "expr.h" -#include "optabs.h" #include "loop.h" #include "hard-reg-set.h" #include "basic-block.h" @@ -469,9 +468,9 @@ doloop_modify (loop, iterations, iterations_max, if (GET_CODE (count) == CONST_INT) count = GEN_INT (INTVAL (count) - 1); else - count = expand_binop (GET_MODE (counter_reg), sub_optab, - count, GEN_INT (1), - 0, 0, OPTAB_LIB_WIDEN); + count = expand_simple_binop (GET_MODE (counter_reg), MINUS, + count, GEN_INT (1), + 0, 0, OPTAB_LIB_WIDEN); } /* Insert initialization of the count register into the loop header. */ @@ -592,10 +591,10 @@ doloop_modify_runtime (loop, iterations_max, start_sequence (); /* abs (final - initial) */ - diff = expand_binop (mode, sub_optab, - copy_rtx (neg_inc ? initial_value : final_value), - copy_rtx (neg_inc ? final_value : initial_value), - NULL_RTX, unsigned_p, OPTAB_LIB_WIDEN); + diff = expand_simple_binop (mode, MINUS, + copy_rtx (neg_inc ? initial_value : final_value), + copy_rtx (neg_inc ? final_value : initial_value), + NULL_RTX, unsigned_p, OPTAB_LIB_WIDEN); if (abs_inc * loop_info->unroll_number != 1) { @@ -609,18 +608,18 @@ doloop_modify_runtime (loop, iterations_max, abort (); /* abs (final - initial) / (abs_inc * unroll_number) */ - iterations = expand_binop (GET_MODE (diff), lshr_optab, - diff, GEN_INT (shift_count), - NULL_RTX, 1, - OPTAB_LIB_WIDEN); + iterations = expand_simple_binop (GET_MODE (diff), LSHIFTRT, + diff, GEN_INT (shift_count), + NULL_RTX, 1, + OPTAB_LIB_WIDEN); if (abs_inc != 1) { /* abs (final - initial) % (abs_inc * unroll_number) */ - extra = expand_binop (GET_MODE (iterations), and_optab, - diff, GEN_INT (abs_inc * loop_info->unroll_number - 1), - NULL_RTX, 1, - OPTAB_LIB_WIDEN); + rtx count = GEN_INT (abs_inc * loop_info->unroll_number - 1); + extra = expand_simple_binop (GET_MODE (iterations), AND, + diff, count, NULL_RTX, 1, + OPTAB_LIB_WIDEN); /* If (abs (final - initial) % (abs_inc * unroll_number) <= abs_inc * (unroll - 1)), @@ -634,10 +633,10 @@ doloop_modify_runtime (loop, iterations_max, LABEL_NUSES (label)++; /* Increment the iteration count by one. */ - iterations = expand_binop (GET_MODE (iterations), add_optab, - iterations, GEN_INT (1), - iterations, 1, - OPTAB_LIB_WIDEN); + iterations = expand_simple_binop (GET_MODE (iterations), PLUS, + iterations, GEN_INT (1), + iterations, 1, + OPTAB_LIB_WIDEN); emit_label (label); } diff --git a/gcc/expr.c b/gcc/expr.c index 27ad3f62953..ed7f33fcf1f 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -7861,7 +7861,7 @@ expand_expr (exp, target, tmode, modifier) build_real (type, dconst1), TREE_OPERAND (exp, 1))), target, tmode, unsignedp); - this_optab = flodiv_optab; + this_optab = sdiv_optab; goto binop; case TRUNC_MOD_EXPR: diff --git a/gcc/expr.h b/gcc/expr.h index 3a651b0eefb..2ea167ec3d6 100644 --- a/gcc/expr.h +++ b/gcc/expr.h @@ -256,6 +256,34 @@ enum direction {none, upward, downward}; /* Value has this type. */ /* Functions from optabs.c, commonly used, and without need for the optabs tables: */ +/* Passed to expand_simple_binop and expand_binop to say which options + to try to use if the requested operation can't be open-coded on the + requisite mode. Either OPTAB_LIB or OPTAB_LIB_WIDEN says try using + a library call. Either OPTAB_WIDEN or OPTAB_LIB_WIDEN says try + using a wider mode. OPTAB_MUST_WIDEN says try widening and don't + try anything else. */ + +enum optab_methods +{ + OPTAB_DIRECT, + OPTAB_LIB, + OPTAB_WIDEN, + OPTAB_LIB_WIDEN, + OPTAB_MUST_WIDEN +}; + +/* Generate code for a simple binary or unary operation. "Simple" in + this case means "can be unambiguously described by a (mode, code) + pair and mapped to a single optab." */ +extern rtx expand_simple_binop PARAMS ((enum machine_mode, enum rtx_code, rtx, + rtx, rtx, int, enum optab_methods)); +extern rtx expand_simple_unop PARAMS ((enum machine_mode, enum rtx_code, + rtx, rtx, int)); + +/* Report whether the machine description contains an insn which can + perform the operation described by CODE and MODE. */ +extern int have_insn_for PARAMS ((enum rtx_code, enum machine_mode)); + /* Emit code to make a call to a constant function or a library call. */ extern void emit_libcall_block PARAMS ((rtx, rtx, rtx, rtx)); @@ -266,6 +294,7 @@ extern void emit_libcall_block PARAMS ((rtx, rtx, rtx, rtx)); extern rtx gen_add2_insn PARAMS ((rtx, rtx)); extern rtx gen_add3_insn PARAMS ((rtx, rtx, rtx)); extern rtx gen_sub2_insn PARAMS ((rtx, rtx)); +extern rtx gen_sub3_insn PARAMS ((rtx, rtx, rtx)); extern rtx gen_move_insn PARAMS ((rtx, rtx)); extern int have_add2_insn PARAMS ((rtx, rtx)); extern int have_sub2_insn PARAMS ((rtx, rtx)); diff --git a/gcc/function.c b/gcc/function.c index 0a6ed73b52e..c2424fd0732 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -46,11 +46,11 @@ Boston, MA 02111-1307, USA. */ #include "except.h" #include "function.h" #include "expr.h" -#include "optabs.h" #include "libfuncs.h" #include "regs.h" #include "hard-reg-set.h" #include "insn-config.h" +#include "insn-codes.h" #include "recog.h" #include "output.h" #include "basic-block.h" @@ -5693,12 +5693,13 @@ round_trampoline_addr (tramp) #ifdef TRAMPOLINE_ALIGNMENT /* Round address up to desired boundary. */ rtx temp = gen_reg_rtx (Pmode); - temp = expand_binop (Pmode, add_optab, tramp, - GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1), - temp, 0, OPTAB_LIB_WIDEN); - tramp = expand_binop (Pmode, and_optab, temp, - GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT), - temp, 0, OPTAB_LIB_WIDEN); + rtx addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1); + rtx mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT); + + temp = expand_simple_binop (Pmode, PLUS, tramp, addend, + temp, 0, OPTAB_LIB_WIDEN); + tramp = expand_simple_binop (Pmode, AND, temp, mask, + temp, 0, OPTAB_LIB_WIDEN); #endif return tramp; } @@ -6321,15 +6322,15 @@ expand_main_function () int align = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT; rtx tmp; - /* Forcably align the stack. */ + /* Forcibly align the stack. */ #ifdef STACK_GROWS_DOWNWARD - tmp = expand_binop (Pmode, and_optab, stack_pointer_rtx, - GEN_INT (-align), stack_pointer_rtx, 1, OPTAB_WIDEN); + tmp = expand_simple_binop (Pmode, AND, stack_pointer_rtx, GEN_INT(-align), + stack_pointer_rtx, 1, OPTAB_WIDEN); #else - tmp = expand_binop (Pmode, add_optab, stack_pointer_rtx, - GEN_INT (align - 1), NULL_RTX, 1, OPTAB_WIDEN); - tmp = expand_binop (Pmode, and_optab, tmp, GEN_INT (-align), - stack_pointer_rtx, 1, OPTAB_WIDEN); + tmp = expand_simple_binop (Pmode, PLUS, stack_pointer_rtx, + GEN_INT (align - 1), NULL_RTX, 1, OPTAB_WIDEN); + tmp = expand_simple_binop (Pmode, AND, tmp, GEN_INT (-align), + stack_pointer_rtx, 1, OPTAB_WIDEN); #endif if (tmp != stack_pointer_rtx) emit_move_insn (stack_pointer_rtx, tmp); diff --git a/gcc/genopinit.c b/gcc/genopinit.c index ee4dbf2fad9..43355611008 100644 --- a/gcc/genopinit.c +++ b/gcc/genopinit.c @@ -81,14 +81,13 @@ const char * const optabs[] = "smul_highpart_optab->handlers[$A].insn_code = CODE_FOR_$(smul$a3_highpart$)", "smul_widen_optab->handlers[$B].insn_code = CODE_FOR_$(mul$a$b3$)$N", "umul_widen_optab->handlers[$B].insn_code = CODE_FOR_$(umul$a$b3$)$N", - "sdiv_optab->handlers[$A].insn_code = CODE_FOR_$(div$I$a3$)", + "sdiv_optab->handlers[$A].insn_code = CODE_FOR_$(div$a3$)", "sdivv_optab->handlers[(int) $A].insn_code = CODE_FOR_$(div$V$I$a3$)", "udiv_optab->handlers[$A].insn_code = CODE_FOR_$(udiv$I$a3$)", "sdivmod_optab->handlers[$A].insn_code = CODE_FOR_$(divmod$a4$)", "udivmod_optab->handlers[$A].insn_code = CODE_FOR_$(udivmod$a4$)", "smod_optab->handlers[$A].insn_code = CODE_FOR_$(mod$a3$)", "umod_optab->handlers[$A].insn_code = CODE_FOR_$(umod$a3$)", - "flodiv_optab->handlers[$A].insn_code = CODE_FOR_$(div$F$a3$)", "ftrunc_optab->handlers[$A].insn_code = CODE_FOR_$(ftrunc$F$a2$)", "and_optab->handlers[$A].insn_code = CODE_FOR_$(and$a3$)", "ior_optab->handlers[$A].insn_code = CODE_FOR_$(ior$a3$)", diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index 77d585c28a4..a877a90da18 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -30,7 +30,6 @@ #include "hard-reg-set.h" #include "basic-block.h" #include "expr.h" -#include "optabs.h" #include "real.h" #include "output.h" #include "toplev.h" @@ -698,42 +697,42 @@ noce_try_store_flag_constants (if_info) => x = 3 + (test == 0); */ if (diff == STORE_FLAG_VALUE || diff == -STORE_FLAG_VALUE) { - target = expand_binop (mode, - (diff == STORE_FLAG_VALUE - ? add_optab : sub_optab), - GEN_INT (ifalse), target, if_info->x, 0, - OPTAB_WIDEN); + target = expand_simple_binop (mode, + (diff == STORE_FLAG_VALUE + ? PLUS : MINUS), + GEN_INT (ifalse), target, if_info->x, 0, + OPTAB_WIDEN); } /* if (test) x = 8; else x = 0; => x = (test != 0) << 3; */ else if (ifalse == 0 && (tmp = exact_log2 (itrue)) >= 0) { - target = expand_binop (mode, ashl_optab, - target, GEN_INT (tmp), if_info->x, 0, - OPTAB_WIDEN); + target = expand_simple_binop (mode, ASHIFT, + target, GEN_INT (tmp), if_info->x, 0, + OPTAB_WIDEN); } /* if (test) x = -1; else x = b; => x = -(test != 0) | b; */ else if (itrue == -1) { - target = expand_binop (mode, ior_optab, - target, GEN_INT (ifalse), if_info->x, 0, - OPTAB_WIDEN); + target = expand_simple_binop (mode, IOR, + target, GEN_INT (ifalse), if_info->x, 0, + OPTAB_WIDEN); } /* if (test) x = a; else x = b; => x = (-(test != 0) & (b - a)) + a; */ else { - target = expand_binop (mode, and_optab, - target, GEN_INT (diff), if_info->x, 0, - OPTAB_WIDEN); + target = expand_simple_binop (mode, AND, + target, GEN_INT (diff), if_info->x, 0, + OPTAB_WIDEN); if (target) - target = expand_binop (mode, add_optab, - target, GEN_INT (ifalse), if_info->x, 0, - OPTAB_WIDEN); + target = expand_simple_binop (mode, PLUS, + target, GEN_INT (ifalse), + if_info->x, 0, OPTAB_WIDEN); } if (! target) @@ -796,9 +795,10 @@ noce_try_store_flag_inc (if_info) 1, normalize); if (target) - target = expand_binop (GET_MODE (if_info->x), - subtract ? sub_optab : add_optab, - if_info->x, target, if_info->x, 0, OPTAB_WIDEN); + target = expand_simple_binop (GET_MODE (if_info->x), + subtract ? MINUS : PLUS, + if_info->x, target, if_info->x, + 0, OPTAB_WIDEN); if (target) { if (target != if_info->x) @@ -847,9 +847,9 @@ noce_try_store_flag_mask (if_info) gen_reg_rtx (GET_MODE (if_info->x)), reversep, -1); if (target) - target = expand_binop (GET_MODE (if_info->x), and_optab, - if_info->x, target, if_info->x, 0, - OPTAB_WIDEN); + target = expand_simple_binop (GET_MODE (if_info->x), AND, + if_info->x, target, if_info->x, 0, + OPTAB_WIDEN); if (target) { @@ -1283,9 +1283,8 @@ noce_try_minmax (if_info) struct noce_if_info *if_info; { rtx cond, earliest, target, seq; - enum rtx_code code; + enum rtx_code code, op; int unsignedp; - optab op; /* ??? Can't guarantee that expand_binop won't create pseudos. */ if (no_new_pseudos) @@ -1328,24 +1327,24 @@ noce_try_minmax (if_info) case LE: case UNLT: case UNLE: - op = smax_optab; + op = SMAX; unsignedp = 0; break; case GT: case GE: case UNGT: case UNGE: - op = smin_optab; + op = SMIN; unsignedp = 0; break; case LTU: case LEU: - op = umax_optab; + op = UMAX; unsignedp = 1; break; case GTU: case GEU: - op = umin_optab; + op = UMIN; unsignedp = 1; break; default: @@ -1354,8 +1353,9 @@ noce_try_minmax (if_info) start_sequence (); - target = expand_binop (GET_MODE (if_info->x), op, if_info->a, if_info->b, - if_info->x, unsignedp, OPTAB_WIDEN); + target = expand_simple_binop (GET_MODE (if_info->x), op, + if_info->a, if_info->b, + if_info->x, unsignedp, OPTAB_WIDEN); if (! target) { end_sequence (); @@ -1466,12 +1466,12 @@ noce_try_abs (if_info) start_sequence (); - target = expand_unop (GET_MODE (if_info->x), abs_optab, b, if_info->x, 0); + target = expand_simple_unop (GET_MODE (if_info->x), ABS, b, if_info->x, 0); /* ??? It's a quandry whether cmove would be better here, especially for integers. Perhaps combine will clean things up. */ if (target && negate) - target = expand_unop (GET_MODE (target), neg_optab, target, if_info->x, 0); + target = expand_simple_unop (GET_MODE (target), NEG, target, if_info->x, 0); if (! target) { diff --git a/gcc/loop.c b/gcc/loop.c index 55fa9121762..a8bf9c7cbd0 100644 --- a/gcc/loop.c +++ b/gcc/loop.c @@ -41,7 +41,6 @@ Boston, MA 02111-1307, USA. */ #include "obstack.h" #include "function.h" #include "expr.h" -#include "optabs.h" #include "hard-reg-set.h" #include "basic-block.h" #include "insn-config.h" @@ -1952,8 +1951,8 @@ move_movables (loop, movables, threshold, insn_count) rtx tem; start_sequence (); - tem = expand_binop - (GET_MODE (reg), and_optab, reg, + tem = expand_simple_binop + (GET_MODE (reg), AND, reg, GEN_INT ((((HOST_WIDE_INT) 1 << GET_MODE_BITSIZE (m->savemode))) - 1), @@ -7578,21 +7577,16 @@ check_dbra_loop (loop, insn_count) } else if (GET_CODE (initial_value) == CONST_INT) { - rtx offset = GEN_INT (-INTVAL (initial_value) - add_adjust); enum machine_mode mode = GET_MODE (reg); - enum insn_code icode - = add_optab->handlers[(int) mode].insn_code; - - if (! (*insn_data[icode].operand[0].predicate) (reg, mode) - || ! ((*insn_data[icode].operand[1].predicate) - (comparison_value, mode)) - || ! ((*insn_data[icode].operand[2].predicate) - (offset, mode))) + rtx offset = GEN_INT (-INTVAL (initial_value) - add_adjust); + rtx add_insn = gen_add3_insn (reg, comparison_value, offset); + + if (add_insn == 0) return 0; + start_value = gen_rtx_PLUS (mode, comparison_value, offset); - loop_insn_hoist (loop, (GEN_FCN (icode) - (reg, comparison_value, offset))); + loop_insn_hoist (loop, add_insn); if (GET_CODE (comparison) == LE) final_value = gen_rtx_PLUS (mode, comparison_value, GEN_INT (add_val)); @@ -7600,19 +7594,14 @@ check_dbra_loop (loop, insn_count) else if (! add_adjust) { enum machine_mode mode = GET_MODE (reg); - enum insn_code icode - = sub_optab->handlers[(int) mode].insn_code; - if (! (*insn_data[icode].operand[0].predicate) (reg, mode) - || ! ((*insn_data[icode].operand[1].predicate) - (comparison_value, mode)) - || ! ((*insn_data[icode].operand[2].predicate) - (initial_value, mode))) + rtx sub_insn = gen_sub3_insn (reg, comparison_value, + initial_value); + + if (sub_insn == 0) return 0; start_value = gen_rtx_MINUS (mode, comparison_value, initial_value); - loop_insn_hoist (loop, (GEN_FCN (icode) - (reg, comparison_value, - initial_value))); + loop_insn_hoist (loop, sub_insn); } else /* We could handle the other cases too, but it'll be diff --git a/gcc/optabs.c b/gcc/optabs.c index 285555392d9..1afff42c51f 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -101,7 +101,9 @@ static enum insn_code can_fix_p PARAMS ((enum machine_mode, enum machine_mode, static enum insn_code can_float_p PARAMS ((enum machine_mode, enum machine_mode, int)); static rtx ftruncify PARAMS ((rtx)); -static optab init_optab PARAMS ((enum rtx_code)); +static optab new_optab PARAMS ((void)); +static inline optab init_optab PARAMS ((enum rtx_code)); +static inline optab init_optabv PARAMS ((enum rtx_code)); static void init_libfuncs PARAMS ((optab, int, int, const char *, int)); static void init_integral_libfuncs PARAMS ((optab, const char *, int)); static void init_floating_libfuncs PARAMS ((optab, const char *, int)); @@ -599,6 +601,25 @@ expand_cmplxdiv_wide (real0, real1, imag0, imag1, realr, imagr, submode, return 1; } +/* Wrapper around expand_binop which takes an rtx code to specify + the operation to perform, not an optab pointer. All other + arguments are the same. */ +rtx +expand_simple_binop (mode, code, op0, op1, target, unsignedp, methods) + enum machine_mode mode; + enum rtx_code code; + rtx op0, op1; + rtx target; + int unsignedp; + enum optab_methods methods; +{ + optab binop = code_to_optab [(int) code]; + if (binop == 0) + abort (); + + return expand_binop (mode, binop, op0, op1, target, unsignedp, methods); +} + /* Generate code to perform an operation specified by BINOPTAB on operands OP0 and OP1, with result having machine-mode MODE. @@ -2014,6 +2035,24 @@ expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp) return 0; } +/* Wrapper around expand_unop which takes an rtx code to specify + the operation to perform, not an optab pointer. All other + arguments are the same. */ +rtx +expand_simple_unop (mode, code, op0, target, unsignedp) + enum machine_mode mode; + enum rtx_code code; + rtx op0; + rtx target; + int unsignedp; +{ + optab unop = code_to_optab [(int) code]; + if (unop == 0) + abort (); + + return expand_unop (mode, unop, op0, target, unsignedp); +} + /* Generate code to perform an operation specified by UNOPTAB on operand OP0, with result having machine-mode MODE. @@ -3830,6 +3869,26 @@ gen_sub2_insn (x, y) return (GEN_FCN (icode) (x, x, y)); } +/* Generate and return an insn body to subtract r1 and c, + storing the result in r0. */ +rtx +gen_sub3_insn (r0, r1, c) + rtx r0, r1, c; +{ + int icode = (int) sub_optab->handlers[(int) GET_MODE (r0)].insn_code; + + if (icode == CODE_FOR_nothing + || ! ((*insn_data[icode].operand[0].predicate) + (r0, insn_data[icode].operand[0].mode)) + || ! ((*insn_data[icode].operand[1].predicate) + (r1, insn_data[icode].operand[1].mode)) + || ! ((*insn_data[icode].operand[2].predicate) + (c, insn_data[icode].operand[2].mode))) + return NULL_RTX; + + return (GEN_FCN (icode) (r0, r1, c)); +} + int have_sub2_insn (x, y) rtx x, y; @@ -4495,22 +4554,53 @@ expand_fix (to, from, unsignedp) } } -static optab -init_optab (code) +/* Report whether we have an instruction to perform the operation + specified by CODE on operands of mode MODE. */ +int +have_insn_for (code, mode) enum rtx_code code; + enum machine_mode mode; +{ + return (code_to_optab[(int) code] != 0 + && (code_to_optab[(int) code]->handlers[(int) mode].insn_code + != CODE_FOR_nothing)); +} + +/* Create a blank optab. */ +static optab +new_optab () { int i; optab op = (optab) xmalloc (sizeof (struct optab)); - op->code = code; for (i = 0; i < NUM_MACHINE_MODES; i++) { op->handlers[i].insn_code = CODE_FOR_nothing; op->handlers[i].libfunc = 0; } - if (code != UNKNOWN) - code_to_optab[(int) code] = op; + return op; +} +/* Same, but fill in its code as CODE, and write it into the + code_to_optab table. */ +static inline optab +init_optab (code) + enum rtx_code code; +{ + optab op = new_optab (); + op->code = code; + code_to_optab[(int) code] = op; + return op; +} + +/* Same, but fill in its code as CODE, and do _not_ write it into + the code_to_optab table. */ +static inline optab +init_optabv (code) + enum rtx_code code; +{ + optab op = new_optab (); + op->code = code; return op; } @@ -4656,23 +4746,22 @@ init_optabs () #endif add_optab = init_optab (PLUS); - addv_optab = init_optab (PLUS); + addv_optab = init_optabv (PLUS); sub_optab = init_optab (MINUS); - subv_optab = init_optab (MINUS); + subv_optab = init_optabv (MINUS); smul_optab = init_optab (MULT); - smulv_optab = init_optab (MULT); + smulv_optab = init_optabv (MULT); smul_highpart_optab = init_optab (UNKNOWN); umul_highpart_optab = init_optab (UNKNOWN); smul_widen_optab = init_optab (UNKNOWN); umul_widen_optab = init_optab (UNKNOWN); sdiv_optab = init_optab (DIV); - sdivv_optab = init_optab (DIV); + sdivv_optab = init_optabv (DIV); sdivmod_optab = init_optab (UNKNOWN); udiv_optab = init_optab (UDIV); udivmod_optab = init_optab (UNKNOWN); smod_optab = init_optab (MOD); umod_optab = init_optab (UMOD); - flodiv_optab = init_optab (DIV); ftrunc_optab = init_optab (UNKNOWN); and_optab = init_optab (AND); ior_optab = init_optab (IOR); @@ -4686,15 +4775,19 @@ init_optabs () smax_optab = init_optab (SMAX); umin_optab = init_optab (UMIN); umax_optab = init_optab (UMAX); - mov_optab = init_optab (UNKNOWN); - movstrict_optab = init_optab (UNKNOWN); - cmp_optab = init_optab (UNKNOWN); + + /* These three have codes assigned exclusively for the sake of + have_insn_for. */ + mov_optab = init_optab (SET); + movstrict_optab = init_optab (STRICT_LOW_PART); + cmp_optab = init_optab (COMPARE); + ucmp_optab = init_optab (UNKNOWN); tst_optab = init_optab (UNKNOWN); neg_optab = init_optab (NEG); - negv_optab = init_optab (NEG); + negv_optab = init_optabv (NEG); abs_optab = init_optab (ABS); - absv_optab = init_optab (ABS); + absv_optab = init_optabv (ABS); one_cmpl_optab = init_optab (NOT); ffs_optab = init_optab (FFS); sqrt_optab = init_optab (SQRT); @@ -4741,13 +4834,13 @@ init_optabs () init_integral_libfuncs (smulv_optab, "mulv", '3'); init_floating_libfuncs (smulv_optab, "mul", '3'); init_integral_libfuncs (sdiv_optab, "div", '3'); + init_floating_libfuncs (sdiv_optab, "div", '3'); init_integral_libfuncs (sdivv_optab, "divv", '3'); init_integral_libfuncs (udiv_optab, "udiv", '3'); init_integral_libfuncs (sdivmod_optab, "divmod", '4'); init_integral_libfuncs (udivmod_optab, "udivmod", '4'); init_integral_libfuncs (smod_optab, "mod", '3'); init_integral_libfuncs (umod_optab, "umod", '3'); - init_floating_libfuncs (flodiv_optab, "div", '3'); init_floating_libfuncs (ftrunc_optab, "ftrunc", '2'); init_integral_libfuncs (and_optab, "and", '3'); init_integral_libfuncs (ior_optab, "ior", '3'); diff --git a/gcc/optabs.h b/gcc/optabs.h index 2f249c182db..dea49d3057c 100644 --- a/gcc/optabs.h +++ b/gcc/optabs.h @@ -79,8 +79,6 @@ enum optab_index /* Signed remainder */ OTI_smod, OTI_umod, - /* Optab for floating divide. */ - OTI_flodiv, /* Convert float to integer in float fmt */ OTI_ftrunc, @@ -173,7 +171,6 @@ extern optab optab_table[OTI_MAX]; #define udivmod_optab (optab_table[OTI_udivmod]) #define smod_optab (optab_table[OTI_smod]) #define umod_optab (optab_table[OTI_umod]) -#define flodiv_optab (optab_table[OTI_flodiv]) #define ftrunc_optab (optab_table[OTI_ftrunc]) #define and_optab (optab_table[OTI_and]) #define ior_optab (optab_table[OTI_ior]) @@ -229,21 +226,6 @@ extern enum insn_code reload_out_optab[NUM_MACHINE_MODES]; /* Contains the optab used for each rtx code. */ extern optab code_to_optab[NUM_RTX_CODE + 1]; -/* Passed to expand_binop and expand_unop to say which options to try to use - if the requested operation can't be open-coded on the requisite mode. - Either OPTAB_LIB or OPTAB_LIB_WIDEN says try using a library call. - Either OPTAB_WIDEN or OPTAB_LIB_WIDEN says try using a wider mode. - OPTAB_MUST_WIDEN says try widening and don't try anything else. */ - -enum optab_methods -{ - OPTAB_DIRECT, - OPTAB_LIB, - OPTAB_WIDEN, - OPTAB_LIB_WIDEN, - OPTAB_MUST_WIDEN -}; - typedef rtx (*rtxfun) PARAMS ((rtx)); diff --git a/gcc/profile.c b/gcc/profile.c index 39b259f3870..86a91a0a193 100644 --- a/gcc/profile.c +++ b/gcc/profile.c @@ -42,7 +42,6 @@ Boston, MA 02111-1307, USA. */ #include "output.h" #include "regs.h" #include "expr.h" -#include "optabs.h" #include "function.h" #include "toplev.h" #include "ggc.h" @@ -1072,8 +1071,8 @@ gen_edge_profiler (edgeno) tmp = plus_constant (tmp, GCOV_TYPE_SIZE / BITS_PER_UNIT * edgeno); mem_ref = validize_mem (gen_rtx_MEM (mode, tmp)); - tmp = expand_binop (mode, add_optab, mem_ref, const1_rtx, - mem_ref, 0, OPTAB_WIDEN); + tmp = expand_simple_binop (mode, PLUS, mem_ref, const1_rtx, + mem_ref, 0, OPTAB_WIDEN); if (tmp != mem_ref) emit_move_insn (copy_rtx (mem_ref), tmp); diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index 74e50c8f4cd..3dd0ee583cb 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -33,7 +33,6 @@ Boston, MA 02111-1307, USA. */ #include "recog.h" #include "function.h" #include "expr.h" -#include "optabs.h" #include "toplev.h" #include "output.h" #include "ggc.h" @@ -2520,8 +2519,7 @@ simplify_subreg (outermode, op, innermode, byte) /* Allow splitting of volatile memory references in case we don't have instruction to move the whole thing. */ && (! MEM_VOLATILE_P (op) - || (mov_optab->handlers[(int) innermode].insn_code - == CODE_FOR_nothing)) + || ! have_insn_for (SET, innermode)) && GET_MODE_SIZE (outermode) <= GET_MODE_SIZE (GET_MODE (op))) return adjust_address_nv (op, outermode, byte); diff --git a/gcc/stmt.c b/gcc/stmt.c index 357583d004f..5ef7ba90c7c 100644 --- a/gcc/stmt.c +++ b/gcc/stmt.c @@ -43,8 +43,8 @@ Boston, MA 02111-1307, USA. */ #include "except.h" #include "function.h" #include "insn-config.h" +#include "insn-codes.h" #include "expr.h" -#include "optabs.h" #include "libfuncs.h" #include "hard-reg-set.h" #include "obstack.h" @@ -5326,14 +5326,12 @@ expand_end_case (orig_index) generate the conversion. */ if (GET_MODE_CLASS (GET_MODE (index)) == MODE_INT - && (cmp_optab->handlers[(int) GET_MODE (index)].insn_code - == CODE_FOR_nothing)) + && ! have_insn_for (COMPARE, GET_MODE (index))) { enum machine_mode wider_mode; for (wider_mode = GET_MODE (index); wider_mode != VOIDmode; wider_mode = GET_MODE_WIDER_MODE (wider_mode)) - if (cmp_optab->handlers[(int) wider_mode].insn_code - != CODE_FOR_nothing) + if (have_insn_for (COMPARE, wider_mode)) { index = convert_to_mode (wider_mode, index, unsignedp); break; @@ -6345,13 +6343,14 @@ emit_case_nodes (index, node, default_label, index_type) tree type = type_for_mode (mode, unsignedp); tree low = build1 (CONVERT_EXPR, type, node->low); tree high = build1 (CONVERT_EXPR, type, node->high); - rtx new_index, new_bound; + rtx low_rtx, new_index, new_bound; /* Instead of doing two branches, emit one unsigned branch for (index-low) > (high-low). */ - new_index = expand_binop (mode, sub_optab, index, - expand_expr (low, NULL_RTX, mode, 0), - NULL_RTX, unsignedp, OPTAB_WIDEN); + low_rtx = expand_expr (low, NULL_RTX, mode, 0); + new_index = expand_simple_binop (mode, MINUS, index, low_rtx, + NULL_RTX, unsignedp, + OPTAB_WIDEN); new_bound = expand_expr (fold (build (MINUS_EXPR, type, high, low)), NULL_RTX, mode, 0); diff --git a/gcc/unroll.c b/gcc/unroll.c index 09a07321e47..eb33988bedc 100644 --- a/gcc/unroll.c +++ b/gcc/unroll.c @@ -163,7 +163,6 @@ enum unroll_types #include "flags.h" #include "function.h" #include "expr.h" -#include "optabs.h" #include "loop.h" #include "toplev.h" #include "hard-reg-set.h" @@ -936,15 +935,15 @@ unroll_loop (loop, insn_count, strength_reduce_p) We must copy the final and initial values here to avoid improperly shared rtl. */ - diff = expand_binop (mode, sub_optab, copy_rtx (final_value), - copy_rtx (initial_value), NULL_RTX, 0, - OPTAB_LIB_WIDEN); + diff = expand_simple_binop (mode, MINUS, copy_rtx (final_value), + copy_rtx (initial_value), NULL_RTX, 0, + OPTAB_LIB_WIDEN); /* Now calculate (diff % (unroll * abs (increment))) by using an and instruction. */ - diff = expand_binop (GET_MODE (diff), and_optab, diff, - GEN_INT (unroll_number * abs_inc - 1), - NULL_RTX, 0, OPTAB_LIB_WIDEN); + diff = expand_simple_binop (GET_MODE (diff), AND, diff, + GEN_INT (unroll_number * abs_inc - 1), + NULL_RTX, 0, OPTAB_LIB_WIDEN); /* Now emit a sequence of branches to jump to the proper precond loop entry point. */ @@ -2298,8 +2297,8 @@ emit_unrolled_add (dest_reg, src_reg, increment) { rtx result; - result = expand_binop (GET_MODE (dest_reg), add_optab, src_reg, increment, - dest_reg, 0, OPTAB_LIB_WIDEN); + result = expand_simple_binop (GET_MODE (dest_reg), PLUS, src_reg, increment, + dest_reg, 0, OPTAB_LIB_WIDEN); if (dest_reg != result) emit_move_insn (dest_reg, result); @@ -3314,9 +3313,9 @@ final_giv_value (loop, v) if (biv->insn == insn) { start_sequence (); - tem = expand_binop (GET_MODE (tem), sub_optab, tem, - biv->add_val, NULL_RTX, 0, - OPTAB_LIB_WIDEN); + tem = expand_simple_binop (GET_MODE (tem), MINUS, tem, + biv->add_val, NULL_RTX, 0, + OPTAB_LIB_WIDEN); seq = gen_sequence (); end_sequence (); loop_insn_sink (loop, seq); -- 2.11.0