Commit 8999a12e by Richard Kenner

(make_extraction): Don't use POS < 0 as a flag that POS_RTX is to be used;…

(make_extraction): Don't use POS < 0 as a flag that POS_RTX is to be used; instead use POS_RTX unless it is nonzero.

(make_extraction): Don't use POS < 0 as a flag that POS_RTX is to be
used; instead use POS_RTX unless it is nonzero.  If POS_RTX is a
constant, set POS and clear POS_RTX.
(make_compound_operation, make_field_assignment): Pass 0 for POS
instead of -1 when POS_RTX is nonzero.

From-SVN: r3178
parent 08fb99fa
...@@ -4542,9 +4542,9 @@ expand_field_assignment (x) ...@@ -4542,9 +4542,9 @@ expand_field_assignment (x)
return x; return x;
} }
/* Return an RTX for a reference to LEN bits of INNER. POS is the starting /* Return an RTX for a reference to LEN bits of INNER. If POS_RTX is nonzero,
bit position (counted from the LSB) if >= 0; otherwise POS_RTX represents it is an RTX that represents a variable starting position; otherwise,
the starting bit position. POS is the (constant) starting bit position (counted from the LSB).
INNER may be a USE. This will occur when we started with a bitfield INNER may be a USE. This will occur when we started with a bitfield
that went outside the boundary of the object in memory, which is that went outside the boundary of the object in memory, which is
...@@ -4588,6 +4588,7 @@ make_extraction (mode, inner, pos, pos_rtx, len, ...@@ -4588,6 +4588,7 @@ make_extraction (mode, inner, pos, pos_rtx, len,
enum machine_mode tmode = mode_for_size (len, MODE_INT, 1); enum machine_mode tmode = mode_for_size (len, MODE_INT, 1);
int spans_byte = 0; int spans_byte = 0;
rtx new = 0; rtx new = 0;
rtx orig_pos_rtx = pos_rtx;
/* Get some information about INNER and get the innermost object. */ /* Get some information about INNER and get the innermost object. */
if (GET_CODE (inner) == USE) if (GET_CODE (inner) == USE)
...@@ -4610,7 +4611,7 @@ make_extraction (mode, inner, pos, pos_rtx, len, ...@@ -4610,7 +4611,7 @@ make_extraction (mode, inner, pos, pos_rtx, len,
inner_mode = GET_MODE (inner); inner_mode = GET_MODE (inner);
if (pos_rtx && GET_CODE (pos_rtx) == CONST_INT) if (pos_rtx && GET_CODE (pos_rtx) == CONST_INT)
pos = INTVAL (pos_rtx); pos = INTVAL (pos_rtx), pos_rtx = 0;
/* See if this can be done without an extraction. We never can if the /* See if this can be done without an extraction. We never can if the
width of the field is not the same as that of some integer mode. For width of the field is not the same as that of some integer mode. For
...@@ -4627,12 +4628,12 @@ make_extraction (mode, inner, pos, pos_rtx, len, ...@@ -4627,12 +4628,12 @@ make_extraction (mode, inner, pos, pos_rtx, len,
if (tmode != BLKmode if (tmode != BLKmode
&& ! (spans_byte && inner_mode != tmode) && ! (spans_byte && inner_mode != tmode)
&& ((pos == 0 && GET_CODE (inner) != MEM && ((pos_rtx == 0 && pos == 0 && GET_CODE (inner) != MEM
&& (! in_dest && (! in_dest
|| (GET_CODE (inner) == REG || (GET_CODE (inner) == REG
&& (movstrict_optab->handlers[(int) tmode].insn_code && (movstrict_optab->handlers[(int) tmode].insn_code
!= CODE_FOR_nothing)))) != CODE_FOR_nothing))))
|| (GET_CODE (inner) == MEM && pos >= 0 || (GET_CODE (inner) == MEM && pos_rtx == 0
&& (pos && (pos
% (STRICT_ALIGNMENT ? GET_MODE_ALIGNMENT (tmode) % (STRICT_ALIGNMENT ? GET_MODE_ALIGNMENT (tmode)
: BITS_PER_UNIT)) == 0 : BITS_PER_UNIT)) == 0
...@@ -4696,7 +4697,8 @@ make_extraction (mode, inner, pos, pos_rtx, len, ...@@ -4696,7 +4697,8 @@ make_extraction (mode, inner, pos, pos_rtx, len,
/* Unless this is a COMPARE or we have a funny memory reference, /* Unless this is a COMPARE or we have a funny memory reference,
don't do anything with zero-extending field extracts starting at don't do anything with zero-extending field extracts starting at
the low-order bit since they are simple AND operations. */ the low-order bit since they are simple AND operations. */
if (pos == 0 && ! in_dest && ! in_compare && ! spans_byte && unsignedp) if (pos_rtx == 0 && pos == 0 && ! in_dest
&& ! in_compare && ! spans_byte && unsignedp)
return 0; return 0;
/* Get the mode to use should INNER be a MEM, the mode for the position, /* Get the mode to use should INNER be a MEM, the mode for the position,
...@@ -4749,7 +4751,7 @@ make_extraction (mode, inner, pos, pos_rtx, len, ...@@ -4749,7 +4751,7 @@ make_extraction (mode, inner, pos, pos_rtx, len,
#if BITS_BIG_ENDIAN #if BITS_BIG_ENDIAN
/* If position is constant, compute new position. Otherwise, build /* If position is constant, compute new position. Otherwise, build
subtraction. */ subtraction. */
if (pos >= 0) if (pos_rtx == 0)
pos = (MAX (GET_MODE_BITSIZE (is_mode), GET_MODE_BITSIZE (wanted_mem_mode)) pos = (MAX (GET_MODE_BITSIZE (is_mode), GET_MODE_BITSIZE (wanted_mem_mode))
- len - pos); - len - pos);
else else
...@@ -4792,7 +4794,7 @@ make_extraction (mode, inner, pos, pos_rtx, len, ...@@ -4792,7 +4794,7 @@ make_extraction (mode, inner, pos, pos_rtx, len,
#endif #endif
/* If this is a constant position, we can move to the desired byte. */ /* If this is a constant position, we can move to the desired byte. */
if (pos >= 0) if (pos_rtx == 0)
{ {
offset += pos / BITS_PER_UNIT; offset += pos / BITS_PER_UNIT;
pos %= GET_MODE_BITSIZE (wanted_mem_mode); pos %= GET_MODE_BITSIZE (wanted_mem_mode);
...@@ -4818,15 +4820,20 @@ make_extraction (mode, inner, pos, pos_rtx, len, ...@@ -4818,15 +4820,20 @@ make_extraction (mode, inner, pos, pos_rtx, len,
/* Adjust mode of POS_RTX, if needed. If we want a wider mode, we /* Adjust mode of POS_RTX, if needed. If we want a wider mode, we
have to zero extend. Otherwise, we can just use a SUBREG. */ have to zero extend. Otherwise, we can just use a SUBREG. */
if (pos < 0 if (pos_rtx != 0
&& GET_MODE_SIZE (pos_mode) > GET_MODE_SIZE (GET_MODE (pos_rtx))) && GET_MODE_SIZE (pos_mode) > GET_MODE_SIZE (GET_MODE (pos_rtx)))
pos_rtx = gen_rtx_combine (ZERO_EXTEND, pos_mode, pos_rtx); pos_rtx = gen_rtx_combine (ZERO_EXTEND, pos_mode, pos_rtx);
else if (pos < 0 else if (pos_rtx != 0
&& GET_MODE_SIZE (pos_mode) < GET_MODE_SIZE (GET_MODE (pos_rtx))) && GET_MODE_SIZE (pos_mode) < GET_MODE_SIZE (GET_MODE (pos_rtx)))
pos_rtx = gen_lowpart_for_combine (pos_mode, pos_rtx); pos_rtx = gen_lowpart_for_combine (pos_mode, pos_rtx);
/* Make POS_RTX unless we already have it and it is correct. */ /* Make POS_RTX unless we already have it and it is correct. If we don't
if (pos_rtx == 0 || (pos >= 0 && INTVAL (pos_rtx) != pos)) have a POS_RTX but we do have an ORIG_POS_RTX, the latter must
be a CONST_INT. */
if (pos_rtx == 0 && orig_pos_rtx != 0 && INTVAL (orig_pos_rtx) == pos)
pos_rtx = orig_pos_rtx;
else if (pos_rtx == 0)
pos_rtx = GEN_INT (pos); pos_rtx = GEN_INT (pos);
/* Make the required operation. See if we can use existing rtx. */ /* Make the required operation. See if we can use existing rtx. */
...@@ -4905,7 +4912,7 @@ make_compound_operation (x, in_code) ...@@ -4905,7 +4912,7 @@ make_compound_operation (x, in_code)
is a logical right shift, make an extraction. */ is a logical right shift, make an extraction. */
if (GET_CODE (XEXP (x, 0)) == LSHIFTRT if (GET_CODE (XEXP (x, 0)) == LSHIFTRT
&& (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0) && (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0)
new = make_extraction (mode, XEXP (XEXP (x, 0), 0), -1, new = make_extraction (mode, XEXP (XEXP (x, 0), 0), 0,
XEXP (XEXP (x, 0), 1), i, 1, XEXP (XEXP (x, 0), 1), i, 1,
0, in_code == COMPARE); 0, in_code == COMPARE);
...@@ -4915,7 +4922,7 @@ make_compound_operation (x, in_code) ...@@ -4915,7 +4922,7 @@ make_compound_operation (x, in_code)
&& GET_CODE (SUBREG_REG (XEXP (x, 0))) == LSHIFTRT && GET_CODE (SUBREG_REG (XEXP (x, 0))) == LSHIFTRT
&& (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0) && (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0)
new = make_extraction (GET_MODE (SUBREG_REG (XEXP (x, 0))), new = make_extraction (GET_MODE (SUBREG_REG (XEXP (x, 0))),
XEXP (SUBREG_REG (XEXP (x, 0)), 0), -1, XEXP (SUBREG_REG (XEXP (x, 0)), 0), 0,
XEXP (SUBREG_REG (XEXP (x, 0)), 1), i, 1, XEXP (SUBREG_REG (XEXP (x, 0)), 1), i, 1,
0, in_code == COMPARE); 0, in_code == COMPARE);
...@@ -5425,7 +5432,7 @@ make_field_assignment (x) ...@@ -5425,7 +5432,7 @@ make_field_assignment (x)
|| rtx_equal_p (dest, get_last_value (XEXP (src, 1))) || rtx_equal_p (dest, get_last_value (XEXP (src, 1)))
|| rtx_equal_p (get_last_value (dest), XEXP (src, 1)))) || rtx_equal_p (get_last_value (dest), XEXP (src, 1))))
{ {
assign = make_extraction (VOIDmode, dest, -1, XEXP (XEXP (src, 0), 1), assign = make_extraction (VOIDmode, dest, 0, XEXP (XEXP (src, 0), 1),
1, 1, 1, 0); 1, 1, 1, 0);
return gen_rtx (SET, VOIDmode, assign, const0_rtx); return gen_rtx (SET, VOIDmode, assign, const0_rtx);
} }
...@@ -5440,7 +5447,7 @@ make_field_assignment (x) ...@@ -5440,7 +5447,7 @@ make_field_assignment (x)
|| rtx_equal_p (dest, get_last_value (XEXP (src, 1))) || rtx_equal_p (dest, get_last_value (XEXP (src, 1)))
|| rtx_equal_p (get_last_value (dest), XEXP (src, 1)))) || rtx_equal_p (get_last_value (dest), XEXP (src, 1))))
{ {
assign = make_extraction (VOIDmode, dest, -1, assign = make_extraction (VOIDmode, dest, 0,
XEXP (SUBREG_REG (XEXP (src, 0)), 1), XEXP (SUBREG_REG (XEXP (src, 0)), 1),
1, 1, 1, 0); 1, 1, 1, 0);
return gen_rtx (SET, VOIDmode, assign, const0_rtx); return gen_rtx (SET, VOIDmode, assign, const0_rtx);
...@@ -5454,7 +5461,7 @@ make_field_assignment (x) ...@@ -5454,7 +5461,7 @@ make_field_assignment (x)
|| rtx_equal_p (dest, get_last_value (XEXP (src, 1))) || rtx_equal_p (dest, get_last_value (XEXP (src, 1)))
|| rtx_equal_p (get_last_value (dest), XEXP (src, 1)))) || rtx_equal_p (get_last_value (dest), XEXP (src, 1))))
{ {
assign = make_extraction (VOIDmode, dest, -1, XEXP (XEXP (src, 0), 1), assign = make_extraction (VOIDmode, dest, 0, XEXP (XEXP (src, 0), 1),
1, 1, 1, 0); 1, 1, 1, 0);
return gen_rtx (SET, VOIDmode, assign, const1_rtx); return gen_rtx (SET, VOIDmode, assign, const1_rtx);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment