This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
expr.c (store_expr): When target is a promoted subreg, return a...
- To: egcs-patches at egcs dot cygnus dot com
- Subject: expr.c (store_expr): When target is a promoted subreg, return a...
- From: Jim Wilson <wilson at cygnus dot com>
- Date: Tue, 22 Jun 1999 14:40:07 -0700
I have installed this patch.
This fixes a problem that can occur if a port defines PROMOTE_MODES, but
does not define PROMOTE_FUNCTION_ARGS or PROMOTE_FUNCTION_RETURN. In this
case, we can hit the mode mismatch abort in emit_move_insn if an assignment
expression is used as an argument or return value. E.g.
sub (i = 10);
What happens is that store_expr is passed an SImode target, but returns
a DImode result, confusing the caller. I believe that store_expr should always
return a result which matches the target passed into it, so I fixed this by
adding a subreg.
1999-06-22 Jim Wilson <wilson@cygnus.com>
* expr.c (store_expr): When target is a promoted subreg, return a
promoted subreg as a result.
Index: expr.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/expr.c,v
retrieving revision 1.144
diff -p -r1.144 expr.c
*** expr.c 1999/05/17 07:21:14 1.144
--- expr.c 1999/06/22 21:29:24
*************** store_expr (exp, target, want_value)
*** 3652,3657 ****
--- 3652,3671 ----
convert_move (SUBREG_REG (target), temp,
SUBREG_PROMOTED_UNSIGNED_P (target));
+
+ /* If we promoted a constant, change the mode back down to match
+ target. Otherwise, the caller might get confused by a result whose
+ mode is larger than expected. */
+
+ if (want_value && GET_MODE (temp) != GET_MODE (target)
+ && GET_MODE (temp) != VOIDmode)
+ {
+ temp = gen_rtx_SUBREG (GET_MODE (target), temp, 0);
+ SUBREG_PROMOTED_VAR_P (temp) = 1;
+ SUBREG_PROMOTED_UNSIGNED_P (temp)
+ = SUBREG_PROMOTED_UNSIGNED_P (target);
+ }
+
return want_value ? temp : NULL_RTX;
}
else