expmed.c (store_bit_field): Try to simplify the subreg before generating a new one when...
2002-02-21 Eric Christopher <echristo@redhat.com> * expmed.c (store_bit_field): Try to simplify the subreg before generating a new one when when the mode size of value is less than maxmode. From-SVN: r49946
This commit is contained in:
parent
e3c8ea6725
commit
c410d49e43
2 changed files with 67 additions and 52 deletions
|
@ -1,3 +1,9 @@
|
|||
2002-02-21 Eric Christopher <echristo@redhat.com>
|
||||
|
||||
* expmed.c (store_bit_field): Try to simplify the subreg
|
||||
before generating a new one when when the mode size of
|
||||
value is less than maxmode.
|
||||
|
||||
2002-02-21 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* emit-rtl.c (offset_address): Use simplify_gen_binary rather
|
||||
|
@ -95,7 +101,7 @@ Thu Feb 21 15:35:46 2002 J"orn Rennecke <joern.rennecke@superh.com>
|
|||
bits of SImode const_int.
|
||||
(includes_rshift_p): Likewise.
|
||||
(print_operand): Call mask_operand and mask64_operand with correct
|
||||
mode.
|
||||
mode.
|
||||
(rs6000_output_function_epilogue): Pad traceback table to word.
|
||||
* config/rs6000/rs6000.h (MASK_64BIT): Correct comment.
|
||||
(EXTRA_CONSTRAINT, 'S' and 'T'): Call mask_operand and
|
||||
|
@ -161,7 +167,7 @@ Thu Feb 21 15:35:46 2002 J"orn Rennecke <joern.rennecke@superh.com>
|
|||
(ix86_expand_unop1_builtin): Likewise.
|
||||
|
||||
2002-02-20 Philip Blundell <philb@gnu.org>
|
||||
|
||||
|
||||
PR 5705
|
||||
* config/arm/arm.h (HARD_REGNO_RENAME_OK): New macro.
|
||||
|
||||
|
@ -203,7 +209,7 @@ Wed Feb 20 00:03:25 EST 2002 Alan Matsuoka <alanm@redhat.com>
|
|||
|
||||
* cppinit.c (init_dependency_output): Take deps output file
|
||||
from -o if none given with -MF. Suppress normal output.
|
||||
* gcc.c (cpp_unique_options): Have -M and -MM imply -E.
|
||||
* gcc.c (cpp_unique_options): Have -M and -MM imply -E.
|
||||
* doc/cpp.texi, doc/invoke.texi: Update.
|
||||
|
||||
2002-02-19 Zack Weinberg <zack@codesourcery.com>
|
||||
|
@ -217,7 +223,7 @@ Wed Feb 20 00:03:25 EST 2002 Alan Matsuoka <alanm@redhat.com>
|
|||
really_call_used[VRSAVE_REGNO] if not Altivec.
|
||||
|
||||
2002-02-19 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
|
||||
* config/rs6000/rs6000.c (u_short_cint_operand): Mask op with
|
||||
MODE_MASK.
|
||||
(constant_pool_expr_1): Fix formatting.
|
||||
|
@ -283,7 +289,7 @@ Tue Feb 19 20:13:57 2002 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
|
|||
(arm_assemble_integer): Likewise.
|
||||
* config/arm/arm.h (ARM_ENCODE_CALL_TYPE): Allow any decl to be
|
||||
marked local.
|
||||
|
||||
|
||||
2002-02-19 matthew green <mrg@eterna.com.au>
|
||||
|
||||
* config.gcc (sparc-*-netbsdelf*): Enable target.
|
||||
|
@ -465,7 +471,7 @@ Tue Feb 19 12:37:23 CET 2002 Jan Hubicka <jh@suse.cz>
|
|||
(decode_rtx_const): Add case for vector.
|
||||
|
||||
* config/rs6000/rs6000-protos.h: Add zero_constant.
|
||||
|
||||
|
||||
* config/rs6000/rs6000.c (rs6000_emit_move): Handle vector
|
||||
constants. Force easy vector constants into memory.
|
||||
(easy_vector_constant): New.
|
||||
|
@ -537,7 +543,7 @@ Mon Feb 18 11:55:55 CET 2002 Jan Hubicka <jh@suse.cz>
|
|||
2002-02-18 David Billinghurst <David.Billinghurst@riotinto.com>
|
||||
|
||||
* objc/objc-act.c (handle_impent): Remove leading '*'
|
||||
from objc_class_name.
|
||||
from objc_class_name.
|
||||
|
||||
2002-02-17 Richard Henderson <rth@redhat.com>
|
||||
|
||||
|
@ -593,7 +599,7 @@ Mon Feb 18 11:55:55 CET 2002 Jan Hubicka <jh@suse.cz>
|
|||
* config/arc/arc.c config/fr30/fr30.c config/m32r/m32r.c
|
||||
config/m88k/m88k.c : Adapt all calls to output_operand_lossage.
|
||||
Update copyright date where necessary.
|
||||
|
||||
|
||||
* config/i386/i386.c (print_operand): Likewise. Remove use of
|
||||
sprintf.
|
||||
|
||||
|
@ -662,15 +668,15 @@ Sat Feb 16 13:39:09 2002 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
|
|||
|
||||
2002-02-16 Ulrich Weigand <uweigand@de.ibm.com>
|
||||
|
||||
* config/s390/s390.c (pool_stop_uid, other_chunk, far_away,
|
||||
* config/s390/s390.c (pool_stop_uid, other_chunk, far_away,
|
||||
check_and_change_labels, s390_final_chunkify): Delete.
|
||||
(s390_split_branches, s390_chunkify_pool): New functions.
|
||||
(s390_function_prologue): Call them.
|
||||
|
||||
|
||||
* config/s390/s390.h (S390_REL_MAX): Delete.
|
||||
(S390_CHUNK_MAX, S390_CHUNK_OV): Adjust values.
|
||||
|
||||
* config/s390/s390.md (cjump, icjump, jump): Fix length
|
||||
* config/s390/s390.md (cjump, icjump, jump): Fix length
|
||||
attribute calculation.
|
||||
|
||||
|
||||
|
|
91
gcc/expmed.c
91
gcc/expmed.c
|
@ -54,7 +54,7 @@ static void do_cmp_and_jump PARAMS ((rtx, rtx, enum rtx_code,
|
|||
enum machine_mode, rtx));
|
||||
|
||||
/* Non-zero means divides or modulus operations are relatively cheap for
|
||||
powers of two, so don't use branches; emit the operation instead.
|
||||
powers of two, so don't use branches; emit the operation instead.
|
||||
Usually, this will mean that the MD file will emit non-branch
|
||||
sequences. */
|
||||
|
||||
|
@ -333,7 +333,7 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, total_size)
|
|||
If the target is memory, storing any naturally aligned field can be
|
||||
done with a simple store. For targets that support fast unaligned
|
||||
memory, any naturally sized, unit aligned field can be done directly. */
|
||||
|
||||
|
||||
byte_offset = (bitnum % BITS_PER_WORD) / BITS_PER_UNIT
|
||||
+ (offset * UNITS_PER_WORD);
|
||||
|
||||
|
@ -576,7 +576,7 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, total_size)
|
|||
&& GET_MODE_BITSIZE (bestmode) > MEM_ALIGN (op0)))
|
||||
goto insv_loses;
|
||||
|
||||
/* Adjust address to point to the containing unit of that mode.
|
||||
/* Adjust address to point to the containing unit of that mode.
|
||||
Compute offset as multiple of this unit, counting in bytes. */
|
||||
unit = GET_MODE_BITSIZE (bestmode);
|
||||
offset = (bitnum / unit) * GET_MODE_SIZE (bestmode);
|
||||
|
@ -630,8 +630,17 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, total_size)
|
|||
if we must narrow it, be sure we do it correctly. */
|
||||
|
||||
if (GET_MODE_SIZE (GET_MODE (value)) < GET_MODE_SIZE (maxmode))
|
||||
value1 = simplify_gen_subreg (maxmode, value1,
|
||||
GET_MODE (value1), 0);
|
||||
{
|
||||
rtx tmp;
|
||||
|
||||
tmp = simplify_subreg (maxmode, value1, GET_MODE (value), 0);
|
||||
if (! tmp)
|
||||
tmp = simplify_gen_subreg (maxmode,
|
||||
force_reg (GET_MODE (value),
|
||||
value1),
|
||||
GET_MODE (value), 0);
|
||||
value1 = tmp;
|
||||
}
|
||||
else
|
||||
value1 = gen_lowpart (maxmode, value1);
|
||||
}
|
||||
|
@ -712,7 +721,7 @@ store_fixed_bit_field (op0, offset, bitsize, bitpos, value)
|
|||
{
|
||||
/* Get the proper mode to use for this field. We want a mode that
|
||||
includes the entire field. If such a mode would be larger than
|
||||
a word, we won't be doing the extraction the normal way.
|
||||
a word, we won't be doing the extraction the normal way.
|
||||
We don't want a mode bigger than the destination. */
|
||||
|
||||
mode = GET_MODE (op0);
|
||||
|
@ -1061,7 +1070,7 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
|
|||
/* ??? We currently assume TARGET is at least as big as BITSIZE.
|
||||
If that's wrong, the solution is to test for it and set TARGET to 0
|
||||
if needed. */
|
||||
|
||||
|
||||
/* If OP0 is a register, BITPOS must count within a word.
|
||||
But as we have it, it counts within whatever size OP0 now has.
|
||||
On a bigendian machine, these are not the same, so convert. */
|
||||
|
@ -1128,7 +1137,7 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
|
|||
}
|
||||
|
||||
/* Handle fields bigger than a word. */
|
||||
|
||||
|
||||
if (bitsize > BITS_PER_WORD)
|
||||
{
|
||||
/* Here we transfer the words of the field
|
||||
|
@ -1200,14 +1209,14 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
|
|||
build_int_2 (GET_MODE_BITSIZE (mode) - bitsize, 0),
|
||||
NULL_RTX, 0);
|
||||
}
|
||||
|
||||
|
||||
/* From here on we know the desired field is smaller than a word. */
|
||||
|
||||
/* Check if there is a correspondingly-sized integer field, so we can
|
||||
safely extract it as one size of integer, if necessary; then
|
||||
truncate or extend to the size that is wanted; then use SUBREGs or
|
||||
convert_to_mode to get one of the modes we really wanted. */
|
||||
|
||||
|
||||
int_mode = int_mode_for_mode (tmode);
|
||||
if (int_mode == BLKmode)
|
||||
int_mode = int_mode_for_mode (mode);
|
||||
|
@ -1366,7 +1375,7 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
|
|||
}
|
||||
else
|
||||
extzv_loses:
|
||||
target = extract_fixed_bit_field (int_mode, op0, offset, bitsize,
|
||||
target = extract_fixed_bit_field (int_mode, op0, offset, bitsize,
|
||||
bitpos, target, 1);
|
||||
}
|
||||
else
|
||||
|
@ -1492,10 +1501,10 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
|
|||
target = extract_fixed_bit_field (int_mode, op0, offset, bitsize,
|
||||
bitpos, target, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
extv_loses:
|
||||
target = extract_fixed_bit_field (int_mode, op0, offset, bitsize,
|
||||
target = extract_fixed_bit_field (int_mode, op0, offset, bitsize,
|
||||
bitpos, target, 0);
|
||||
}
|
||||
if (target == spec_target)
|
||||
|
@ -1660,7 +1669,7 @@ extract_fixed_bit_field (tmode, op0, offset, bitsize, bitpos,
|
|||
}
|
||||
|
||||
return expand_shift (RSHIFT_EXPR, mode, op0,
|
||||
build_int_2 (GET_MODE_BITSIZE (mode) - bitsize, 0),
|
||||
build_int_2 (GET_MODE_BITSIZE (mode) - bitsize, 0),
|
||||
target, 0);
|
||||
}
|
||||
|
||||
|
@ -1685,7 +1694,7 @@ mask_rtx (mode, bitpos, bitsize, complement)
|
|||
if (bitpos + bitsize < HOST_BITS_PER_WIDE_INT)
|
||||
masklow &= ((unsigned HOST_WIDE_INT) -1
|
||||
>> (HOST_BITS_PER_WIDE_INT - bitpos - bitsize));
|
||||
|
||||
|
||||
if (bitpos <= HOST_BITS_PER_WIDE_INT)
|
||||
maskhigh = -1;
|
||||
else
|
||||
|
@ -1975,7 +1984,7 @@ expand_shift (code, mode, shifted, amount, target, unsignedp)
|
|||
&& (unsigned int) INTVAL (op1) < GET_MODE_BITSIZE (mode))
|
||||
temp = expand_binop (mode,
|
||||
left ? rotr_optab : rotl_optab,
|
||||
shifted,
|
||||
shifted,
|
||||
GEN_INT (GET_MODE_BITSIZE (mode)
|
||||
- INTVAL (op1)),
|
||||
target, unsignedp, methods);
|
||||
|
@ -2006,7 +2015,7 @@ expand_shift (code, mode, shifted, amount, target, unsignedp)
|
|||
}
|
||||
|
||||
/* We used to try extzv here for logical right shifts, but that was
|
||||
only useful for one machine, the VAX, and caused poor code
|
||||
only useful for one machine, the VAX, and caused poor code
|
||||
generation there for lshrdi3, so the code was deleted and a
|
||||
define_expand for lshrsi3 was added to vax.md. */
|
||||
}
|
||||
|
@ -2147,7 +2156,7 @@ synth_mult (alg_out, t, cost_limit)
|
|||
for (w = 1; (w & t) != 0; w <<= 1)
|
||||
;
|
||||
/* If T was -1, then W will be zero after the loop. This is another
|
||||
case where T ends with ...111. Handling this with (T + 1) and
|
||||
case where T ends with ...111. Handling this with (T + 1) and
|
||||
subtract 1 produces slightly better code and results in algorithm
|
||||
selection much faster than treating it like the ...0111 case
|
||||
below. */
|
||||
|
@ -2427,7 +2436,7 @@ expand_mult (mode, op0, op1, target, unsignedp)
|
|||
&& ! preserve)
|
||||
? target : 0;
|
||||
rtx accum_target = preserve ? 0 : accum;
|
||||
|
||||
|
||||
switch (alg.op[opno])
|
||||
{
|
||||
case alg_shift:
|
||||
|
@ -2509,7 +2518,7 @@ expand_mult (mode, op0, op1, target, unsignedp)
|
|||
}
|
||||
|
||||
insn = get_last_insn ();
|
||||
set_unique_reg_note (insn,
|
||||
set_unique_reg_note (insn,
|
||||
REG_EQUAL,
|
||||
gen_rtx_MULT (nmode, tem,
|
||||
GEN_INT (val_so_far)));
|
||||
|
@ -2535,7 +2544,7 @@ expand_mult (mode, op0, op1, target, unsignedp)
|
|||
|
||||
/* This used to use umul_optab if unsigned, but for non-widening multiply
|
||||
there is no difference between signed and unsigned. */
|
||||
op0 = expand_binop (mode,
|
||||
op0 = expand_binop (mode,
|
||||
! unsignedp
|
||||
&& flag_trapv && (GET_MODE_CLASS(mode) == MODE_INT)
|
||||
? smulv_optab : smul_optab,
|
||||
|
@ -2823,7 +2832,7 @@ expand_mult_highpart (mode, op0, cnst1, target, unsignedp, max_cost)
|
|||
{
|
||||
op1 = force_reg (mode, op1);
|
||||
goto try;
|
||||
}
|
||||
}
|
||||
|
||||
/* Try widening the mode and perform a non-widening multiplication. */
|
||||
moptab = smul_optab;
|
||||
|
@ -3230,7 +3239,7 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp)
|
|||
if (insn != last
|
||||
&& (set = single_set (insn)) != 0
|
||||
&& SET_DEST (set) == quotient)
|
||||
set_unique_reg_note (insn,
|
||||
set_unique_reg_note (insn,
|
||||
REG_EQUAL,
|
||||
gen_rtx_UDIV (compute_mode, op0, op1));
|
||||
}
|
||||
|
@ -3318,7 +3327,7 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp)
|
|||
&& SET_DEST (set) == quotient
|
||||
&& abs_d < ((unsigned HOST_WIDE_INT) 1
|
||||
<< (HOST_BITS_PER_WIDE_INT - 1)))
|
||||
set_unique_reg_note (insn,
|
||||
set_unique_reg_note (insn,
|
||||
REG_EQUAL,
|
||||
gen_rtx_DIV (compute_mode,
|
||||
op0,
|
||||
|
@ -3409,7 +3418,7 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp)
|
|||
if (insn != last
|
||||
&& (set = single_set (insn)) != 0
|
||||
&& SET_DEST (set) == quotient)
|
||||
set_unique_reg_note (insn,
|
||||
set_unique_reg_note (insn,
|
||||
REG_EQUAL,
|
||||
gen_rtx_DIV (compute_mode, op0, op1));
|
||||
}
|
||||
|
@ -3902,7 +3911,7 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp)
|
|||
emit_label (label);
|
||||
}
|
||||
return gen_lowpart (mode, rem_flag ? remainder : quotient);
|
||||
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
|
@ -4056,42 +4065,42 @@ make_tree (type, x)
|
|||
elt = CONST_VECTOR_ELT (x, i);
|
||||
t = tree_cons (NULL_TREE, make_tree (type, elt), t);
|
||||
}
|
||||
|
||||
|
||||
return build_vector (type, t);
|
||||
}
|
||||
|
||||
case PLUS:
|
||||
return fold (build (PLUS_EXPR, type, make_tree (type, XEXP (x, 0)),
|
||||
make_tree (type, XEXP (x, 1))));
|
||||
|
||||
|
||||
case MINUS:
|
||||
return fold (build (MINUS_EXPR, type, make_tree (type, XEXP (x, 0)),
|
||||
make_tree (type, XEXP (x, 1))));
|
||||
|
||||
|
||||
case NEG:
|
||||
return fold (build1 (NEGATE_EXPR, type, make_tree (type, XEXP (x, 0))));
|
||||
|
||||
case MULT:
|
||||
return fold (build (MULT_EXPR, type, make_tree (type, XEXP (x, 0)),
|
||||
make_tree (type, XEXP (x, 1))));
|
||||
|
||||
|
||||
case ASHIFT:
|
||||
return fold (build (LSHIFT_EXPR, type, make_tree (type, XEXP (x, 0)),
|
||||
make_tree (type, XEXP (x, 1))));
|
||||
|
||||
|
||||
case LSHIFTRT:
|
||||
return fold (convert (type,
|
||||
build (RSHIFT_EXPR, unsigned_type (type),
|
||||
make_tree (unsigned_type (type),
|
||||
XEXP (x, 0)),
|
||||
make_tree (type, XEXP (x, 1)))));
|
||||
|
||||
|
||||
case ASHIFTRT:
|
||||
return fold (convert (type,
|
||||
build (RSHIFT_EXPR, signed_type (type),
|
||||
make_tree (signed_type (type), XEXP (x, 0)),
|
||||
make_tree (type, XEXP (x, 1)))));
|
||||
|
||||
|
||||
case DIV:
|
||||
if (TREE_CODE (type) != REAL_TYPE)
|
||||
t = signed_type (type);
|
||||
|
@ -4182,7 +4191,7 @@ expand_and (mode, op0, op1, target)
|
|||
Return 0 if that cannot be done.
|
||||
|
||||
MODE is the mode to use for OP0 and OP1 should they be CONST_INTs. If
|
||||
it is VOIDmode, they cannot both be CONST_INT.
|
||||
it is VOIDmode, they cannot both be CONST_INT.
|
||||
|
||||
UNSIGNEDP is for the case where we have to widen the operands
|
||||
to perform the operation. It says to use zero-extension.
|
||||
|
@ -4230,7 +4239,7 @@ emit_store_flag (target, code, op0, op1, mode, unsignedp, normalizep)
|
|||
if (mode == VOIDmode)
|
||||
mode = GET_MODE (op0);
|
||||
|
||||
/* For some comparisons with 1 and -1, we can convert this to
|
||||
/* For some comparisons with 1 and -1, we can convert this to
|
||||
comparisons with zero. This will often produce more opportunities for
|
||||
store-flag insns. */
|
||||
|
||||
|
@ -4433,7 +4442,7 @@ emit_store_flag (target, code, op0, op1, mode, unsignedp, normalizep)
|
|||
else
|
||||
abort ();
|
||||
|
||||
/* If we were converting to a smaller mode, do the
|
||||
/* If we were converting to a smaller mode, do the
|
||||
conversion now. */
|
||||
if (target_mode != compare_mode)
|
||||
{
|
||||
|
@ -4478,7 +4487,7 @@ emit_store_flag (target, code, op0, op1, mode, unsignedp, normalizep)
|
|||
return tem;
|
||||
}
|
||||
|
||||
/* Some other cases we can do are EQ, NE, LE, and GT comparisons with
|
||||
/* Some other cases we can do are EQ, NE, LE, and GT comparisons with
|
||||
the constant zero. Reject all other comparisons at this point. Only
|
||||
do LE and GT if branches are expensive since they are expensive on
|
||||
2-operand machines. */
|
||||
|
@ -4540,22 +4549,22 @@ emit_store_flag (target, code, op0, op1, mode, unsignedp, normalizep)
|
|||
tem = expand_binop (mode, sub_optab, tem, op0, subtarget, 0,
|
||||
OPTAB_WIDEN);
|
||||
}
|
||||
|
||||
|
||||
if (code == EQ || code == NE)
|
||||
{
|
||||
/* For EQ or NE, one way to do the comparison is to apply an operation
|
||||
that converts the operand into a positive number if it is non-zero
|
||||
or zero if it was originally zero. Then, for EQ, we subtract 1 and
|
||||
for NE we negate. This puts the result in the sign bit. Then we
|
||||
normalize with a shift, if needed.
|
||||
normalize with a shift, if needed.
|
||||
|
||||
Two operations that can do the above actions are ABS and FFS, so try
|
||||
them. If that doesn't work, and MODE is smaller than a full word,
|
||||
we can use zero-extension to the wider mode (an unsigned conversion)
|
||||
as the operation. */
|
||||
|
||||
/* Note that ABS doesn't yield a positive number for INT_MIN, but
|
||||
that is compensated by the subsequent overflow when subtracting
|
||||
/* Note that ABS doesn't yield a positive number for INT_MIN, but
|
||||
that is compensated by the subsequent overflow when subtracting
|
||||
one / negating. */
|
||||
|
||||
if (abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
|
||||
|
|
Loading…
Add table
Reference in a new issue