From 9068af20f17bc257569a26a39a00fe4ef11066fa Mon Sep 17 00:00:00 2001 From: zack Date: Wed, 22 Aug 2001 00:33:33 +0000 Subject: [PATCH] * expmed.c (mode_for_extraction): New function. (store_bit_field, extract_bit_field): Use it. * expr.h: Prototype it and provide an enum for its first argument. * combine.c, function.c, recog.c: Don't include insn-codes.h. Use mode_for_extraction rather than testing HAVE_insv/extv/extzv and digging through the insn_data tables. * Makefile.in: Update dependencies. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@45086 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 11 ++++++ gcc/Makefile.in | 6 ++-- gcc/combine.c | 77 +++++++++++++----------------------------- gcc/expmed.c | 102 ++++++++++++++++++++++++++++++++++++++------------------ gcc/expr.h | 8 +++++ gcc/function.c | 34 ++++++++----------- gcc/recog.c | 23 ++++++------- 7 files changed, 138 insertions(+), 123 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 11a3364..f07bea4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2001-08-21 Zack Weinberg + + * expmed.c (mode_for_extraction): New function. + (store_bit_field, extract_bit_field): Use it. + * expr.h: Prototype it and provide an enum for its first argument. + + * combine.c, function.c, recog.c: Don't include insn-codes.h. + Use mode_for_extraction rather than testing HAVE_insv/extv/extzv + and digging through the insn_data tables. + * Makefile.in: Update dependencies. + 2001-08-22 Neil Booth * cppfiles.c (stack_include_file): line-map.c now handles include diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 478a10c..22861cc 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1380,7 +1380,7 @@ 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 insn-codes.h $(EXPR_H) libfuncs.h $(REGS_H) hard-reg-set.h \ + function.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) libfuncs.h except.h \ @@ -1490,7 +1490,7 @@ flow.o : flow.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h insn-config.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-codes.h $(INSN_ATTR_H) $(REGS_H) $(EXPR_H) \ + insn-config.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 \ @@ -1545,7 +1545,7 @@ final.o : final.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h intl.h \ toplev.h reload.h dwarf2out.h $(BASIC_BLOCK_H) $(TM_P_H) $(TARGET_H) recog.o : recog.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) function.h $(BASIC_BLOCK_H) \ $(REGS_H) $(RECOG_H) $(EXPR_H) hard-reg-set.h flags.h insn-config.h \ - $(INSN_ATTR_H) insn-codes.h real.h toplev.h output.h reload.h $(TM_P_H) + $(INSN_ATTR_H) real.h toplev.h output.h reload.h $(TM_P_H) reg-stack.o : reg-stack.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) $(RECOG_H) \ $(REGS_H) hard-reg-set.h flags.h insn-config.h toplev.h reload.h \ varray.h function.h $(TM_P_H) diff --git a/gcc/combine.c b/gcc/combine.c index b453396..5c6dcbc 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -83,7 +83,6 @@ 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" @@ -6004,59 +6003,28 @@ make_extraction (mode, inner, pos, pos_rtx, len, /* Get the mode to use should INNER not be a MEM, the mode for the position, and the mode for the result. */ -#ifdef HAVE_insv - if (in_dest) + if (in_dest && mode_for_extraction(EP_insv, -1) != MAX_MACHINE_MODE) { - wanted_inner_reg_mode - = insn_data[(int) CODE_FOR_insv].operand[0].mode; - if (wanted_inner_reg_mode == VOIDmode) - wanted_inner_reg_mode = word_mode; - - pos_mode = insn_data[(int) CODE_FOR_insv].operand[2].mode; - if (pos_mode == VOIDmode) - pos_mode = word_mode; - - extraction_mode = insn_data[(int) CODE_FOR_insv].operand[3].mode; - if (extraction_mode == VOIDmode) - extraction_mode = word_mode; + wanted_inner_reg_mode = mode_for_extraction (EP_insv, 0); + pos_mode = mode_for_extraction (EP_insv, 2); + extraction_mode = mode_for_extraction (EP_insv, 3); } -#endif -#ifdef HAVE_extzv - if (! in_dest && unsignedp) + if (! in_dest && unsignedp + && mode_for_extraction (EP_extzv, -1) != MAX_MACHINE_MODE) { - wanted_inner_reg_mode - = insn_data[(int) CODE_FOR_extzv].operand[1].mode; - if (wanted_inner_reg_mode == VOIDmode) - wanted_inner_reg_mode = word_mode; - - pos_mode = insn_data[(int) CODE_FOR_extzv].operand[3].mode; - if (pos_mode == VOIDmode) - pos_mode = word_mode; - - extraction_mode = insn_data[(int) CODE_FOR_extzv].operand[0].mode; - if (extraction_mode == VOIDmode) - extraction_mode = word_mode; + wanted_inner_reg_mode = mode_for_extraction (EP_extzv, 1); + pos_mode = mode_for_extraction (EP_extzv, 3); + extraction_mode = mode_for_extraction (EP_extzv, 0); } -#endif -#ifdef HAVE_extv - if (! in_dest && ! unsignedp) + if (! in_dest && ! unsignedp + && mode_for_extraction (EP_extv, -1) != MAX_MACHINE_MODE) { - wanted_inner_reg_mode - = insn_data[(int) CODE_FOR_extv].operand[1].mode; - if (wanted_inner_reg_mode == VOIDmode) - wanted_inner_reg_mode = word_mode; - - pos_mode = insn_data[(int) CODE_FOR_extv].operand[3].mode; - if (pos_mode == VOIDmode) - pos_mode = word_mode; - - extraction_mode = insn_data[(int) CODE_FOR_extv].operand[0].mode; - if (extraction_mode == VOIDmode) - extraction_mode = word_mode; + wanted_inner_reg_mode = mode_for_extraction (EP_extv, 1); + pos_mode = mode_for_extraction (EP_extv, 3); + extraction_mode = mode_for_extraction (EP_extv, 0); } -#endif /* Never narrow an object, since that might not be safe. */ @@ -10235,14 +10203,15 @@ simplify_comparison (code, pop0, pop1) { if (BITS_BIG_ENDIAN) { -#ifdef HAVE_extzv - mode = insn_data[(int) CODE_FOR_extzv].operand[1].mode; - if (mode == VOIDmode) - mode = word_mode; - i = (GET_MODE_BITSIZE (mode) - 1 - i); -#else - i = BITS_PER_WORD - 1 - i; -#endif + enum machine_mode new_mode + = mode_for_extraction (EP_extzv, 1); + if (new_mode == MAX_MACHINE_MODE) + i = BITS_PER_WORD - 1 - i; + else + { + mode = new_mode; + i = (GET_MODE_BITSIZE (mode) - 1 - i); + } } op0 = XEXP (op0, 2); diff --git a/gcc/expmed.c b/gcc/expmed.c index 830ef9e..e3918d8 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -203,6 +203,61 @@ negate_rtx (mode, x) return result; } + +/* Report on the availability of insv/extv/extzv and the desired mode + of each of their operands. Returns MAX_MACHINE_MODE if HAVE_foo + is false; else the mode of the specified operand. If OPNO is -1, + all the caller cares about is whether the insn is available. */ +enum machine_mode +mode_for_extraction (pattern, opno) + enum extraction_pattern pattern; + int opno; +{ + const struct insn_data *data; + + switch (pattern) + { + case EP_insv: +#ifdef HAVE_insv + if (HAVE_insv) + { + data = &insn_data[CODE_FOR_insv]; + break; + } +#endif + return MAX_MACHINE_MODE; + + case EP_extv: +#ifdef HAVE_extv + if (HAVE_extv) + { + data = &insn_data[CODE_FOR_extv]; + break; + } +#endif + return MAX_MACHINE_MODE; + + case EP_extzv: +#ifdef HAVE_extzv + if (HAVE_extzv) + { + data = &insn_data[CODE_FOR_extzv]; + break; + } +#endif + return MAX_MACHINE_MODE; + } + + if (opno == -1) + return VOIDmode; + + /* Everyone who uses this function used to follow it with + if (result == VOIDmode) result = word_mode; */ + if (data->operand[opno].mode == VOIDmode) + return word_mode; + return data->operand[opno].mode; +} + /* Generate code to store value from rtx VALUE into a bit-field within structure STR_RTX @@ -234,15 +289,13 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size) unsigned HOST_WIDE_INT offset = bitnum / unit; unsigned HOST_WIDE_INT bitpos = bitnum % unit; register rtx op0 = str_rtx; -#ifdef HAVE_insv + unsigned HOST_WIDE_INT insv_bitsize; enum machine_mode op_mode; - op_mode = insn_data[(int) CODE_FOR_insv].operand[3].mode; - if (op_mode == VOIDmode) - op_mode = word_mode; - insv_bitsize = GET_MODE_BITSIZE (op_mode); -#endif + op_mode = mode_for_extraction (EP_insv, 3); + if (op_mode != MAX_MACHINE_MODE) + insv_bitsize = GET_MODE_BITSIZE (op_mode); /* It is wrong to have align==0, since every object is aligned at least at a bit boundary. This usually means a bug elsewhere. */ @@ -475,8 +528,7 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size) /* Now OFFSET is nonzero only if OP0 is memory and is therefore always measured in bytes. */ -#ifdef HAVE_insv - if (HAVE_insv + if (op_mode != MAX_MACHINE_MODE && GET_MODE (value) != BLKmode && !(bitsize == 1 && GET_CODE (value) == CONST_INT) /* Ensure insv's size is wide enough for this field. */ @@ -617,7 +669,6 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size) } else insv_loses: -#endif /* Insv is not available; store using shifts and boolean ops. */ store_fixed_bit_field (op0, offset, bitsize, bitpos, value, align); return value; @@ -981,28 +1032,18 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp, rtx spec_target = target; rtx spec_target_subreg = 0; enum machine_mode int_mode; -#ifdef HAVE_extv unsigned HOST_WIDE_INT extv_bitsize; enum machine_mode extv_mode; -#endif -#ifdef HAVE_extzv unsigned HOST_WIDE_INT extzv_bitsize; enum machine_mode extzv_mode; -#endif -#ifdef HAVE_extv - extv_mode = insn_data[(int) CODE_FOR_extv].operand[0].mode; - if (extv_mode == VOIDmode) - extv_mode = word_mode; - extv_bitsize = GET_MODE_BITSIZE (extv_mode); -#endif + extv_mode = mode_for_extraction (EP_extv, 0); + if (extv_mode != MAX_MACHINE_MODE) + extv_bitsize = GET_MODE_BITSIZE (extv_mode); -#ifdef HAVE_extzv - extzv_mode = insn_data[(int) CODE_FOR_extzv].operand[0].mode; - if (extzv_mode == VOIDmode) - extzv_mode = word_mode; - extzv_bitsize = GET_MODE_BITSIZE (extzv_mode); -#endif + extzv_mode = mode_for_extraction (EP_extzv, 0); + if (extzv_mode != MAX_MACHINE_MODE) + extzv_bitsize = GET_MODE_BITSIZE (extzv_mode); /* Discount the part of the structure before the desired byte. We need to know how many bytes are safe to reference after it. */ @@ -1236,8 +1277,7 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp, if (unsignedp) { -#ifdef HAVE_extzv - if (HAVE_extzv + if (extzv_mode != MAX_MACHINE_MODE && (extzv_bitsize >= bitsize) && ! ((GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG) && (bitsize + bitpos > extzv_bitsize))) @@ -1369,14 +1409,12 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp, } else extzv_loses: -#endif target = extract_fixed_bit_field (int_mode, op0, offset, bitsize, bitpos, target, 1, align); } else { -#ifdef HAVE_extv - if (HAVE_extv + if (extv_mode != MAX_MACHINE_MODE && (extv_bitsize >= bitsize) && ! ((GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG) && (bitsize + bitpos > extv_bitsize))) @@ -1503,7 +1541,6 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp, } else extv_loses: -#endif target = extract_fixed_bit_field (int_mode, op0, offset, bitsize, bitpos, target, 0, align); } @@ -2000,7 +2037,8 @@ expand_shift (code, mode, shifted, amount, target, unsignedp) that is in range, try a rotate in the opposite direction. */ if (temp == 0 && GET_CODE (op1) == CONST_INT - && INTVAL (op1) > 0 && INTVAL (op1) < GET_MODE_BITSIZE (mode)) + && INTVAL (op1) > 0 + && (unsigned int) INTVAL (op1) < GET_MODE_BITSIZE (mode)) temp = expand_binop (mode, left ? rotr_optab : rotl_optab, shifted, diff --git a/gcc/expr.h b/gcc/expr.h index 22e537d..9bf2adb 100644 --- a/gcc/expr.h +++ b/gcc/expr.h @@ -715,6 +715,14 @@ extern rtx hard_libcall_value PARAMS ((enum machine_mode)); of STACK_BOUNDARY / BITS_PER_UNIT. */ extern rtx round_push PARAMS ((rtx)); +/* Return the mode desired by operand N of a particular bitfield + insert/extract insn, or MAX_MACHINE_MODE if no such insn is + available. */ + +enum extraction_pattern { EP_insv, EP_extv, EP_extzv }; +extern enum machine_mode +mode_for_extraction PARAMS ((enum extraction_pattern, int)); + extern rtx store_bit_field PARAMS ((rtx, unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, enum machine_mode, rtx, diff --git a/gcc/function.c b/gcc/function.c index 6c8a937..93add2a 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -50,7 +50,6 @@ Boston, MA 02111-1307, USA. */ #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" @@ -2064,23 +2063,21 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements) enum machine_mode is_mode = GET_MODE (tem); HOST_WIDE_INT pos = INTVAL (XEXP (x, 2)); -#ifdef HAVE_extzv if (GET_CODE (x) == ZERO_EXTRACT) { - wanted_mode - = insn_data[(int) CODE_FOR_extzv].operand[1].mode; - if (wanted_mode == VOIDmode) - wanted_mode = word_mode; + enum machine_mode new_mode + = mode_for_extraction (EP_extzv, 1); + if (new_mode != MAX_MACHINE_MODE) + wanted_mode = new_mode; } -#endif -#ifdef HAVE_extv - if (GET_CODE (x) == SIGN_EXTRACT) + else if (GET_CODE (x) == SIGN_EXTRACT) { - wanted_mode = insn_data[(int) CODE_FOR_extv].operand[1].mode; - if (wanted_mode == VOIDmode) - wanted_mode = word_mode; + enum machine_mode new_mode + = mode_for_extraction (EP_extv, 1); + if (new_mode != MAX_MACHINE_MODE) + wanted_mode = new_mode; } -#endif + /* If we have a narrower mode, we can do something. */ if (wanted_mode != VOIDmode && GET_MODE_SIZE (wanted_mode) < GET_MODE_SIZE (is_mode)) @@ -2215,9 +2212,7 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements) { rtx dest = SET_DEST (x); rtx src = SET_SRC (x); -#ifdef HAVE_insv rtx outerdest = dest; -#endif while (GET_CODE (dest) == SUBREG || GET_CODE (dest) == STRICT_LOW_PART || GET_CODE (dest) == SIGN_EXTRACT @@ -2236,8 +2231,8 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements) /* We will need to rerecognize this insn. */ INSN_CODE (insn) = -1; -#ifdef HAVE_insv - if (GET_CODE (outerdest) == ZERO_EXTRACT && dest == var) + if (GET_CODE (outerdest) == ZERO_EXTRACT && dest == var + && mode_for_extraction (EP_insv, -1) != MAX_MACHINE_MODE) { /* Since this case will return, ensure we fixup all the operands here. */ @@ -2268,9 +2263,7 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements) enum machine_mode is_mode = GET_MODE (tem); HOST_WIDE_INT pos = INTVAL (XEXP (outerdest, 2)); - wanted_mode = insn_data[(int) CODE_FOR_insv].operand[0].mode; - if (wanted_mode == VOIDmode) - wanted_mode = word_mode; + wanted_mode = mode_for_extraction (EP_insv, 0); /* If we have a narrower mode, we can do something. */ if (GET_MODE_SIZE (wanted_mode) < GET_MODE_SIZE (is_mode)) @@ -2311,7 +2304,6 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements) XEXP (outerdest, 0) = tem1; return; } -#endif /* STRICT_LOW_PART is a no-op on memory references and it can cause combinations to be unrecognizable, diff --git a/gcc/recog.c b/gcc/recog.c index f2e046f..3ec2eeb 100644 --- a/gcc/recog.c +++ b/gcc/recog.c @@ -30,7 +30,6 @@ Boston, MA 02111-1307, USA. */ #include "recog.h" #include "regs.h" #include "expr.h" -#include "insn-codes.h" #include "function.h" #include "flags.h" #include "real.h" @@ -566,22 +565,20 @@ validate_replace_rtx_1 (loc, from, to, object) enum machine_mode is_mode = GET_MODE (XEXP (x, 0)); int pos = INTVAL (XEXP (x, 2)); -#ifdef HAVE_extzv - if (code == ZERO_EXTRACT) + if (GET_CODE (x) == ZERO_EXTRACT) { - wanted_mode = insn_data[(int) CODE_FOR_extzv].operand[1].mode; - if (wanted_mode == VOIDmode) - wanted_mode = word_mode; + enum machine_mode new_mode + = mode_for_extraction (EP_extzv, 1); + if (new_mode != MAX_MACHINE_MODE) + wanted_mode = new_mode; } -#endif -#ifdef HAVE_extv - if (code == SIGN_EXTRACT) + else if (GET_CODE (x) == SIGN_EXTRACT) { - wanted_mode = insn_data[(int) CODE_FOR_extv].operand[1].mode; - if (wanted_mode == VOIDmode) - wanted_mode = word_mode; + enum machine_mode new_mode + = mode_for_extraction (EP_extv, 1); + if (new_mode != MAX_MACHINE_MODE) + wanted_mode = new_mode; } -#endif /* If we have a narrower mode, we can do something. */ if (wanted_mode != VOIDmode -- 2.7.4