aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorZack Weinberg <zackw@panix.com>2001-08-22 00:33:33 +0000
committerZack Weinberg <zack@gcc.gnu.org>2001-08-22 00:33:33 +0000
commitda92057001929e2c650454e11d828d4296217e3d (patch)
tree129eec34d330cb3fc70326b18b8ff46f6e80e5e2 /gcc
parentd8693c6fa425fecaf6570114f1cd69aaf3c08043 (diff)
downloadgcc-da92057001929e2c650454e11d828d4296217e3d.zip
gcc-da92057001929e2c650454e11d828d4296217e3d.tar.gz
gcc-da92057001929e2c650454e11d828d4296217e3d.tar.bz2
expmed.c (mode_for_extraction): New function.
* 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. From-SVN: r45086
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/Makefile.in6
-rw-r--r--gcc/combine.c77
-rw-r--r--gcc/expmed.c102
-rw-r--r--gcc/expr.h8
-rw-r--r--gcc/function.c34
-rw-r--r--gcc/recog.c23
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 <zackw@panix.com>
+
+ * 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 <neil@daikokuya.demon.co.uk>
* 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