summaryrefslogtreecommitdiff
path: root/gcc/optabs.c
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1992-08-29 22:39:51 -0400
committerRichard Kenner <kenner@gcc.gnu.org>1992-08-29 22:39:51 -0400
commit4a96984737a74d730d1775f9e2e84046dec9fab7 (patch)
tree0ce154b2429acd6ec8711b2556c17ceb159130ae /gcc/optabs.c
parent803090c4274d6ab45674cd94dda7b899aea10b33 (diff)
downloadgcc-4a96984737a74d730d1775f9e2e84046dec9fab7.tar.gz
(expand_{binop,unop}): Don't make invalid paradoxical SUBREGs.
From-SVN: r1995
Diffstat (limited to 'gcc/optabs.c')
-rw-r--r--gcc/optabs.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 7b883cbccb6..7af1c416671 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -454,14 +454,17 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
/* For certain integer operations, we need not actually extend
the narrow operands, as long as we will truncate
- the results to the same narrowness. */
+ the results to the same narrowness. Don't do this when
+ WIDER_MODE is wider than a word since a paradoxical SUBREG
+ isn't valid for such modes. */
if ((binoptab == ior_optab || binoptab == and_optab
|| binoptab == xor_optab
|| binoptab == add_optab || binoptab == sub_optab
|| binoptab == smul_optab
|| binoptab == ashl_optab || binoptab == lshl_optab)
- && class == MODE_INT)
+ && class == MODE_INT
+ && GET_MODE_SIZE (wider_mode) <= UNITS_PER_WORD)
no_extend = 1;
/* If an operand is a constant integer, we might as well
@@ -879,14 +882,17 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
/* For certain integer operations, we need not actually extend
the narrow operands, as long as we will truncate
- the results to the same narrowness. */
+ the results to the same narrowness. Don't do this when
+ WIDER_MODE is wider than a word since a paradoxical SUBREG
+ isn't valid for such modes. */
if ((binoptab == ior_optab || binoptab == and_optab
|| binoptab == xor_optab
|| binoptab == add_optab || binoptab == sub_optab
|| binoptab == smul_optab
|| binoptab == ashl_optab || binoptab == lshl_optab)
- && class == MODE_INT)
+ && class == MODE_INT
+ && GET_MODE_SIZE (wider_mode) <= UNITS_PER_WORD)
no_extend = 1;
/* If an operand is a constant integer, we might as well
@@ -1207,6 +1213,7 @@ expand_unop (mode, unoptab, op0, target, unsignedp)
results to the same narrowness. */
if ((unoptab == neg_optab || unoptab == one_cmpl_optab)
+ && GET_MODE_SIZE (wider_mode) <= UNITS_PER_WORD
&& class == MODE_INT)
xop0 = gen_rtx (SUBREG, wider_mode, force_reg (mode, xop0), 0);
else
@@ -1304,6 +1311,7 @@ expand_unop (mode, unoptab, op0, target, unsignedp)
results to the same narrowness. */
if ((unoptab == neg_optab || unoptab == one_cmpl_optab)
+ && GET_MODE_SIZE (wider_mode) <= UNITS_PER_WORD
&& class == MODE_INT)
xop0 = gen_rtx (SUBREG, wider_mode, force_reg (mode, xop0), 0);
else