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
This commit is contained in:
Zack Weinberg 2001-08-22 00:33:33 +00:00 committed by Zack Weinberg
parent d8693c6fa4
commit da92057001
7 changed files with 138 additions and 123 deletions

View File

@ -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

View File

@ -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)

View File

@ -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);

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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