This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] SUBREG_BYTE fixes
- To: "David S. Miller" <davem at redhat dot com>, Richard Henderson <rth at cygnus dot com>
- Subject: [PATCH] SUBREG_BYTE fixes
- From: Jakub Jelinek <jakub at redhat dot com>
- Date: Thu, 9 Dec 1999 18:22:05 +0100
- Cc: gcc-patches at gcc dot gnu dot org
Hi!
This fixes the genrecog crash when built with sparc64-* non
PROMOTE_FOR_CALL_ONLY compiler. Basically, what used to be
gen_rtx_SUBREG (mode, reg, 0) with the meaning low part of a register
shall be rewritten in generic code as gen_rtx_SUBREG (mode, reg, -1)
and gen_rtx_SUBREG handles this special argument. Only if we're sure it
will create a paradoxical subreg it can be left as *, 0).
There are still some places I need to study regarding to this and
tests for SUBREG_BYTE(x) == 0 which are meant as tests if it is a low part
of register.
1999-12-09 Jakub Jelinek <jakub@redhat.com>
* emit-rtl.c (gen_rtx_SUBREG): Allow a shorthand gen_rtx_SUBREG(.. -1)
for low part SUBREG. If the SUBREG to be created, offset will be
always 0, otherwise it depends on machine endianess.
* calls.c (precompute_arguments): Use it.
* expr.c (store_expr, expand_expr): Likewise.
* regmove.c (optimize_reg_copy_3): Likewise.
* reload1.c (emit_reload_insns): Likewise.
* stmt.c (expand_anon_union_decl): Likewise.
--- gcc/emit-rtl.c.jj Wed Dec 8 10:54:45 1999
+++ gcc/emit-rtl.c Thu Dec 9 17:08:16 1999
@@ -270,12 +270,34 @@ gen_rtx_MEM (mode, addr)
return rt;
}
+/* Passing OFFSET -1 will set offset so that the SUBREG will refer
+ to the low part of the register, unless it is a paradoxical SUBREG,
+ in which case it will use 0. */
rtx
gen_rtx_SUBREG (mode, reg, offset)
enum machine_mode mode;
rtx reg;
int offset;
{
+ if (offset == -1)
+ {
+ enum machine_mode inmode;
+
+ inmode = GET_MODE (reg);
+ if (inmode == VOIDmode)
+ inmode = mode;
+ offset = 0;
+ if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (inmode)
+ && (WORDS_BIG_ENDIAN || BYTES_BIG_ENDIAN))
+ {
+ offset = GET_MODE_SIZE (inmode) - GET_MODE_SIZE (mode);
+ if (! BYTES_BIG_ENDIAN)
+ offset = (offset / UNITS_PER_WORD) * UNITS_PER_WORD;
+ else if (! WORDS_BIG_ENDIAN)
+ offset %= UNITS_PER_WORD;
+ }
+ }
+
/* This is the most common failure type.
Catch it early so we can see who does it. */
if ((offset % GET_MODE_SIZE (mode)) != 0)
--- gcc/calls.c.jj Wed Dec 8 10:54:50 1999
+++ gcc/calls.c Thu Dec 9 17:08:57 1999
@@ -1295,7 +1295,7 @@ precompute_arguments (is_const, must_pre
{
args[i].initial_value
= gen_rtx_SUBREG (TYPE_MODE (TREE_TYPE (args[i].tree_value)),
- args[i].value, 0);
+ args[i].value, -1);
SUBREG_PROMOTED_VAR_P (args[i].initial_value) = 1;
SUBREG_PROMOTED_UNSIGNED_P (args[i].initial_value)
= args[i].unsignedp;
--- gcc/expr.c.jj Wed Dec 1 19:21:35 1999
+++ gcc/expr.c Thu Dec 9 17:49:15 1999
@@ -3731,7 +3731,7 @@ store_expr (exp, target, want_value)
if (want_value && GET_MODE (temp) != GET_MODE (target)
&& GET_MODE (temp) != VOIDmode)
{
- temp = gen_rtx_SUBREG (GET_MODE (target), temp, 0);
+ temp = gen_rtx_SUBREG (GET_MODE (target), temp, -1);
SUBREG_PROMOTED_VAR_P (temp) = 1;
SUBREG_PROMOTED_UNSIGNED_P (temp)
= SUBREG_PROMOTED_UNSIGNED_P (target);
@@ -5961,7 +5961,7 @@ expand_expr (exp, target, tmode, modifie
!= promote_mode (type, DECL_MODE (exp), &unsignedp, 0))
abort ();
- temp = gen_rtx_SUBREG (mode, DECL_RTL (exp), 0);
+ temp = gen_rtx_SUBREG (mode, DECL_RTL (exp), -1);
SUBREG_PROMOTED_VAR_P (temp) = 1;
SUBREG_PROMOTED_UNSIGNED_P (temp) = unsignedp;
return temp;
@@ -6079,7 +6079,7 @@ expand_expr (exp, target, tmode, modifie
if (GET_CODE (temp) == REG && GET_MODE (temp) != mode)
{
- temp = gen_rtx_SUBREG (mode, SAVE_EXPR_RTL (exp), 0);
+ temp = gen_rtx_SUBREG (mode, SAVE_EXPR_RTL (exp), -1);
SUBREG_PROMOTED_VAR_P (temp) = 1;
SUBREG_PROMOTED_UNSIGNED_P (temp) = unsignedp;
}
@@ -6102,7 +6102,7 @@ expand_expr (exp, target, tmode, modifie
{
/* Compute the signedness and make the proper SUBREG. */
promote_mode (type, mode, &unsignedp, 0);
- temp = gen_rtx_SUBREG (mode, SAVE_EXPR_RTL (exp), 0);
+ temp = gen_rtx_SUBREG (mode, SAVE_EXPR_RTL (exp), -1);
SUBREG_PROMOTED_VAR_P (temp) = 1;
SUBREG_PROMOTED_UNSIGNED_P (temp) = unsignedp;
return temp;
--- gcc/regmove.c.jj Wed Dec 8 10:54:46 1999
+++ gcc/regmove.c Thu Dec 9 17:56:47 1999
@@ -715,7 +715,7 @@ optimize_reg_copy_3 (insn, dest, src)
/* Now walk forward making additional replacements. We want to be able
to undo all the changes if a later substitution fails. */
- subreg = gen_rtx_SUBREG (old_mode, src_reg, 0);
+ subreg = gen_rtx_SUBREG (old_mode, src_reg, -1);
while (p = NEXT_INSN (p), p != insn)
{
if (GET_RTX_CLASS (GET_CODE (p)) != 'i')
--- gcc/reload1.c.jj Wed Dec 8 10:54:49 1999
+++ gcc/reload1.c Thu Dec 9 17:58:02 1999
@@ -6736,7 +6736,7 @@ emit_reload_insns (chain)
oldequiv = SUBREG_REG (oldequiv);
if (GET_MODE (oldequiv) != VOIDmode
&& mode != GET_MODE (oldequiv))
- oldequiv = gen_rtx_SUBREG (mode, oldequiv, 0);
+ oldequiv = gen_rtx_SUBREG (mode, oldequiv, -1);
/* Switch to the right place to emit the reload insns. */
switch (rld[j].when_needed)
--- gcc/stmt.c.jj Tue Dec 7 08:27:41 1999
+++ gcc/stmt.c Thu Dec 9 17:59:55 1999
@@ -4195,7 +4195,7 @@ expand_anon_union_decl (decl, cleanup, d
if (mode == GET_MODE (x))
DECL_RTL (decl_elt) = x;
else
- DECL_RTL (decl_elt) = gen_rtx_SUBREG (mode, x, 0);
+ DECL_RTL (decl_elt) = gen_rtx_SUBREG (mode, x, -1);
}
else
abort ();
Cheers,
Jakub
___________________________________________________________________
Jakub Jelinek | jakub@redhat.com | http://sunsite.mff.cuni.cz/~jj
Linux version 2.3.18 on a sparc64 machine (1343.49 BogoMips)
___________________________________________________________________