summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>2005-01-05 23:19:23 +0000
committersteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>2005-01-05 23:19:23 +0000
commit476d094d7713bdd77be9c7863518b69342c7a4b4 (patch)
tree8d81e917b2a1cc0618df0ec47f5dcced22b199dc
parent37e6be124c7dc5274014a63bdd8eeeb6057e6c43 (diff)
downloadgcc-476d094d7713bdd77be9c7863518b69342c7a4b4.tar.gz
* combine.c (expand_compound_operation) <ZERO_EXTRACT>: Add
comment that we fall through after case. (mark_used_regs_combine): Don't expect a SIGN_EXTRACT in a SET_DEST. (distribute_links): Likewise. * cse.c (cse_insn): Likewise. * cselib.c (cselib_invalidate_mem): Likewise. * df.c: Update comments at the top of the file. (read_modify_subreg_p): Update comments here too. (df_def_record_1): Don't expect a SIGN_EXTRACT in a SET_DEST. * flow.c (mark_set_1): Likewise. (mark_used_regs): Likewise. * gcse.c (mems_conflict_for_gcse_p): Likewise. (canon_list_insert): Likewise. (mark_set): Likewise. (try_replace_reg): Likewise. (store_killed_in_insn): Likewise. * loop.c (count_one_set): Likewise. (basic_induction_var): Likewise. * postreload-gcse.c (find_mem_conflicts): Likewise. * postreload.c (reload_combine_note_store): Likewise. (move2add_note_store): Likewise. * reload.c (find_equiv_reg): Likewise. (mark_referenced_resources): Likewise. * rtlanal.c (set_noop_p): Likewise. (note_stores): Likewise. (note_uses): Likewise. * sched-deps.c (sched_analyze_1): Likewise. * sched-rgn.c (check_live_1): Likewise. (update_live_1): Likewise. * config/i860/i860.c: Likewise. * rtl.dec (SIGN_EXTRACT): Document that this cannot appear as an lvalue. (ZERO_EXTRACT): Mention that this one can be an lvalue. * doc/rtl.texi: Update documentation for bit-fields and SET. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@92974 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog39
-rw-r--r--gcc/combine.c5
-rw-r--r--gcc/config/i860/i860.c1
-rw-r--r--gcc/cse.c18
-rw-r--r--gcc/cselib.c5
-rw-r--r--gcc/df.c23
-rw-r--r--gcc/doc/rtl.texi23
-rw-r--r--gcc/flow.c7
-rw-r--r--gcc/gcse.c9
-rw-r--r--gcc/loop.c4
-rw-r--r--gcc/postreload-gcse.c1
-rw-r--r--gcc/postreload.c5
-rw-r--r--gcc/reload.c2
-rw-r--r--gcc/resource.c5
-rw-r--r--gcc/rtl.def6
-rw-r--r--gcc/rtlanal.c8
-rw-r--r--gcc/sched-deps.c5
-rw-r--r--gcc/sched-rgn.c8
18 files changed, 104 insertions, 70 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d7ec1d39ee9..281c9dbadf5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,42 @@
+2005-01-05 Steven Bosscher <stevenb@suse.de>
+
+ * combine.c (expand_compound_operation) <ZERO_EXTRACT>: Add
+ comment that we fall through after case.
+ (mark_used_regs_combine): Don't expect a SIGN_EXTRACT in a SET_DEST.
+ (distribute_links): Likewise.
+ * cse.c (cse_insn): Likewise.
+ * cselib.c (cselib_invalidate_mem): Likewise.
+ * df.c: Update comments at the top of the file.
+ (read_modify_subreg_p): Update comments here too.
+ (df_def_record_1): Don't expect a SIGN_EXTRACT in a SET_DEST.
+ * flow.c (mark_set_1): Likewise.
+ (mark_used_regs): Likewise.
+ * gcse.c (mems_conflict_for_gcse_p): Likewise.
+ (canon_list_insert): Likewise.
+ (mark_set): Likewise.
+ (try_replace_reg): Likewise.
+ (store_killed_in_insn): Likewise.
+ * loop.c (count_one_set): Likewise.
+ (basic_induction_var): Likewise.
+ * postreload-gcse.c (find_mem_conflicts): Likewise.
+ * postreload.c (reload_combine_note_store): Likewise.
+ (move2add_note_store): Likewise.
+ * reload.c (find_equiv_reg): Likewise.
+ (mark_referenced_resources): Likewise.
+ * rtlanal.c (set_noop_p): Likewise.
+ (note_stores): Likewise.
+ (note_uses): Likewise.
+ * sched-deps.c (sched_analyze_1): Likewise.
+ * sched-rgn.c (check_live_1): Likewise.
+ (update_live_1): Likewise.
+ * config/i860/i860.c: Likewise.
+
+ * rtl.dec (SIGN_EXTRACT): Document that this cannot appear as
+ an lvalue.
+ (ZERO_EXTRACT): Mention that this one can be an lvalue.
+
+ * doc/rtl.texi: Update documentation for bit-fields and SET.
+
2005-01-05 Roger Sayle <roger@eyesopen.com>
* ifcvt.c (find_if_case_1): Revert 2005-01-04 change.
diff --git a/gcc/combine.c b/gcc/combine.c
index 90934e11672..a870ff3751c 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -5793,6 +5793,9 @@ expand_compound_operation (rtx x)
case ZERO_EXTRACT:
unsignedp = 1;
+
+ /* ... fall through ... */
+
case SIGN_EXTRACT:
/* If the operand is a CLOBBER, just return it. */
if (GET_CODE (XEXP (x, 0)) == CLOBBER)
@@ -11429,7 +11432,6 @@ mark_used_regs_combine (rtx x)
while (GET_CODE (testreg) == SUBREG
|| GET_CODE (testreg) == ZERO_EXTRACT
- || GET_CODE (testreg) == SIGN_EXTRACT
|| GET_CODE (testreg) == STRICT_LOW_PART)
testreg = XEXP (testreg, 0);
@@ -12302,7 +12304,6 @@ distribute_links (rtx links)
reg = SET_DEST (set);
while (GET_CODE (reg) == SUBREG || GET_CODE (reg) == ZERO_EXTRACT
- || GET_CODE (reg) == SIGN_EXTRACT
|| GET_CODE (reg) == STRICT_LOW_PART)
reg = XEXP (reg, 0);
diff --git a/gcc/config/i860/i860.c b/gcc/config/i860/i860.c
index 0723bac8ca9..ed9cae6d4af 100644
--- a/gcc/config/i860/i860.c
+++ b/gcc/config/i860/i860.c
@@ -145,7 +145,6 @@ reg_clobbered_p (rtx reg, rtx in)
while (GET_CODE (dest) == STRICT_LOW_PART
|| GET_CODE (dest) == SUBREG
- || GET_CODE (dest) == SIGN_EXTRACT
|| GET_CODE (dest) == ZERO_EXTRACT)
dest = XEXP (dest, 0);
diff --git a/gcc/cse.c b/gcc/cse.c
index 766c7252de3..eee27422f8c 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -4865,7 +4865,7 @@ cse_insn (rtx insn, rtx libcall_insn)
else
SET_SRC (sets[i].rtl) = new;
- if (GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == SIGN_EXTRACT)
+ if (GET_CODE (dest) == ZERO_EXTRACT)
{
validate_change (insn, &XEXP (dest, 1),
canon_reg (XEXP (dest, 1), insn), 1);
@@ -4873,9 +4873,9 @@ cse_insn (rtx insn, rtx libcall_insn)
canon_reg (XEXP (dest, 2), insn), 1);
}
- while (GET_CODE (dest) == SUBREG || GET_CODE (dest) == STRICT_LOW_PART
+ while (GET_CODE (dest) == SUBREG
|| GET_CODE (dest) == ZERO_EXTRACT
- || GET_CODE (dest) == SIGN_EXTRACT)
+ || GET_CODE (dest) == STRICT_LOW_PART)
dest = XEXP (dest, 0);
if (MEM_P (dest))
@@ -4972,8 +4972,7 @@ cse_insn (rtx insn, rtx libcall_insn)
causes later instructions to be mis-optimized. */
/* If storing a constant in a bitfield, pre-truncate the constant
so we will be able to record it later. */
- if (GET_CODE (SET_DEST (sets[i].rtl)) == ZERO_EXTRACT
- || GET_CODE (SET_DEST (sets[i].rtl)) == SIGN_EXTRACT)
+ if (GET_CODE (SET_DEST (sets[i].rtl)) == ZERO_EXTRACT)
{
rtx width = XEXP (SET_DEST (sets[i].rtl), 1);
@@ -5629,11 +5628,9 @@ cse_insn (rtx insn, rtx libcall_insn)
/* Now deal with the destination. */
do_not_record = 0;
- /* Look within any SIGN_EXTRACT or ZERO_EXTRACT
- to the MEM or REG within it. */
- while (GET_CODE (dest) == SIGN_EXTRACT
+ /* Look within any ZERO_EXTRACT to the MEM or REG within it. */
+ while (GET_CODE (dest) == SUBREG
|| GET_CODE (dest) == ZERO_EXTRACT
- || GET_CODE (dest) == SUBREG
|| GET_CODE (dest) == STRICT_LOW_PART)
dest = XEXP (dest, 0);
@@ -5661,8 +5658,7 @@ cse_insn (rtx insn, rtx libcall_insn)
because the value in it after the store
may not equal what was stored, due to truncation. */
- if (GET_CODE (SET_DEST (sets[i].rtl)) == ZERO_EXTRACT
- || GET_CODE (SET_DEST (sets[i].rtl)) == SIGN_EXTRACT)
+ if (GET_CODE (SET_DEST (sets[i].rtl)) == ZERO_EXTRACT)
{
rtx width = XEXP (SET_DEST (sets[i].rtl), 1);
diff --git a/gcc/cselib.c b/gcc/cselib.c
index b57125bf9fa..13c3a1f421e 100644
--- a/gcc/cselib.c
+++ b/gcc/cselib.c
@@ -1148,8 +1148,9 @@ cselib_invalidate_mem (rtx mem_rtx)
void
cselib_invalidate_rtx (rtx dest)
{
- while (GET_CODE (dest) == STRICT_LOW_PART || GET_CODE (dest) == SIGN_EXTRACT
- || GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == SUBREG)
+ while (GET_CODE (dest) == SUBREG
+ || GET_CODE (dest) == ZERO_EXTRACT
+ || GET_CODE (dest) == STRICT_LOW_PART)
dest = XEXP (dest, 0);
if (REG_P (dest))
diff --git a/gcc/df.c b/gcc/df.c
index 07da6e5b1cc..81ba0ea0932 100644
--- a/gcc/df.c
+++ b/gcc/df.c
@@ -107,8 +107,8 @@ These are linked into a variety of lists; namely reg-def, reg-use,
the reg-def lists contain all the refs that define a given register
while the insn-use lists contain all the refs used by an insn.
-Note that the reg-def and reg-use chains are generally short (except for the
-hard registers) and thus it is much faster to search these chains
+Note that the reg-def and reg-use chains are generally short (except for
+the hard registers) and thus it is much faster to search these chains
rather than searching the def or use bitmaps.
If the insns are in SSA form then the reg-def and use-def lists
@@ -166,10 +166,13 @@ generates a use of reg 41 then a def of reg 41 (both marked read/write),
even though reg 41 is decremented before it is used for the memory
address in this second example.
-A set to a REG inside a ZERO_EXTRACT, SIGN_EXTRACT, or SUBREG invokes
-a read-modify write operation. We generate both a use and a def
-and again mark them read/write.
-*/
+A set to a REG inside a ZERO_EXTRACT, or a set to a non-paradoxical SUBREG
+for which the number of word_mode units covered by the outer mode is
+smaller than that covered by the inner mode, invokes a read-modify-write.
+operation. We generate both a use and a def and again mark them
+read/write.
+Paradoxical subreg writes don't leave a trace of the old content, so they
+are write-only operations. */
#include "config.h"
#include "system.h"
@@ -858,8 +861,10 @@ df_ref_record (struct df *df, rtx reg, rtx *loc, rtx insn,
}
-/* Return nonzero if writes to paradoxical SUBREGs, or SUBREGs which
- are too narrow, are read-modify-write. */
+/* A set to a non-paradoxical SUBREG for which the number of word_mode units
+ covered by the outer mode is smaller than that covered by the inner mode,
+ is a read-modify-write operation.
+ This function returns true iff the SUBREG X is such a SUBREG. */
bool
read_modify_subreg_p (rtx x)
{
@@ -868,7 +873,6 @@ read_modify_subreg_p (rtx x)
return false;
isize = GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)));
osize = GET_MODE_SIZE (GET_MODE (x));
- /* Paradoxical subreg writes don't leave a trace of the old content. */
return (isize > osize && isize > UNITS_PER_WORD);
}
@@ -909,7 +913,6 @@ df_def_record_1 (struct df *df, rtx x, basic_block bb, rtx insn)
be handy for the reg allocator. */
while (GET_CODE (dst) == STRICT_LOW_PART
|| GET_CODE (dst) == ZERO_EXTRACT
- || GET_CODE (dst) == SIGN_EXTRACT
|| ((df->flags & DF_FOR_REGALLOC) == 0
&& read_modify_subreg_p (dst)))
{
diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi
index e82d0c0b5e6..60685162432 100644
--- a/gcc/doc/rtl.texi
+++ b/gcc/doc/rtl.texi
@@ -2132,9 +2132,6 @@ for insn attributes. @xref{Insn Attributes}.
@cindex bit-fields
Special expression codes exist to represent bit-field instructions.
-These types of expressions are lvalues in RTL; they may appear
-on the left side of an assignment, indicating insertion of a value
-into the specified bit-field.
@table @code
@findex sign_extract
@@ -2158,11 +2155,18 @@ in the @code{insv} or @code{extv} pattern.
The mode @var{m} is the same as the mode that would be used for
@var{loc} if it were a register.
+A @code{sign_extract} can not appear as an lvalue, or part thereof,
+in RTL.
+
@findex zero_extract
@item (zero_extract:@var{m} @var{loc} @var{size} @var{pos})
Like @code{sign_extract} but refers to an unsigned or zero-extended
bit-field. The same sequence of bits are extracted, but they
are filled to an entire word with zeros instead of by sign-extension.
+
+Unlike @code{sign_extract}, this type of expressions can be lvalues
+in RTL; they may appear on the left side of an assignment, indicating
+insertion of a value into the specified bit-field.
@end table
@node Vector Operations
@@ -2365,10 +2369,15 @@ rest of the register receives an undefined value. Likewise, if
the mode of the register, the rest of the register can be changed in
an undefined way.
-If @var{lval} is a @code{strict_low_part} or @code{zero_extract}
-of a @code{subreg}, then the part of the register specified by the
-machine mode of the @code{subreg} is given the value @var{x} and
-the rest of the register is not changed.
+If @var{lval} is a @code{strict_low_part} of a subreg, then the part
+of the register specified by the machine mode of the @code{subreg} is
+given the value @var{x} and the rest of the register is not changed.
+
+If @var{lval} is a @code{zero_extract}, then the referenced part of
+the bit-field (a memory or register reference) specified by the
+@code{zero_extract} is given the value @var{x} and the rest of the
+bit-field is not changed. Note that @code{sign_extract} can not
+appear in @var{lval}.
If @var{lval} is @code{(cc0)}, it has no machine mode, and @var{x} may
be either a @code{compare} expression or a value that may have any mode.
diff --git a/gcc/flow.c b/gcc/flow.c
index cc2c1988767..e3d10a13814 100644
--- a/gcc/flow.c
+++ b/gcc/flow.c
@@ -2554,15 +2554,17 @@ mark_set_1 (struct propagate_block_info *pbi, enum rtx_code code, rtx reg, rtx c
flags);
return;
- case ZERO_EXTRACT:
case SIGN_EXTRACT:
+ /* SIGN_EXTRACT cannot be an lvalue. */
+ gcc_unreachable ();
+
+ case ZERO_EXTRACT:
case STRICT_LOW_PART:
/* ??? Assumes STRICT_LOW_PART not used on multi-word registers. */
do
reg = XEXP (reg, 0);
while (GET_CODE (reg) == SUBREG
|| GET_CODE (reg) == ZERO_EXTRACT
- || GET_CODE (reg) == SIGN_EXTRACT
|| GET_CODE (reg) == STRICT_LOW_PART);
if (MEM_P (reg))
break;
@@ -3844,7 +3846,6 @@ mark_used_regs (struct propagate_block_info *pbi, rtx x, rtx cond, rtx insn)
then this SET is not needed. */
while (GET_CODE (testreg) == STRICT_LOW_PART
|| GET_CODE (testreg) == ZERO_EXTRACT
- || GET_CODE (testreg) == SIGN_EXTRACT
|| GET_CODE (testreg) == SUBREG)
{
#ifdef CANNOT_CHANGE_MODE_CLASS
diff --git a/gcc/gcse.c b/gcc/gcse.c
index 47d3fae5730..67f8053e9c8 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -1366,7 +1366,6 @@ mems_conflict_for_gcse_p (rtx dest, rtx setter ATTRIBUTE_UNUSED,
{
while (GET_CODE (dest) == SUBREG
|| GET_CODE (dest) == ZERO_EXTRACT
- || GET_CODE (dest) == SIGN_EXTRACT
|| GET_CODE (dest) == STRICT_LOW_PART)
dest = XEXP (dest, 0);
@@ -2002,7 +2001,6 @@ canon_list_insert (rtx dest ATTRIBUTE_UNUSED, rtx unused1 ATTRIBUTE_UNUSED,
while (GET_CODE (dest) == SUBREG
|| GET_CODE (dest) == ZERO_EXTRACT
- || GET_CODE (dest) == SIGN_EXTRACT
|| GET_CODE (dest) == STRICT_LOW_PART)
dest = XEXP (dest, 0);
@@ -2390,7 +2388,6 @@ mark_set (rtx pat, rtx insn)
while (GET_CODE (dest) == SUBREG
|| GET_CODE (dest) == ZERO_EXTRACT
- || GET_CODE (dest) == SIGN_EXTRACT
|| GET_CODE (dest) == STRICT_LOW_PART)
dest = XEXP (dest, 0);
@@ -2739,8 +2736,7 @@ try_replace_reg (rtx from, rtx to, rtx insn)
have a note, and have no special SET, add a REG_EQUAL note to not
lose information. */
if (!success && note == 0 && set != 0
- && GET_CODE (XEXP (set, 0)) != ZERO_EXTRACT
- && GET_CODE (XEXP (set, 0)) != SIGN_EXTRACT)
+ && GET_CODE (SET_DEST (set)) != ZERO_EXTRACT)
note = set_unique_reg_note (insn, REG_EQUAL, copy_rtx (src));
}
@@ -5960,8 +5956,7 @@ store_killed_in_insn (rtx x, rtx x_regs, rtx insn, int after)
rtx pat = PATTERN (insn);
rtx dest = SET_DEST (pat);
- if (GET_CODE (dest) == SIGN_EXTRACT
- || GET_CODE (dest) == ZERO_EXTRACT)
+ if (GET_CODE (dest) == ZERO_EXTRACT)
dest = XEXP (dest, 0);
/* Check for memory stores to aliased objects. */
diff --git a/gcc/loop.c b/gcc/loop.c
index 7a446eadc12..3fa0f48a778 100644
--- a/gcc/loop.c
+++ b/gcc/loop.c
@@ -3849,7 +3849,6 @@ count_one_set (struct loop_regs *regs, rtx insn, rtx x, rtx *last_set)
rtx dest = SET_DEST (x);
while (GET_CODE (dest) == SUBREG
|| GET_CODE (dest) == ZERO_EXTRACT
- || GET_CODE (dest) == SIGN_EXTRACT
|| GET_CODE (dest) == STRICT_LOW_PART)
dest = XEXP (dest, 0);
if (REG_P (dest))
@@ -7595,9 +7594,8 @@ basic_induction_var (const struct loop *loop, rtx x, enum machine_mode mode,
dest_reg, insn,
inc_val, mult_val, location);
- while (GET_CODE (dest) == SIGN_EXTRACT
+ while (GET_CODE (dest) == SUBREG
|| GET_CODE (dest) == ZERO_EXTRACT
- || GET_CODE (dest) == SUBREG
|| GET_CODE (dest) == STRICT_LOW_PART)
dest = XEXP (dest, 0);
if (dest == x)
diff --git a/gcc/postreload-gcse.c b/gcc/postreload-gcse.c
index 24c233caea3..70e60452fd0 100644
--- a/gcc/postreload-gcse.c
+++ b/gcc/postreload-gcse.c
@@ -570,7 +570,6 @@ find_mem_conflicts (rtx dest, rtx setter ATTRIBUTE_UNUSED,
while (GET_CODE (dest) == SUBREG
|| GET_CODE (dest) == ZERO_EXTRACT
- || GET_CODE (dest) == SIGN_EXTRACT
|| GET_CODE (dest) == STRICT_LOW_PART)
dest = XEXP (dest, 0);
diff --git a/gcc/postreload.c b/gcc/postreload.c
index 14dc7126883..06714b90ab8 100644
--- a/gcc/postreload.c
+++ b/gcc/postreload.c
@@ -1005,11 +1005,9 @@ reload_combine_note_store (rtx dst, rtx set, void *data ATTRIBUTE_UNUSED)
/* note_stores might have stripped a STRICT_LOW_PART, so we have to be
careful with registers / register parts that are not full words.
-
- Similarly for ZERO_EXTRACT and SIGN_EXTRACT. */
+ Similarly for ZERO_EXTRACT. */
if (GET_CODE (set) != SET
|| GET_CODE (SET_DEST (set)) == ZERO_EXTRACT
- || GET_CODE (SET_DEST (set)) == SIGN_EXTRACT
|| GET_CODE (SET_DEST (set)) == STRICT_LOW_PART)
{
for (i = hard_regno_nregs[regno][mode] - 1 + regno; i >= regno; i--)
@@ -1462,7 +1460,6 @@ move2add_note_store (rtx dst, rtx set, void *data ATTRIBUTE_UNUSED)
if (SCALAR_INT_MODE_P (mode)
&& hard_regno_nregs[regno][mode] == 1 && GET_CODE (set) == SET
&& GET_CODE (SET_DEST (set)) != ZERO_EXTRACT
- && GET_CODE (SET_DEST (set)) != SIGN_EXTRACT
&& GET_CODE (SET_DEST (set)) != STRICT_LOW_PART)
{
rtx src = SET_SRC (set);
diff --git a/gcc/reload.c b/gcc/reload.c
index 08a22deffab..2bb2fb96a95 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -6734,7 +6734,6 @@ find_equiv_reg (rtx goal, rtx insn, enum reg_class class, int other,
rtx dest = SET_DEST (pat);
while (GET_CODE (dest) == SUBREG
|| GET_CODE (dest) == ZERO_EXTRACT
- || GET_CODE (dest) == SIGN_EXTRACT
|| GET_CODE (dest) == STRICT_LOW_PART)
dest = XEXP (dest, 0);
if (REG_P (dest))
@@ -6778,7 +6777,6 @@ find_equiv_reg (rtx goal, rtx insn, enum reg_class class, int other,
rtx dest = SET_DEST (v1);
while (GET_CODE (dest) == SUBREG
|| GET_CODE (dest) == ZERO_EXTRACT
- || GET_CODE (dest) == SIGN_EXTRACT
|| GET_CODE (dest) == STRICT_LOW_PART)
dest = XEXP (dest, 0);
if (REG_P (dest))
diff --git a/gcc/resource.c b/gcc/resource.c
index 9881293b419..aa419ceac9c 100644
--- a/gcc/resource.c
+++ b/gcc/resource.c
@@ -299,13 +299,12 @@ mark_referenced_resources (rtx x, struct resources *res,
case SET:
/* Usually, the first operand of SET is set, not referenced. But
registers used to access memory are referenced. SET_DEST is
- also referenced if it is a ZERO_EXTRACT or SIGN_EXTRACT. */
+ also referenced if it is a ZERO_EXTRACT. */
mark_referenced_resources (SET_SRC (x), res, 0);
x = SET_DEST (x);
- if (GET_CODE (x) == SIGN_EXTRACT
- || GET_CODE (x) == ZERO_EXTRACT
+ if (GET_CODE (x) == ZERO_EXTRACT
|| GET_CODE (x) == STRICT_LOW_PART)
mark_referenced_resources (x, res, 0);
else if (GET_CODE (x) == SUBREG)
diff --git a/gcc/rtl.def b/gcc/rtl.def
index c20f61bdd4b..7bee09b1c6d 100644
--- a/gcc/rtl.def
+++ b/gcc/rtl.def
@@ -587,10 +587,12 @@ DEF_RTL_EXPR(PARITY, "parity", "e", RTX_UNARY)
If BITS_BIG_ENDIAN is defined, the first bit is the msb and
operand 2 counts from the msb of the memory unit.
Otherwise, the first bit is the lsb and operand 2 counts from
- the lsb of the memory unit. */
+ the lsb of the memory unit.
+ This kind of expression can not appear as an lvalue in RTL. */
DEF_RTL_EXPR(SIGN_EXTRACT, "sign_extract", "eee", RTX_BITFIELD_OPS)
-/* Similar for unsigned bit-field. */
+/* Similar for unsigned bit-field.
+ But note! This kind of expression _can_ appear as an lvalue. */
DEF_RTL_EXPR(ZERO_EXTRACT, "zero_extract", "eee", RTX_BITFIELD_OPS)
/* For RISC machines. These save memory when splitting insns. */
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index 3ffd0632638..98a284324e4 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -1075,8 +1075,7 @@ set_noop_p (rtx set)
if (MEM_P (dst) && MEM_P (src))
return rtx_equal_p (dst, src) && !side_effects_p (dst);
- if (GET_CODE (dst) == SIGN_EXTRACT
- || GET_CODE (dst) == ZERO_EXTRACT)
+ if (GET_CODE (dst) == ZERO_EXTRACT)
return rtx_equal_p (XEXP (dst, 0), src)
&& ! BYTES_BIG_ENDIAN && XEXP (dst, 2) == const0_rtx
&& !side_effects_p (src);
@@ -1405,7 +1404,6 @@ note_stores (rtx x, void (*fun) (rtx, rtx, void *), void *data)
&& (!REG_P (SUBREG_REG (dest))
|| REGNO (SUBREG_REG (dest)) >= FIRST_PSEUDO_REGISTER))
|| GET_CODE (dest) == ZERO_EXTRACT
- || GET_CODE (dest) == SIGN_EXTRACT
|| GET_CODE (dest) == STRICT_LOW_PART)
dest = XEXP (dest, 0);
@@ -1514,8 +1512,8 @@ note_uses (rtx *pbody, void (*fun) (rtx *, void *), void *data)
This will be true if X is (cc0) or if X is a register and
X dies in INSN or because INSN entirely sets X.
- "Entirely set" means set directly and not through a SUBREG,
- ZERO_EXTRACT or SIGN_EXTRACT, so no trace of the old contents remains.
+ "Entirely set" means set directly and not through a SUBREG, or
+ ZERO_EXTRACT, so no trace of the old contents remains.
Likewise, REG_INC does not count.
REG may be a hard or pseudo reg. Renumbering is not taken into account,
diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c
index 539d0273410..52f6e5b1746 100644
--- a/gcc/sched-deps.c
+++ b/gcc/sched-deps.c
@@ -507,11 +507,10 @@ sched_analyze_1 (struct deps *deps, rtx x, rtx insn)
}
while (GET_CODE (dest) == STRICT_LOW_PART || GET_CODE (dest) == SUBREG
- || GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == SIGN_EXTRACT)
+ || GET_CODE (dest) == ZERO_EXTRACT)
{
if (GET_CODE (dest) == STRICT_LOW_PART
|| GET_CODE (dest) == ZERO_EXTRACT
- || GET_CODE (dest) == SIGN_EXTRACT
|| read_modify_subreg_p (dest))
{
/* These both read and modify the result. We must handle
@@ -522,7 +521,7 @@ sched_analyze_1 (struct deps *deps, rtx x, rtx insn)
sched_analyze_2 (deps, XEXP (dest, 0), insn);
}
- if (GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == SIGN_EXTRACT)
+ if (GET_CODE (dest) == ZERO_EXTRACT)
{
/* The second and third arguments are values read by this insn. */
sched_analyze_2 (deps, XEXP (dest, 1), insn);
diff --git a/gcc/sched-rgn.c b/gcc/sched-rgn.c
index 162576a0c92..2aba7f3b1c1 100644
--- a/gcc/sched-rgn.c
+++ b/gcc/sched-rgn.c
@@ -1146,8 +1146,8 @@ check_live_1 (int src, rtx x)
if (reg == 0)
return 1;
- while (GET_CODE (reg) == SUBREG || GET_CODE (reg) == ZERO_EXTRACT
- || GET_CODE (reg) == SIGN_EXTRACT
+ while (GET_CODE (reg) == SUBREG
+ || GET_CODE (reg) == ZERO_EXTRACT
|| GET_CODE (reg) == STRICT_LOW_PART)
reg = XEXP (reg, 0);
@@ -1223,8 +1223,8 @@ update_live_1 (int src, rtx x)
if (reg == 0)
return;
- while (GET_CODE (reg) == SUBREG || GET_CODE (reg) == ZERO_EXTRACT
- || GET_CODE (reg) == SIGN_EXTRACT
+ while (GET_CODE (reg) == SUBREG
+ || GET_CODE (reg) == ZERO_EXTRACT
|| GET_CODE (reg) == STRICT_LOW_PART)
reg = XEXP (reg, 0);