This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: CLASS_CANNOT_CHANGE_MODE* redesign
> > + for (i=0; i < NUM_MACHINE_MODES; ++i)
> > + {
> > + INIT_REG_SET (&subregs_of_mode[i]);
> > + CLEAR_REG_SET (&subregs_of_mode[i]);
>
> Memory leak here. Easiest is to initialize in init_reg_sets_1
> then just clear the sets here.
As per our conversation, this is allocated once per function, so
no memory leak. However, I did remove the CLEAR_REG_SET, since
INIT_REG_SET will do that.
> Unused variable?
Fixed all.
> Not sufficient. You need to test for any class that
> intersects with FLOAT_REGS. See reg_classes_intersect_p.
> Note the code you removed that computed class_can_change_mode.
Done.
On this set of changes, only bootstrapped alpha and regtested.
How does this look?
2002-10-22 Aldy Hernandez <aldyh@redhat.com>
* config/rs6000/rs6000.h (CLASS_CANNOT_CHANGE_MODE_P): Change to
use CLASS.
(CLASS_CANNOT_CHANGE_MODE): Remove.
* config/alpha/alpha.h: Same.
* config/ia64/ia64.h: Same.
* config/mips/mips.h: Same.
* config/s390/s390.h: Same.
* config/sh/sh.h: Same.
* config/pa/pa64-regs.h: Same.
* doc/tm.texi (Register Classes): Remove
CLASS_CANNOT_CHANGE_MODE. Add documentation for CLASS argument of
CLASS_CANNOT_CHANGE_MODE_P.
* reload.c (push_reload): Pass class to
CLASS_CANNOT_CHANGE_MODE_P.
(push_reload): Same.
* simplify-rtx.c (simplify_subreg): Same.
* reload1.c (choose_reload_regs): Pass class to
CLASS_CANNOT_CHANGE_MODE_P. Do not use CLASS_CANNOT_CHANGE_MODE.
* regrename.c (mode_change_ok): Change to use new
CLASS_CANNOT_CHANGE_MODE_P infrastructure.
* regclass.c (cannot_change_mode_set_regs): New.
Declare subregs_of_mode.
(regclass): Use subregs_of_mode.
Remove references to reg_changes_mode.
(init_reg_sets_1): Remove class_can_change_mode and
reg_changes_mode code.
(invalid_mode_change_p): New.
(dump_regclass): Use invalid_mode_change_p instead of
class_can_change_mode.
(regclass): Same.
(record_operand_costs): Do not set reg_changes_mode.
* local-alloc.c (struct qty): Remove changes_mode field.
(alloc_qty): Remove changes_mode initialization.
(update_qty_class): Remove set of changes_mode.
(find_free_reg): Use subregs_of_mode.
* recog.c (register_operand): Pass class to
CLASS_CANNOT_CHANGE_MODE_P.
* global.c (find_reg): Use subregs_of_mode info.
* rtl.h (cannot_change_mode_set_regs): New prototype.
(invalid_mode_change_p): Same.
* flow.c (mark_used_regs): Calculate subregs_of_mode. Remove
REG_CHANGES_MODE.
(life_analysis): Clear subregs_of_mode.
* combine.c (subst): Pass class to CLASS_CANNOT_CHANGE_MODE_P.
Remove use of CLASS_CANNOT_CHANGE_MODE.
(simplify_set): Same.
(gen_lowpart_for_combine): Calculate subregs_of_mode. Remove
REG_CHANGES_MODE.
* regs.h: Add extern for subregs_of_mode;
Include hard-reg-set and basic-block.
(REG_CHANGES_MODE): Delete.
Index: combine.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/combine.c,v
retrieving revision 1.321
diff -c -p -r1.321 combine.c
*** combine.c 15 Oct 2002 05:01:07 -0000 1.321
--- combine.c 22 Oct 2002 22:00:10 -0000
*************** subst (x, from, to, in_dest, unique_copy
*** 3519,3533 ****
)
return gen_rtx_CLOBBER (VOIDmode, const0_rtx);
! #ifdef CLASS_CANNOT_CHANGE_MODE
if (code == SUBREG
&& GET_CODE (to) == REG
&& REGNO (to) < FIRST_PSEUDO_REGISTER
! && (TEST_HARD_REG_BIT
! (reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE],
! REGNO (to)))
! && CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (to),
! GET_MODE (x)))
return gen_rtx_CLOBBER (VOIDmode, const0_rtx);
#endif
--- 3519,3532 ----
)
return gen_rtx_CLOBBER (VOIDmode, const0_rtx);
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
if (code == SUBREG
&& GET_CODE (to) == REG
&& REGNO (to) < FIRST_PSEUDO_REGISTER
! && CLASS_CANNOT_CHANGE_MODE_P
! (REGNO_REG_CLASS (REGNO (to)),
! GET_MODE (to),
! GET_MODE (x)))
return gen_rtx_CLOBBER (VOIDmode, const0_rtx);
#endif
*************** simplify_set (x)
*** 5198,5209 ****
&& (GET_MODE_SIZE (GET_MODE (src))
< GET_MODE_SIZE (GET_MODE (SUBREG_REG (src))))
#endif
! #ifdef CLASS_CANNOT_CHANGE_MODE
&& ! (GET_CODE (dest) == REG && REGNO (dest) < FIRST_PSEUDO_REGISTER
! && (TEST_HARD_REG_BIT
! (reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE],
! REGNO (dest)))
! && CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (src),
GET_MODE (SUBREG_REG (src))))
#endif
&& (GET_CODE (dest) == REG
--- 5197,5206 ----
&& (GET_MODE_SIZE (GET_MODE (src))
< GET_MODE_SIZE (GET_MODE (SUBREG_REG (src))))
#endif
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
&& ! (GET_CODE (dest) == REG && REGNO (dest) < FIRST_PSEUDO_REGISTER
! && CLASS_CANNOT_CHANGE_MODE_P (REGNO_REG_CLASS (REGNO (dest)),
! GET_MODE (src),
GET_MODE (SUBREG_REG (src))))
#endif
&& (GET_CODE (dest) == REG
*************** gen_lowpart_for_combine (mode, x)
*** 9937,9950 ****
}
result = gen_lowpart_common (mode, x);
! #ifdef CLASS_CANNOT_CHANGE_MODE
if (result != 0
&& GET_CODE (result) == SUBREG
&& GET_CODE (SUBREG_REG (result)) == REG
! && REGNO (SUBREG_REG (result)) >= FIRST_PSEUDO_REGISTER
! && CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (result),
! GET_MODE (SUBREG_REG (result))))
! REG_CHANGES_MODE (REGNO (SUBREG_REG (result))) = 1;
#endif
if (result)
--- 9934,9946 ----
}
result = gen_lowpart_common (mode, x);
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
if (result != 0
&& GET_CODE (result) == SUBREG
&& GET_CODE (SUBREG_REG (result)) == REG
! && REGNO (SUBREG_REG (result)) >= FIRST_PSEUDO_REGISTER)
! SET_REGNO_REG_SET (&subregs_of_mode[GET_MODE (result)],
! REGNO (SUBREG_REG (result)));
#endif
if (result)
Index: flow.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/flow.c,v
retrieving revision 1.539
diff -c -p -r1.539 flow.c
*** flow.c 1 Oct 2002 12:19:36 -0000 1.539
--- flow.c 22 Oct 2002 22:00:10 -0000
*************** life_analysis (f, file, flags)
*** 431,436 ****
--- 431,446 ----
SET_HARD_REG_BIT (elim_reg_set, FRAME_POINTER_REGNUM);
#endif
+
+ #ifdef CLASS_CANNOT_CHANGE_MODE_P
+ if (flags & PROP_REG_INFO)
+ for (i=0; i < NUM_MACHINE_MODES; ++i)
+ {
+ INIT_REG_SET (&subregs_of_mode[i]);
+ CLEAR_REG_SET (&subregs_of_mode[i]);
+ }
+ #endif
+
if (! optimize)
flags &= ~(PROP_LOG_LINKS | PROP_AUTOINC | PROP_ALLOW_CFG_CHANGES);
*************** mark_used_regs (pbi, x, cond, insn)
*** 3813,3824 ****
break;
case SUBREG:
! #ifdef CLASS_CANNOT_CHANGE_MODE
if (GET_CODE (SUBREG_REG (x)) == REG
! && REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER
! && CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (x),
! GET_MODE (SUBREG_REG (x))))
! REG_CHANGES_MODE (REGNO (SUBREG_REG (x))) = 1;
#endif
/* While we're here, optimize this case. */
--- 3823,3833 ----
break;
case SUBREG:
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
if (GET_CODE (SUBREG_REG (x)) == REG
! && REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER)
! SET_REGNO_REG_SET (&subregs_of_mode[GET_MODE (x)],
! REGNO (SUBREG_REG (x)));
#endif
/* While we're here, optimize this case. */
*************** mark_used_regs (pbi, x, cond, insn)
*** 3862,3874 ****
|| GET_CODE (testreg) == SIGN_EXTRACT
|| GET_CODE (testreg) == SUBREG)
{
! #ifdef CLASS_CANNOT_CHANGE_MODE
if (GET_CODE (testreg) == SUBREG
&& GET_CODE (SUBREG_REG (testreg)) == REG
! && REGNO (SUBREG_REG (testreg)) >= FIRST_PSEUDO_REGISTER
! && CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (SUBREG_REG (testreg)),
! GET_MODE (testreg)))
! REG_CHANGES_MODE (REGNO (SUBREG_REG (testreg))) = 1;
#endif
/* Modifying a single register in an alternate mode
--- 3871,3882 ----
|| GET_CODE (testreg) == SIGN_EXTRACT
|| GET_CODE (testreg) == SUBREG)
{
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
if (GET_CODE (testreg) == SUBREG
&& GET_CODE (SUBREG_REG (testreg)) == REG
! && REGNO (SUBREG_REG (testreg)) >= FIRST_PSEUDO_REGISTER)
! SET_REGNO_REG_SET (&subregs_of_mode[GET_MODE (testreg)],
! REGNO (SUBREG_REG (testreg)));
#endif
/* Modifying a single register in an alternate mode
Index: global.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/global.c,v
retrieving revision 1.85
diff -c -p -r1.85 global.c
*** global.c 22 Sep 2002 14:09:33 -0000 1.85
--- global.c 22 Oct 2002 22:00:10 -0000
*************** find_reg (num, losers, alt_regs_p, accep
*** 983,988 ****
--- 983,989 ----
? reg_alternate_class (allocno[num].reg)
: reg_preferred_class (allocno[num].reg));
enum machine_mode mode = PSEUDO_REGNO_MODE (allocno[num].reg);
+ enum machine_mode to_mode;
if (accept_call_clobbered)
COPY_HARD_REG_SET (used1, call_fixed_reg_set);
*************** find_reg (num, losers, alt_regs_p, accep
*** 1001,1010 ****
IOR_HARD_REG_SET (used1, allocno[num].hard_reg_conflicts);
! #ifdef CLASS_CANNOT_CHANGE_MODE
! if (REG_CHANGES_MODE (allocno[num].reg))
! IOR_HARD_REG_SET (used1,
! reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE]);
#endif
/* Try each hard reg to see if it fits. Do this in two passes.
--- 1002,1009 ----
IOR_HARD_REG_SET (used1, allocno[num].hard_reg_conflicts);
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
! cannot_change_mode_set_regs (&used1, mode, allocno[num].reg);
#endif
/* Try each hard reg to see if it fits. Do this in two passes.
*************** find_reg (num, losers, alt_regs_p, accep
*** 1200,1210 ****
&& (allocno[num].calls_crossed == 0
|| accept_call_clobbered
|| ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))
! #ifdef CLASS_CANNOT_CHANGE_MODE
! && ! (REG_CHANGES_MODE (allocno[num].reg)
! && (TEST_HARD_REG_BIT
! (reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE],
! regno)))
#endif
)
{
--- 1199,1207 ----
&& (allocno[num].calls_crossed == 0
|| accept_call_clobbered
|| ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
! && ! invalid_mode_change_p (regno, REGNO_REG_CLASS (regno),
! mode)
#endif
)
{
Index: local-alloc.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/local-alloc.c,v
retrieving revision 1.111
diff -c -p -r1.111 local-alloc.c
*** local-alloc.c 22 Sep 2002 14:09:34 -0000 1.111
--- local-alloc.c 22 Oct 2002 22:00:10 -0000
*************** struct qty
*** 144,155 ****
or -1 if none was found. */
short phys_reg;
-
- /* Nonzero if this quantity has been used in a SUBREG in some
- way that is illegal. */
-
- char changes_mode;
-
};
static struct qty *qty;
--- 144,149 ----
*************** alloc_qty (regno, mode, size, birth)
*** 328,334 ****
qty[qtyno].alternate_class = reg_alternate_class (regno);
qty[qtyno].n_refs = REG_N_REFS (regno);
qty[qtyno].freq = REG_FREQ (regno);
- qty[qtyno].changes_mode = REG_CHANGES_MODE (regno);
}
/* Main entry point of this file. */
--- 322,327 ----
*************** update_qty_class (qtyno, reg)
*** 2026,2034 ****
rclass = reg_alternate_class (reg);
if (reg_class_subset_p (rclass, qty[qtyno].alternate_class))
qty[qtyno].alternate_class = rclass;
-
- if (REG_CHANGES_MODE (reg))
- qty[qtyno].changes_mode = 1;
}
/* Handle something which alters the value of an rtx REG.
--- 2019,2024 ----
*************** find_free_reg (class, mode, qtyno, accep
*** 2234,2243 ****
SET_HARD_REG_BIT (used, FRAME_POINTER_REGNUM);
#endif
! #ifdef CLASS_CANNOT_CHANGE_MODE
! if (qty[qtyno].changes_mode)
! IOR_HARD_REG_SET (used,
! reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE]);
#endif
/* Normally, the registers that can be used for the first register in
--- 2224,2232 ----
SET_HARD_REG_BIT (used, FRAME_POINTER_REGNUM);
#endif
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
! /* FIXME: ?? should FROM_MODE=mode or FROM_MODE=qty[qtyno].mode ?? */
! cannot_change_mode_set_regs (&used, mode, qty[qtyno].first_reg);
#endif
/* Normally, the registers that can be used for the first register in
Index: recog.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/recog.c,v
retrieving revision 1.165
diff -c -p -r1.165 recog.c
*** recog.c 26 Sep 2002 22:25:12 -0000 1.165
--- recog.c 22 Oct 2002 22:00:10 -0000
*************** register_operand (op, mode)
*** 1083,1095 ****
if (! reload_completed && GET_CODE (sub) == MEM)
return general_operand (op, mode);
! #ifdef CLASS_CANNOT_CHANGE_MODE
if (GET_CODE (sub) == REG
&& REGNO (sub) < FIRST_PSEUDO_REGISTER
! && (TEST_HARD_REG_BIT
! (reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE],
! REGNO (sub)))
! && CLASS_CANNOT_CHANGE_MODE_P (mode, GET_MODE (sub))
&& GET_MODE_CLASS (GET_MODE (sub)) != MODE_COMPLEX_INT
&& GET_MODE_CLASS (GET_MODE (sub)) != MODE_COMPLEX_FLOAT)
return 0;
--- 1083,1093 ----
if (! reload_completed && GET_CODE (sub) == MEM)
return general_operand (op, mode);
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
if (GET_CODE (sub) == REG
&& REGNO (sub) < FIRST_PSEUDO_REGISTER
! && CLASS_CANNOT_CHANGE_MODE_P (REGNO_REG_CLASS (REGNO (sub)),
! mode, GET_MODE (sub))
&& GET_MODE_CLASS (GET_MODE (sub)) != MODE_COMPLEX_INT
&& GET_MODE_CLASS (GET_MODE (sub)) != MODE_COMPLEX_FLOAT)
return 0;
Index: regclass.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/regclass.c,v
retrieving revision 1.158
diff -c -p -r1.158 regclass.c
*** regclass.c 26 Sep 2002 22:25:13 -0000 1.158
--- regclass.c 22 Oct 2002 22:00:10 -0000
*************** static char *in_inc_dec;
*** 227,246 ****
#endif /* FORBIDDEN_INC_DEC_CLASSES */
! #ifdef CLASS_CANNOT_CHANGE_MODE
!
! /* These are the classes containing only registers that can be used in
! a SUBREG expression that changes the mode of the register in some
! way that is illegal. */
!
! static int class_can_change_mode[N_REG_CLASSES];
!
! /* Registers, including pseudos, which change modes in some way that
! is illegal. */
!
! static regset reg_changes_mode;
!
! #endif /* CLASS_CANNOT_CHANGE_MODE */
/* Sample MEM values for use by memory_move_secondary_cost. */
--- 227,237 ----
#endif /* FORBIDDEN_INC_DEC_CLASSES */
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
! /* All registers that have been subreged. Indexed by mode, where each
! entry is a regset of registers. */
! regset_head subregs_of_mode [NUM_MACHINE_MODES];
! #endif
/* Sample MEM values for use by memory_move_secondary_cost. */
*************** init_reg_sets_1 ()
*** 549,570 ****
may_move_out_cost[m][i][j] = 65536;
}
}
-
- #ifdef CLASS_CANNOT_CHANGE_MODE
- {
- HARD_REG_SET c;
- COMPL_HARD_REG_SET (c, reg_class_contents[CLASS_CANNOT_CHANGE_MODE]);
-
- for (i = 0; i < N_REG_CLASSES; i++)
- {
- GO_IF_HARD_REG_SUBSET (reg_class_contents[i], c, ok_class);
- class_can_change_mode [i] = 0;
- continue;
- ok_class:
- class_can_change_mode [i] = 1;
- }
- }
- #endif /* CLASS_CANNOT_CHANGE_MODE */
}
/* Compute the table of register modes.
--- 540,545 ----
*************** dump_regclass (dump)
*** 952,960 ****
&& (!in_inc_dec[i]
|| !forbidden_inc_dec_class[(enum reg_class) class])
#endif
! #ifdef CLASS_CANNOT_CHANGE_MODE
! && (!REGNO_REG_SET_P (reg_changes_mode, i)
! || class_can_change_mode [(enum reg_class) class])
#endif
)
fprintf (dump, " %s:%i", reg_class_names[class],
--- 927,935 ----
&& (!in_inc_dec[i]
|| !forbidden_inc_dec_class[(enum reg_class) class])
#endif
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
! && ! invalid_mode_change_p (i, (enum reg_class) class,
! PSEUDO_REGNO_MODE (i))
#endif
)
fprintf (dump, " %s:%i", reg_class_names[class],
*************** record_operand_costs (insn, op_costs, re
*** 994,1008 ****
op_costs[i] = init_cost;
if (GET_CODE (recog_data.operand[i]) == SUBREG)
! {
! rtx inner = SUBREG_REG (recog_data.operand[i]);
! #ifdef CLASS_CANNOT_CHANGE_MODE
! if (GET_CODE (inner) == REG
! && CLASS_CANNOT_CHANGE_MODE_P (modes[i], GET_MODE (inner)))
! SET_REGNO_REG_SET (reg_changes_mode, REGNO (inner));
! #endif
! recog_data.operand[i] = inner;
! }
if (GET_CODE (recog_data.operand[i]) == MEM)
record_address_regs (XEXP (recog_data.operand[i], 0),
--- 969,975 ----
op_costs[i] = init_cost;
if (GET_CODE (recog_data.operand[i]) == SUBREG)
! recog_data.operand[i] = SUBREG_REG (recog_data.operand[i]);
if (GET_CODE (recog_data.operand[i]) == MEM)
record_address_regs (XEXP (recog_data.operand[i], 0),
*************** regclass (f, nregs, dump)
*** 1193,1202 ****
costs = (struct costs *) xmalloc (nregs * sizeof (struct costs));
- #ifdef CLASS_CANNOT_CHANGE_MODE
- reg_changes_mode = BITMAP_XMALLOC ();
- #endif
-
#ifdef FORBIDDEN_INC_DEC_CLASSES
in_inc_dec = (char *) xmalloc (nregs);
--- 1160,1165 ----
*************** regclass (f, nregs, dump)
*** 1323,1337 ****
for (class = (int) ALL_REGS - 1; class > 0; class--)
{
/* Ignore classes that are too small for this operand or
invalid for an operand that was auto-incremented. */
if (!contains_reg_of_mode [class][PSEUDO_REGNO_MODE (i)]
#ifdef FORBIDDEN_INC_DEC_CLASSES
|| (in_inc_dec[i] && forbidden_inc_dec_class[class])
#endif
! #ifdef CLASS_CANNOT_CHANGE_MODE
! || (REGNO_REG_SET_P (reg_changes_mode, i)
! && ! class_can_change_mode [class])
#endif
)
;
--- 1286,1302 ----
for (class = (int) ALL_REGS - 1; class > 0; class--)
{
+ enum machine_mode mode;
+
/* Ignore classes that are too small for this operand or
invalid for an operand that was auto-incremented. */
if (!contains_reg_of_mode [class][PSEUDO_REGNO_MODE (i)]
#ifdef FORBIDDEN_INC_DEC_CLASSES
|| (in_inc_dec[i] && forbidden_inc_dec_class[class])
#endif
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
! || invalid_mode_change_p (i, (enum reg_class) class,
! PSEUDO_REGNO_MODE (i))
#endif
)
;
*************** regclass (f, nregs, dump)
*** 1359,1367 ****
#ifdef FORBIDDEN_INC_DEC_CLASSES
&& ! (in_inc_dec[i] && forbidden_inc_dec_class[class])
#endif
! #ifdef CLASS_CANNOT_CHANGE_MODE
! && ! (REGNO_REG_SET_P (reg_changes_mode, i)
! && ! class_can_change_mode [class])
#endif
)
alt = reg_class_subunion[(int) alt][class];
--- 1324,1332 ----
#ifdef FORBIDDEN_INC_DEC_CLASSES
&& ! (in_inc_dec[i] && forbidden_inc_dec_class[class])
#endif
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
! && ! invalid_mode_change_p (i, (enum reg_class) class,
! PSEUDO_REGNO_MODE (i))
#endif
)
alt = reg_class_subunion[(int) alt][class];
*************** regclass (f, nregs, dump)
*** 1395,1403 ****
#ifdef FORBIDDEN_INC_DEC_CLASSES
free (in_inc_dec);
#endif
- #ifdef CLASS_CANNOT_CHANGE_MODE
- BITMAP_XFREE (reg_changes_mode);
- #endif
free (costs);
}
--- 1360,1365 ----
*************** regset_release_memory ()
*** 2642,2646 ****
--- 2604,2650 ----
{
bitmap_release_memory ();
}
+
+ #ifdef CLASS_CANNOT_CHANGE_MODE_P
+ /* Twiddle bits in USED for mode changes that are invalid for a
+ register. */
+
+ void
+ cannot_change_mode_set_regs (used, from, regno)
+ HARD_REG_SET *used;
+ enum machine_mode from;
+ unsigned int regno;
+ {
+ unsigned int r;
+ enum reg_class class;
+ enum machine_mode to;
+
+ for (to = VOIDmode; to < MAX_MACHINE_MODE; ++to)
+ if (REGNO_REG_SET_P (&subregs_of_mode[to], regno))
+ for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
+ {
+ class = REGNO_REG_CLASS (r);
+ if (CLASS_CANNOT_CHANGE_MODE_P (class, from, to))
+ SET_HARD_REG_BIT (*used, r);
+ }
+ }
+
+ /* Return 1 if a given REGNO has had an invalid mode change in CLASS. */
+
+ bool
+ invalid_mode_change_p (regno, class, from_mode)
+ unsigned int regno;
+ enum reg_class class;
+ enum machine_mode from_mode;
+ {
+ enum machine_mode to_mode=SImode;
+
+ for (to_mode = 0; to_mode < NUM_MACHINE_MODES; ++to_mode)
+ if (REGNO_REG_SET_P (&subregs_of_mode[(int) to_mode], regno)
+ && CLASS_CANNOT_CHANGE_MODE_P (class, from_mode, to_mode))
+ return 1;
+ return 0;
+ }
+ #endif /* CLASS_CANNOT_CHANGE_MODE_P */
#include "gt-regclass.h"
Index: regrename.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/regrename.c,v
retrieving revision 1.61
diff -c -p -r1.61 regrename.c
*** regrename.c 14 Sep 2002 13:12:50 -0000 1.61
--- regrename.c 22 Oct 2002 22:00:11 -0000
*************** mode_change_ok (orig_mode, new_mode, reg
*** 1313,1322 ****
if (GET_MODE_SIZE (orig_mode) < GET_MODE_SIZE (new_mode))
return false;
! #ifdef CLASS_CANNOT_CHANGE_MODE
! if (TEST_HARD_REG_BIT (reg_class_contents[CLASS_CANNOT_CHANGE_MODE], regno)
! && CLASS_CANNOT_CHANGE_MODE_P (orig_mode, new_mode))
! return false;
#endif
return true;
--- 1313,1321 ----
if (GET_MODE_SIZE (orig_mode) < GET_MODE_SIZE (new_mode))
return false;
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
! return !CLASS_CANNOT_CHANGE_MODE_P (REGNO_REG_CLASS (regno),
! orig_mode, new_mode);
#endif
return true;
Index: regs.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/regs.h,v
retrieving revision 1.25
diff -c -p -r1.25 regs.h
*** regs.h 27 Nov 2001 15:32:17 -0000 1.25
--- regs.h 22 Oct 2002 22:00:11 -0000
*************** Software Foundation, 59 Temple Place - S
*** 21,26 ****
--- 21,28 ----
#include "varray.h"
+ #include "hard-reg-set.h"
+ #include "basic-block.h"
#define REG_BYTES(R) mode_size[(int) GET_MODE (R)]
*************** typedef struct reg_info_def
*** 64,69 ****
--- 66,73 ----
extern varray_type reg_n_info;
+ extern regset_head subregs_of_mode [];
+
/* Indexed by n, gives number of times (REG n) is used or set. */
#define REG_N_REFS(N) (VARRAY_REG (reg_n_info, N)->refs)
*************** extern varray_type reg_n_info;
*** 103,115 ****
for registers that are contained in one basic block. */
#define REG_N_DEATHS(N) (VARRAY_REG (reg_n_info, N)->deaths)
-
- /* Indexed by N; says whether a pseudo register N was ever used
- within a SUBREG that changes the mode of the reg in some way
- that is illegal for a given class (usually floating-point)
- of registers. */
-
- #define REG_CHANGES_MODE(N) (VARRAY_REG (reg_n_info, N)->changes_mode)
/* Get the number of consecutive words required to hold pseudo-reg N. */
--- 107,112 ----
Index: reload.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload.c,v
retrieving revision 1.194
diff -c -p -r1.194 reload.c
*** reload.c 17 Oct 2002 15:13:10 -0000 1.194
--- reload.c 22 Oct 2002 22:00:11 -0000
*************** push_reload (in, out, inloc, outloc, cla
*** 967,975 ****
if (in != 0 && GET_CODE (in) == SUBREG
&& (subreg_lowpart_p (in) || strict_low)
! #ifdef CLASS_CANNOT_CHANGE_MODE
! && (class != CLASS_CANNOT_CHANGE_MODE
! || ! CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (SUBREG_REG (in)), inmode))
#endif
&& (CONSTANT_P (SUBREG_REG (in))
|| GET_CODE (SUBREG_REG (in)) == PLUS
--- 967,975 ----
if (in != 0 && GET_CODE (in) == SUBREG
&& (subreg_lowpart_p (in) || strict_low)
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
! && !CLASS_CANNOT_CHANGE_MODE_P (class, GET_MODE (SUBREG_REG (in)),
! inmode)
#endif
&& (CONSTANT_P (SUBREG_REG (in))
|| GET_CODE (SUBREG_REG (in)) == PLUS
*************** push_reload (in, out, inloc, outloc, cla
*** 1016,1029 ****
SUBREG_REG (in))
== NO_REGS))
#endif
! #ifdef CLASS_CANNOT_CHANGE_MODE
|| (GET_CODE (SUBREG_REG (in)) == REG
&& REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
! && (TEST_HARD_REG_BIT
! (reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE],
! REGNO (SUBREG_REG (in))))
! && CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (SUBREG_REG (in)),
! inmode))
#endif
))
{
--- 1016,1028 ----
SUBREG_REG (in))
== NO_REGS))
#endif
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
|| (GET_CODE (SUBREG_REG (in)) == REG
&& REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
! && CLASS_CANNOT_CHANGE_MODE_P
! (REGNO_REG_CLASS (REGNO (SUBREG_REG (in))),
! GET_MODE (SUBREG_REG (in)),
! inmode))
#endif
))
{
*************** push_reload (in, out, inloc, outloc, cla
*** 1081,1090 ****
and in that case the constraint should label it input-output.) */
if (out != 0 && GET_CODE (out) == SUBREG
&& (subreg_lowpart_p (out) || strict_low)
! #ifdef CLASS_CANNOT_CHANGE_MODE
! && (class != CLASS_CANNOT_CHANGE_MODE
! || ! CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (SUBREG_REG (out)),
! outmode))
#endif
&& (CONSTANT_P (SUBREG_REG (out))
|| strict_low
--- 1080,1088 ----
and in that case the constraint should label it input-output.) */
if (out != 0 && GET_CODE (out) == SUBREG
&& (subreg_lowpart_p (out) || strict_low)
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
! && !CLASS_CANNOT_CHANGE_MODE_P (class, GET_MODE (SUBREG_REG (out)),
! outmode)
#endif
&& (CONSTANT_P (SUBREG_REG (out))
|| strict_low
*************** push_reload (in, out, inloc, outloc, cla
*** 1118,1131 ****
SUBREG_REG (out))
== NO_REGS))
#endif
! #ifdef CLASS_CANNOT_CHANGE_MODE
|| (GET_CODE (SUBREG_REG (out)) == REG
&& REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
! && (TEST_HARD_REG_BIT
! (reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE],
! REGNO (SUBREG_REG (out))))
! && CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (SUBREG_REG (out)),
! outmode))
#endif
))
{
--- 1116,1127 ----
SUBREG_REG (out))
== NO_REGS))
#endif
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
|| (GET_CODE (SUBREG_REG (out)) == REG
&& REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
! && CLASS_CANNOT_CHANGE_MODE_P
! (REGNO_REG_CLASS (REGNO (SUBREG_REG (out))),
! GET_MODE (SUBREG_REG (out)), outmode))
#endif
))
{
Index: reload1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload1.c,v
retrieving revision 1.359
diff -c -p -r1.359 reload1.c
*** reload1.c 15 Oct 2002 22:46:30 -0000 1.359
--- reload1.c 22 Oct 2002 22:00:12 -0000
*************** choose_reload_regs (chain)
*** 5494,5509 ****
GET_MODE_CLASS (mode));
if (
! #ifdef CLASS_CANNOT_CHANGE_MODE
! (TEST_HARD_REG_BIT
! (reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE], i)
! ? ! CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (last_reg),
! need_mode)
! : (GET_MODE_SIZE (GET_MODE (last_reg))
! >= GET_MODE_SIZE (need_mode)))
! #else
(GET_MODE_SIZE (GET_MODE (last_reg))
>= GET_MODE_SIZE (need_mode))
#endif
&& reg_reloaded_contents[i] == regno
&& TEST_HARD_REG_BIT (reg_reloaded_valid, i)
--- 5494,5509 ----
GET_MODE_CLASS (mode));
if (
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
! (!CLASS_CANNOT_CHANGE_MODE_P (REGNO_REG_CLASS (i),
! GET_MODE (last_reg),
! need_mode)
! ||
! #endif
(GET_MODE_SIZE (GET_MODE (last_reg))
>= GET_MODE_SIZE (need_mode))
+ #ifdef CLASS_CANNOT_CHANGE_MODE_P
+ )
#endif
&& reg_reloaded_contents[i] == regno
&& TEST_HARD_REG_BIT (reg_reloaded_valid, i)
Index: rtl.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtl.h,v
retrieving revision 1.373
diff -c -p -r1.373 rtl.h
*** rtl.h 7 Oct 2002 17:55:46 -0000 1.373
--- rtl.h 22 Oct 2002 22:00:12 -0000
*************** extern void regclass PARAMS ((rtx, int
*** 2109,2114 ****
--- 2109,2122 ----
extern void reg_scan PARAMS ((rtx, unsigned int, int));
extern void reg_scan_update PARAMS ((rtx, rtx, unsigned int));
extern void fix_register PARAMS ((const char *, int, int));
+ #ifdef HARD_CONST
+ extern void cannot_change_mode_set_regs PARAMS ((HARD_REG_SET *,
+ enum machine_mode,
+ unsigned int));
+ #endif
+ extern bool invalid_mode_change_p PARAMS ((unsigned int,
+ enum reg_class,
+ enum machine_mode));
extern int delete_null_pointer_checks PARAMS ((rtx));
Index: simplify-rtx.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/simplify-rtx.c,v
retrieving revision 1.124
diff -c -p -r1.124 simplify-rtx.c
*** simplify-rtx.c 14 Oct 2002 18:16:07 -0000 1.124
--- simplify-rtx.c 22 Oct 2002 22:00:12 -0000
*************** simplify_subreg (outermode, op, innermod
*** 2583,2597 ****
if (REG_P (op)
&& (! REG_FUNCTION_VALUE_P (op)
|| ! rtx_equal_function_value_matters)
! #ifdef CLASS_CANNOT_CHANGE_MODE
! && ! (CLASS_CANNOT_CHANGE_MODE_P (outermode, innermode)
&& GET_MODE_CLASS (innermode) != MODE_COMPLEX_INT
! && GET_MODE_CLASS (innermode) != MODE_COMPLEX_FLOAT
! && (TEST_HARD_REG_BIT
! (reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE],
! REGNO (op))))
#endif
- && REGNO (op) < FIRST_PSEUDO_REGISTER
&& ((reload_completed && !frame_pointer_needed)
|| (REGNO (op) != FRAME_POINTER_REGNUM
#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
--- 2583,2595 ----
if (REG_P (op)
&& (! REG_FUNCTION_VALUE_P (op)
|| ! rtx_equal_function_value_matters)
! && REGNO (op) < FIRST_PSEUDO_REGISTER
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
! && ! (CLASS_CANNOT_CHANGE_MODE_P (REGNO_REG_CLASS (REGNO (op)),
! outermode, innermode)
&& GET_MODE_CLASS (innermode) != MODE_COMPLEX_INT
! && GET_MODE_CLASS (innermode) != MODE_COMPLEX_FLOAT)
#endif
&& ((reload_completed && !frame_pointer_needed)
|| (REGNO (op) != FRAME_POINTER_REGNUM
#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
Index: config/alpha/alpha.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/alpha/alpha.h,v
retrieving revision 1.182
diff -c -p -r1.182 alpha.h
*** config/alpha/alpha.h 24 Sep 2002 12:48:50 -0000 1.182
--- config/alpha/alpha.h 22 Oct 2002 22:00:12 -0000
*************** enum reg_class {
*** 857,871 ****
#define CLASS_MAX_NREGS(CLASS, MODE) \
((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
! /* If defined, gives a class of registers that cannot be used as the
! operand of a SUBREG that changes the mode of the object illegally. */
! #define CLASS_CANNOT_CHANGE_MODE FLOAT_REGS
!
! /* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE. */
!
! #define CLASS_CANNOT_CHANGE_MODE_P(FROM,TO) \
! (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO))
/* Define the cost of moving between registers of various classes. Moving
between FLOAT_REGS and anything else except float regs is expensive.
--- 857,866 ----
#define CLASS_MAX_NREGS(CLASS, MODE) \
((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
! /* Defines invalid mode changes within a class. */
! #define CLASS_CANNOT_CHANGE_MODE_P(CLASS, FROM, TO) \
! ((CLASS) == FLOAT_REGS && (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO)))
/* Define the cost of moving between registers of various classes. Moving
between FLOAT_REGS and anything else except float regs is expensive.
Index: config/ia64/ia64.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64.h,v
retrieving revision 1.130
diff -c -p -r1.130 ia64.h
*** config/ia64/ia64.h 24 Sep 2002 12:48:56 -0000 1.130
--- config/ia64/ia64.h 22 Oct 2002 22:00:13 -0000
*************** enum reg_class
*** 993,1009 ****
: ((CLASS) == FR_REGS && (MODE) == TFmode) ? 1 \
: (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
! /* If defined, gives a class of registers that cannot be used as the
! operand of a SUBREG that changes the mode of the object illegally. */
!
! #define CLASS_CANNOT_CHANGE_MODE FR_REGS
!
! /* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE.
! In FP regs, we can't change FP values to integer values and vice
versa, but we can change e.g. DImode to SImode. */
! #define CLASS_CANNOT_CHANGE_MODE_P(FROM,TO) \
! (GET_MODE_CLASS (FROM) != GET_MODE_CLASS (TO))
/* A C expression that defines the machine-dependent operand constraint
letters (`I', `J', `K', .. 'P') that specify particular ranges of
--- 993,1003 ----
: ((CLASS) == FR_REGS && (MODE) == TFmode) ? 1 \
: (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
! /* In FP regs, we can't change FP values to integer values and vice
versa, but we can change e.g. DImode to SImode. */
! #define CLASS_CANNOT_CHANGE_MODE_P(CLASS, FROM, TO) \
! ((CLASS) == FR_REGS && (GET_MODE_CLASS (FROM) != GET_MODE_CLASS (TO)))
/* A C expression that defines the machine-dependent operand constraint
letters (`I', `J', `K', .. 'P') that specify particular ranges of
Index: config/mips/mips.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.h,v
retrieving revision 1.225
diff -c -p -r1.225 mips.h
*** config/mips/mips.h 6 Oct 2002 17:50:42 -0000 1.225
--- config/mips/mips.h 22 Oct 2002 22:00:13 -0000
*************** extern enum reg_class mips_char_to_class
*** 2343,2356 ****
We can't allow 64-bit float registers to change from a 32-bit
mode to a 64-bit mode. */
! #define CLASS_CANNOT_CHANGE_MODE \
! (TARGET_BIG_ENDIAN ? FP_REGS \
! : (TARGET_FLOAT64 ? HI_AND_FP_REGS : HI_REG))
!
! /* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE. */
!
! #define CLASS_CANNOT_CHANGE_MODE_P(FROM,TO) \
! (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO))
/* Stack layout; function entry, exit and calling. */
--- 2343,2353 ----
We can't allow 64-bit float registers to change from a 32-bit
mode to a 64-bit mode. */
! #define CLASS_CANNOT_CHANGE_MODE_P(CLASS, FROM, TO) \
! (((TARGET_BIG_ENDIAN && (CLASS) == FP_REGS) \
! || (TARGET_FLOAT64 && (CLASS) == HI_AND_FP_REGS) \
! || (CLASS) == HI_REG) \
! && (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO)))
/* Stack layout; function entry, exit and calling. */
Index: config/pa/pa64-regs.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/pa/pa64-regs.h,v
retrieving revision 1.10
diff -c -p -r1.10 pa64-regs.h
*** config/pa/pa64-regs.h 4 Sep 2002 18:09:32 -0000 1.10
--- config/pa/pa64-regs.h 22 Oct 2002 22:00:13 -0000
*************** enum reg_class { NO_REGS, R1_REGS, GENER
*** 232,243 ****
{0x00000000, 0x10000000}, /* SHIFT_REGS */ \
{0xfffffffe, 0x1fffffff}} /* ALL_REGS */
! /* If defined, gives a class of registers that cannot be used as the
! operand of a SUBREG that changes the mode of the object illegally. */
!
! #define CLASS_CANNOT_CHANGE_MODE (FP_REGS)
!
! /* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE.
SImode loads to floating-point registers are not zero-extended.
The definition for LOAD_EXTEND_OP specifies that integer loads
--- 232,238 ----
{0x00000000, 0x10000000}, /* SHIFT_REGS */ \
{0xfffffffe, 0x1fffffff}} /* ALL_REGS */
! /* Defines invalid mode changes.
SImode loads to floating-point registers are not zero-extended.
The definition for LOAD_EXTEND_OP specifies that integer loads
*************** enum reg_class { NO_REGS, R1_REGS, GENER
*** 245,252 ****
we inhibit changes from SImode unless they are to a mode that is
identical in size. */
! #define CLASS_CANNOT_CHANGE_MODE_P(FROM,TO) \
! ((FROM) == SImode && GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO))
/* Return the class number of the smallest class containing
reg number REGNO. This could be a conditional expression
--- 240,248 ----
we inhibit changes from SImode unless they are to a mode that is
identical in size. */
! #define CLASS_CANNOT_CHANGE_MODE_P(CLASS, FROM, TO) \
! ((CLASS) == FP_REGS \
! && (FROM) == SImode && GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO))
/* Return the class number of the smallest class containing
reg number REGNO. This could be a conditional expression
Index: config/rs6000/rs6000.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.232
diff -c -p -r1.232 rs6000.h
*** config/rs6000/rs6000.h 18 Oct 2002 00:30:23 -0000 1.232
--- config/rs6000/rs6000.h 22 Oct 2002 22:00:14 -0000
*************** enum reg_class
*** 1335,1350 ****
? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \
: ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
- /* If defined, gives a class of registers that cannot be used as the
- operand of a SUBREG that changes the mode of the object illegally. */
! #define CLASS_CANNOT_CHANGE_MODE FLOAT_REGS
! /* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE. */
- #define CLASS_CANNOT_CHANGE_MODE_P(FROM,TO) \
- (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO))
-
/* Stack layout; function entry, exit and calling. */
/* Enumeration to give which calling sequence to use. */
--- 1335,1348 ----
? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \
: ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
! /* Return 1 if a given mode change is invalid for CLASS. */
! #define CLASS_CANNOT_CHANGE_MODE_P(CLASS, FROM, TO) \
! ((CLASS == FLOAT_REGS && GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO)) \
! || (CLASS == BASE_REGS \
! && (SPE_VECTOR_MODE (FROM) + SPE_VECTOR_MODE (TO)) == 1))
/* Stack layout; function entry, exit and calling. */
/* Enumeration to give which calling sequence to use. */
Index: config/s390/s390.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390.h,v
retrieving revision 1.45
diff -c -p -r1.45 s390.h
*** config/s390/s390.h 16 Oct 2002 19:09:25 -0000 1.45
--- config/s390/s390.h 22 Oct 2002 22:00:14 -0000
*************** do \
*** 391,402 ****
/* If defined, gives a class of registers that cannot be used as the
operand of a SUBREG that changes the mode of the object illegally. */
! #define CLASS_CANNOT_CHANGE_MODE FP_REGS
!
! /* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE. */
!
! #define CLASS_CANNOT_CHANGE_MODE_P(FROM,TO) \
! (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO))
/* This is an array of structures. Each structure initializes one pair
of eliminable registers. The "from" register number is given first,
--- 391,398 ----
/* If defined, gives a class of registers that cannot be used as the
operand of a SUBREG that changes the mode of the object illegally. */
! #define CLASS_CANNOT_CHANGE_MODE_P(CLASS, FROM, TO) \
! ((CLASS) == FP_REGS && GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO))
/* This is an array of structures. Each structure initializes one pair
of eliminable registers. The "from" register number is given first,
Index: config/sh/sh.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sh/sh.h,v
retrieving revision 1.171
diff -c -p -r1.171 sh.h
*** config/sh/sh.h 19 Sep 2002 13:17:57 -0000 1.171
--- config/sh/sh.h 22 Oct 2002 22:00:14 -0000
*************** extern const enum reg_class reg_class_fr
*** 1372,1385 ****
/* ??? We need to renumber the internal numbers for the frnn registers
when in little endian in order to allow mode size changes. */
! #define CLASS_CANNOT_CHANGE_MODE (TARGET_LITTLE_ENDIAN ? DF_REGS : DF_HI_REGS)
!
! /* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE. */
!
! #define CLASS_CANNOT_CHANGE_MODE_P(FROM,TO) \
! (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
! && ((TARGET_LITTLE_ENDIAN && GET_MODE_SIZE (TO) < 8) \
! || GET_MODE_SIZE (FROM) < 8))
/* Stack layout; function entry, exit and calling. */
--- 1372,1383 ----
/* ??? We need to renumber the internal numbers for the frnn registers
when in little endian in order to allow mode size changes. */
! #define CLASS_CANNOT_CHANGE_MODE_P(CLASS, FROM, TO) \
! (((TARGET_LITTLE_ENDIAN && (CLASS) == DF_REGS) \
! || (CLASS) == DF_HI_REGS) \
! && (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
! && ((TARGET_LITTLE_ENDIAN && GET_MODE_SIZE (TO) < 8) \
! || GET_MODE_SIZE (FROM) < 8)))
/* Stack layout; function entry, exit and calling. */
Index: doc/tm.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.177
diff -c -p -r1.177 tm.texi
*** doc/tm.texi 16 Oct 2002 00:40:38 -0000 1.177
--- doc/tm.texi 22 Oct 2002 22:00:15 -0000
*************** should be the maximum value of @code{HAR
*** 2561,2573 ****
This macro helps control the handling of multiple-word values
in the reload pass.
! @item CLASS_CANNOT_CHANGE_MODE
! If defined, a C expression for a class that contains registers for
! which the compiler may not change modes arbitrarily.
!
! @item CLASS_CANNOT_CHANGE_MODE_P(@var{from}, @var{to})
! A C expression that is true if, for a register in
! @code{CLASS_CANNOT_CHANGE_MODE}, the requested mode punning is invalid.
For the example, loading 32-bit integer or floating-point objects into
floating-point registers on the Alpha extends them to 64 bits.
--- 2561,2570 ----
This macro helps control the handling of multiple-word values
in the reload pass.
! @item CLASS_CANNOT_CHANGE_MODE_P(@var{class}, @var{from}, @var{to})
! If defined, a C expression that returns non-zero if changing a
! register of class @var{class} from mode @var{from} to mode @var{to} is
! invalid.
For the example, loading 32-bit integer or floating-point objects into
floating-point registers on the Alpha extends them to 64 bits.
Index: combine.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/combine.c,v
retrieving revision 1.321
diff -c -p -r1.321 combine.c
*** combine.c 15 Oct 2002 05:01:07 -0000 1.321
--- combine.c 24 Oct 2002 19:20:43 -0000
*************** subst (x, from, to, in_dest, unique_copy
*** 3519,3533 ****
)
return gen_rtx_CLOBBER (VOIDmode, const0_rtx);
! #ifdef CLASS_CANNOT_CHANGE_MODE
if (code == SUBREG
&& GET_CODE (to) == REG
&& REGNO (to) < FIRST_PSEUDO_REGISTER
! && (TEST_HARD_REG_BIT
! (reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE],
! REGNO (to)))
! && CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (to),
! GET_MODE (x)))
return gen_rtx_CLOBBER (VOIDmode, const0_rtx);
#endif
--- 3519,3532 ----
)
return gen_rtx_CLOBBER (VOIDmode, const0_rtx);
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
if (code == SUBREG
&& GET_CODE (to) == REG
&& REGNO (to) < FIRST_PSEUDO_REGISTER
! && CLASS_CANNOT_CHANGE_MODE_P
! (REGNO_REG_CLASS (REGNO (to)),
! GET_MODE (to),
! GET_MODE (x)))
return gen_rtx_CLOBBER (VOIDmode, const0_rtx);
#endif
*************** simplify_set (x)
*** 5198,5209 ****
&& (GET_MODE_SIZE (GET_MODE (src))
< GET_MODE_SIZE (GET_MODE (SUBREG_REG (src))))
#endif
! #ifdef CLASS_CANNOT_CHANGE_MODE
&& ! (GET_CODE (dest) == REG && REGNO (dest) < FIRST_PSEUDO_REGISTER
! && (TEST_HARD_REG_BIT
! (reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE],
! REGNO (dest)))
! && CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (src),
GET_MODE (SUBREG_REG (src))))
#endif
&& (GET_CODE (dest) == REG
--- 5197,5206 ----
&& (GET_MODE_SIZE (GET_MODE (src))
< GET_MODE_SIZE (GET_MODE (SUBREG_REG (src))))
#endif
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
&& ! (GET_CODE (dest) == REG && REGNO (dest) < FIRST_PSEUDO_REGISTER
! && CLASS_CANNOT_CHANGE_MODE_P (REGNO_REG_CLASS (REGNO (dest)),
! GET_MODE (src),
GET_MODE (SUBREG_REG (src))))
#endif
&& (GET_CODE (dest) == REG
*************** gen_lowpart_for_combine (mode, x)
*** 9937,9950 ****
}
result = gen_lowpart_common (mode, x);
! #ifdef CLASS_CANNOT_CHANGE_MODE
if (result != 0
&& GET_CODE (result) == SUBREG
&& GET_CODE (SUBREG_REG (result)) == REG
! && REGNO (SUBREG_REG (result)) >= FIRST_PSEUDO_REGISTER
! && CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (result),
! GET_MODE (SUBREG_REG (result))))
! REG_CHANGES_MODE (REGNO (SUBREG_REG (result))) = 1;
#endif
if (result)
--- 9934,9946 ----
}
result = gen_lowpart_common (mode, x);
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
if (result != 0
&& GET_CODE (result) == SUBREG
&& GET_CODE (SUBREG_REG (result)) == REG
! && REGNO (SUBREG_REG (result)) >= FIRST_PSEUDO_REGISTER)
! SET_REGNO_REG_SET (&subregs_of_mode[GET_MODE (result)],
! REGNO (SUBREG_REG (result)));
#endif
if (result)
Index: flow.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/flow.c,v
retrieving revision 1.539
diff -c -p -r1.539 flow.c
*** flow.c 1 Oct 2002 12:19:36 -0000 1.539
--- flow.c 24 Oct 2002 19:20:43 -0000
*************** life_analysis (f, file, flags)
*** 414,421 ****
FILE *file;
int flags;
{
- #ifdef ELIMINABLE_REGS
int i;
static const struct {const int from, to; } eliminables[] = ELIMINABLE_REGS;
#endif
--- 414,421 ----
FILE *file;
int flags;
{
int i;
+ #ifdef ELIMINABLE_REGS
static const struct {const int from, to; } eliminables[] = ELIMINABLE_REGS;
#endif
*************** life_analysis (f, file, flags)
*** 431,436 ****
--- 431,443 ----
SET_HARD_REG_BIT (elim_reg_set, FRAME_POINTER_REGNUM);
#endif
+
+ #ifdef CLASS_CANNOT_CHANGE_MODE_P
+ if (flags & PROP_REG_INFO)
+ for (i=0; i < NUM_MACHINE_MODES; ++i)
+ INIT_REG_SET (&subregs_of_mode[i]);
+ #endif
+
if (! optimize)
flags &= ~(PROP_LOG_LINKS | PROP_AUTOINC | PROP_ALLOW_CFG_CHANGES);
*************** mark_used_regs (pbi, x, cond, insn)
*** 3813,3824 ****
break;
case SUBREG:
! #ifdef CLASS_CANNOT_CHANGE_MODE
if (GET_CODE (SUBREG_REG (x)) == REG
! && REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER
! && CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (x),
! GET_MODE (SUBREG_REG (x))))
! REG_CHANGES_MODE (REGNO (SUBREG_REG (x))) = 1;
#endif
/* While we're here, optimize this case. */
--- 3820,3830 ----
break;
case SUBREG:
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
if (GET_CODE (SUBREG_REG (x)) == REG
! && REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER)
! SET_REGNO_REG_SET (&subregs_of_mode[GET_MODE (x)],
! REGNO (SUBREG_REG (x)));
#endif
/* While we're here, optimize this case. */
*************** mark_used_regs (pbi, x, cond, insn)
*** 3862,3874 ****
|| GET_CODE (testreg) == SIGN_EXTRACT
|| GET_CODE (testreg) == SUBREG)
{
! #ifdef CLASS_CANNOT_CHANGE_MODE
if (GET_CODE (testreg) == SUBREG
&& GET_CODE (SUBREG_REG (testreg)) == REG
! && REGNO (SUBREG_REG (testreg)) >= FIRST_PSEUDO_REGISTER
! && CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (SUBREG_REG (testreg)),
! GET_MODE (testreg)))
! REG_CHANGES_MODE (REGNO (SUBREG_REG (testreg))) = 1;
#endif
/* Modifying a single register in an alternate mode
--- 3868,3879 ----
|| GET_CODE (testreg) == SIGN_EXTRACT
|| GET_CODE (testreg) == SUBREG)
{
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
if (GET_CODE (testreg) == SUBREG
&& GET_CODE (SUBREG_REG (testreg)) == REG
! && REGNO (SUBREG_REG (testreg)) >= FIRST_PSEUDO_REGISTER)
! SET_REGNO_REG_SET (&subregs_of_mode[GET_MODE (testreg)],
! REGNO (SUBREG_REG (testreg)));
#endif
/* Modifying a single register in an alternate mode
Index: global.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/global.c,v
retrieving revision 1.85
diff -c -p -r1.85 global.c
*** global.c 22 Sep 2002 14:09:33 -0000 1.85
--- global.c 24 Oct 2002 19:20:43 -0000
*************** find_reg (num, losers, alt_regs_p, accep
*** 1001,1010 ****
IOR_HARD_REG_SET (used1, allocno[num].hard_reg_conflicts);
! #ifdef CLASS_CANNOT_CHANGE_MODE
! if (REG_CHANGES_MODE (allocno[num].reg))
! IOR_HARD_REG_SET (used1,
! reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE]);
#endif
/* Try each hard reg to see if it fits. Do this in two passes.
--- 1001,1008 ----
IOR_HARD_REG_SET (used1, allocno[num].hard_reg_conflicts);
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
! cannot_change_mode_set_regs (&used1, mode, allocno[num].reg);
#endif
/* Try each hard reg to see if it fits. Do this in two passes.
*************** find_reg (num, losers, alt_regs_p, accep
*** 1200,1210 ****
&& (allocno[num].calls_crossed == 0
|| accept_call_clobbered
|| ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))
! #ifdef CLASS_CANNOT_CHANGE_MODE
! && ! (REG_CHANGES_MODE (allocno[num].reg)
! && (TEST_HARD_REG_BIT
! (reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE],
! regno)))
#endif
)
{
--- 1198,1206 ----
&& (allocno[num].calls_crossed == 0
|| accept_call_clobbered
|| ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
! && ! invalid_mode_change_p (regno, REGNO_REG_CLASS (regno),
! mode)
#endif
)
{
Index: local-alloc.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/local-alloc.c,v
retrieving revision 1.111
diff -c -p -r1.111 local-alloc.c
*** local-alloc.c 22 Sep 2002 14:09:34 -0000 1.111
--- local-alloc.c 24 Oct 2002 19:20:44 -0000
*************** struct qty
*** 144,155 ****
or -1 if none was found. */
short phys_reg;
-
- /* Nonzero if this quantity has been used in a SUBREG in some
- way that is illegal. */
-
- char changes_mode;
-
};
static struct qty *qty;
--- 144,149 ----
*************** alloc_qty (regno, mode, size, birth)
*** 328,334 ****
qty[qtyno].alternate_class = reg_alternate_class (regno);
qty[qtyno].n_refs = REG_N_REFS (regno);
qty[qtyno].freq = REG_FREQ (regno);
- qty[qtyno].changes_mode = REG_CHANGES_MODE (regno);
}
/* Main entry point of this file. */
--- 322,327 ----
*************** update_qty_class (qtyno, reg)
*** 2026,2034 ****
rclass = reg_alternate_class (reg);
if (reg_class_subset_p (rclass, qty[qtyno].alternate_class))
qty[qtyno].alternate_class = rclass;
-
- if (REG_CHANGES_MODE (reg))
- qty[qtyno].changes_mode = 1;
}
/* Handle something which alters the value of an rtx REG.
--- 2019,2024 ----
*************** find_free_reg (class, mode, qtyno, accep
*** 2234,2243 ****
SET_HARD_REG_BIT (used, FRAME_POINTER_REGNUM);
#endif
! #ifdef CLASS_CANNOT_CHANGE_MODE
! if (qty[qtyno].changes_mode)
! IOR_HARD_REG_SET (used,
! reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE]);
#endif
/* Normally, the registers that can be used for the first register in
--- 2224,2231 ----
SET_HARD_REG_BIT (used, FRAME_POINTER_REGNUM);
#endif
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
! cannot_change_mode_set_regs (&used, mode, qty[qtyno].first_reg);
#endif
/* Normally, the registers that can be used for the first register in
Index: recog.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/recog.c,v
retrieving revision 1.165
diff -c -p -r1.165 recog.c
*** recog.c 26 Sep 2002 22:25:12 -0000 1.165
--- recog.c 24 Oct 2002 19:20:44 -0000
*************** register_operand (op, mode)
*** 1083,1095 ****
if (! reload_completed && GET_CODE (sub) == MEM)
return general_operand (op, mode);
! #ifdef CLASS_CANNOT_CHANGE_MODE
if (GET_CODE (sub) == REG
&& REGNO (sub) < FIRST_PSEUDO_REGISTER
! && (TEST_HARD_REG_BIT
! (reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE],
! REGNO (sub)))
! && CLASS_CANNOT_CHANGE_MODE_P (mode, GET_MODE (sub))
&& GET_MODE_CLASS (GET_MODE (sub)) != MODE_COMPLEX_INT
&& GET_MODE_CLASS (GET_MODE (sub)) != MODE_COMPLEX_FLOAT)
return 0;
--- 1083,1093 ----
if (! reload_completed && GET_CODE (sub) == MEM)
return general_operand (op, mode);
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
if (GET_CODE (sub) == REG
&& REGNO (sub) < FIRST_PSEUDO_REGISTER
! && CLASS_CANNOT_CHANGE_MODE_P (REGNO_REG_CLASS (REGNO (sub)),
! mode, GET_MODE (sub))
&& GET_MODE_CLASS (GET_MODE (sub)) != MODE_COMPLEX_INT
&& GET_MODE_CLASS (GET_MODE (sub)) != MODE_COMPLEX_FLOAT)
return 0;
Index: regclass.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/regclass.c,v
retrieving revision 1.158
diff -c -p -r1.158 regclass.c
*** regclass.c 26 Sep 2002 22:25:13 -0000 1.158
--- regclass.c 24 Oct 2002 19:20:44 -0000
*************** static char *in_inc_dec;
*** 227,246 ****
#endif /* FORBIDDEN_INC_DEC_CLASSES */
! #ifdef CLASS_CANNOT_CHANGE_MODE
!
! /* These are the classes containing only registers that can be used in
! a SUBREG expression that changes the mode of the register in some
! way that is illegal. */
!
! static int class_can_change_mode[N_REG_CLASSES];
!
! /* Registers, including pseudos, which change modes in some way that
! is illegal. */
!
! static regset reg_changes_mode;
!
! #endif /* CLASS_CANNOT_CHANGE_MODE */
/* Sample MEM values for use by memory_move_secondary_cost. */
--- 227,237 ----
#endif /* FORBIDDEN_INC_DEC_CLASSES */
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
! /* All registers that have been subreged. Indexed by mode, where each
! entry is a regset of registers. */
! regset_head subregs_of_mode [NUM_MACHINE_MODES];
! #endif
/* Sample MEM values for use by memory_move_secondary_cost. */
*************** init_reg_sets_1 ()
*** 549,570 ****
may_move_out_cost[m][i][j] = 65536;
}
}
-
- #ifdef CLASS_CANNOT_CHANGE_MODE
- {
- HARD_REG_SET c;
- COMPL_HARD_REG_SET (c, reg_class_contents[CLASS_CANNOT_CHANGE_MODE]);
-
- for (i = 0; i < N_REG_CLASSES; i++)
- {
- GO_IF_HARD_REG_SUBSET (reg_class_contents[i], c, ok_class);
- class_can_change_mode [i] = 0;
- continue;
- ok_class:
- class_can_change_mode [i] = 1;
- }
- }
- #endif /* CLASS_CANNOT_CHANGE_MODE */
}
/* Compute the table of register modes.
--- 540,545 ----
*************** dump_regclass (dump)
*** 952,960 ****
&& (!in_inc_dec[i]
|| !forbidden_inc_dec_class[(enum reg_class) class])
#endif
! #ifdef CLASS_CANNOT_CHANGE_MODE
! && (!REGNO_REG_SET_P (reg_changes_mode, i)
! || class_can_change_mode [(enum reg_class) class])
#endif
)
fprintf (dump, " %s:%i", reg_class_names[class],
--- 927,935 ----
&& (!in_inc_dec[i]
|| !forbidden_inc_dec_class[(enum reg_class) class])
#endif
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
! && ! invalid_mode_change_p (i, (enum reg_class) class,
! PSEUDO_REGNO_MODE (i))
#endif
)
fprintf (dump, " %s:%i", reg_class_names[class],
*************** record_operand_costs (insn, op_costs, re
*** 994,1008 ****
op_costs[i] = init_cost;
if (GET_CODE (recog_data.operand[i]) == SUBREG)
! {
! rtx inner = SUBREG_REG (recog_data.operand[i]);
! #ifdef CLASS_CANNOT_CHANGE_MODE
! if (GET_CODE (inner) == REG
! && CLASS_CANNOT_CHANGE_MODE_P (modes[i], GET_MODE (inner)))
! SET_REGNO_REG_SET (reg_changes_mode, REGNO (inner));
! #endif
! recog_data.operand[i] = inner;
! }
if (GET_CODE (recog_data.operand[i]) == MEM)
record_address_regs (XEXP (recog_data.operand[i], 0),
--- 969,975 ----
op_costs[i] = init_cost;
if (GET_CODE (recog_data.operand[i]) == SUBREG)
! recog_data.operand[i] = SUBREG_REG (recog_data.operand[i]);
if (GET_CODE (recog_data.operand[i]) == MEM)
record_address_regs (XEXP (recog_data.operand[i], 0),
*************** regclass (f, nregs, dump)
*** 1193,1202 ****
costs = (struct costs *) xmalloc (nregs * sizeof (struct costs));
- #ifdef CLASS_CANNOT_CHANGE_MODE
- reg_changes_mode = BITMAP_XMALLOC ();
- #endif
-
#ifdef FORBIDDEN_INC_DEC_CLASSES
in_inc_dec = (char *) xmalloc (nregs);
--- 1160,1165 ----
*************** regclass (f, nregs, dump)
*** 1329,1337 ****
#ifdef FORBIDDEN_INC_DEC_CLASSES
|| (in_inc_dec[i] && forbidden_inc_dec_class[class])
#endif
! #ifdef CLASS_CANNOT_CHANGE_MODE
! || (REGNO_REG_SET_P (reg_changes_mode, i)
! && ! class_can_change_mode [class])
#endif
)
;
--- 1292,1300 ----
#ifdef FORBIDDEN_INC_DEC_CLASSES
|| (in_inc_dec[i] && forbidden_inc_dec_class[class])
#endif
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
! || invalid_mode_change_p (i, (enum reg_class) class,
! PSEUDO_REGNO_MODE (i))
#endif
)
;
*************** regclass (f, nregs, dump)
*** 1359,1367 ****
#ifdef FORBIDDEN_INC_DEC_CLASSES
&& ! (in_inc_dec[i] && forbidden_inc_dec_class[class])
#endif
! #ifdef CLASS_CANNOT_CHANGE_MODE
! && ! (REGNO_REG_SET_P (reg_changes_mode, i)
! && ! class_can_change_mode [class])
#endif
)
alt = reg_class_subunion[(int) alt][class];
--- 1322,1330 ----
#ifdef FORBIDDEN_INC_DEC_CLASSES
&& ! (in_inc_dec[i] && forbidden_inc_dec_class[class])
#endif
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
! && ! invalid_mode_change_p (i, (enum reg_class) class,
! PSEUDO_REGNO_MODE (i))
#endif
)
alt = reg_class_subunion[(int) alt][class];
*************** regclass (f, nregs, dump)
*** 1395,1403 ****
#ifdef FORBIDDEN_INC_DEC_CLASSES
free (in_inc_dec);
#endif
- #ifdef CLASS_CANNOT_CHANGE_MODE
- BITMAP_XFREE (reg_changes_mode);
- #endif
free (costs);
}
--- 1358,1363 ----
*************** regset_release_memory ()
*** 2642,2646 ****
--- 2602,2649 ----
{
bitmap_release_memory ();
}
+
+ #ifdef CLASS_CANNOT_CHANGE_MODE_P
+ /* Set bits in *USED which correspond to registers which can't change
+ their mode from FROM to any mode in which REGNO was encountered. */
+
+ void
+ cannot_change_mode_set_regs (used, from, regno)
+ HARD_REG_SET *used;
+ enum machine_mode from;
+ unsigned int regno;
+ {
+ unsigned int r;
+ enum reg_class class;
+ enum machine_mode to;
+
+ for (to = VOIDmode; to < MAX_MACHINE_MODE; ++to)
+ if (REGNO_REG_SET_P (&subregs_of_mode[to], regno))
+ for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
+ {
+ class = REGNO_REG_CLASS (r);
+ if (CLASS_CANNOT_CHANGE_MODE_P (class, from, to))
+ SET_HARD_REG_BIT (*used, r);
+ }
+ }
+
+ /* Return 1 if REGNO has had an invalid mode change in CLASS from FROM
+ mode. */
+
+ bool
+ invalid_mode_change_p (regno, class, from_mode)
+ unsigned int regno;
+ enum reg_class class;
+ enum machine_mode from_mode;
+ {
+ enum machine_mode to_mode=SImode;
+
+ for (to_mode = 0; to_mode < NUM_MACHINE_MODES; ++to_mode)
+ if (REGNO_REG_SET_P (&subregs_of_mode[(int) to_mode], regno)
+ && CLASS_CANNOT_CHANGE_MODE_P (class, from_mode, to_mode))
+ return 1;
+ return 0;
+ }
+ #endif /* CLASS_CANNOT_CHANGE_MODE_P */
#include "gt-regclass.h"
Index: regrename.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/regrename.c,v
retrieving revision 1.61
diff -c -p -r1.61 regrename.c
*** regrename.c 14 Sep 2002 13:12:50 -0000 1.61
--- regrename.c 24 Oct 2002 19:20:44 -0000
*************** mode_change_ok (orig_mode, new_mode, reg
*** 1313,1322 ****
if (GET_MODE_SIZE (orig_mode) < GET_MODE_SIZE (new_mode))
return false;
! #ifdef CLASS_CANNOT_CHANGE_MODE
! if (TEST_HARD_REG_BIT (reg_class_contents[CLASS_CANNOT_CHANGE_MODE], regno)
! && CLASS_CANNOT_CHANGE_MODE_P (orig_mode, new_mode))
! return false;
#endif
return true;
--- 1313,1321 ----
if (GET_MODE_SIZE (orig_mode) < GET_MODE_SIZE (new_mode))
return false;
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
! return !CLASS_CANNOT_CHANGE_MODE_P (REGNO_REG_CLASS (regno),
! orig_mode, new_mode);
#endif
return true;
Index: regs.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/regs.h,v
retrieving revision 1.25
diff -c -p -r1.25 regs.h
*** regs.h 27 Nov 2001 15:32:17 -0000 1.25
--- regs.h 24 Oct 2002 19:20:44 -0000
*************** Software Foundation, 59 Temple Place - S
*** 21,26 ****
--- 21,28 ----
#include "varray.h"
+ #include "hard-reg-set.h"
+ #include "basic-block.h"
#define REG_BYTES(R) mode_size[(int) GET_MODE (R)]
*************** typedef struct reg_info_def
*** 64,69 ****
--- 66,73 ----
extern varray_type reg_n_info;
+ extern regset_head subregs_of_mode [NUM_MACHINE_MODES];
+
/* Indexed by n, gives number of times (REG n) is used or set. */
#define REG_N_REFS(N) (VARRAY_REG (reg_n_info, N)->refs)
*************** extern varray_type reg_n_info;
*** 103,115 ****
for registers that are contained in one basic block. */
#define REG_N_DEATHS(N) (VARRAY_REG (reg_n_info, N)->deaths)
-
- /* Indexed by N; says whether a pseudo register N was ever used
- within a SUBREG that changes the mode of the reg in some way
- that is illegal for a given class (usually floating-point)
- of registers. */
-
- #define REG_CHANGES_MODE(N) (VARRAY_REG (reg_n_info, N)->changes_mode)
/* Get the number of consecutive words required to hold pseudo-reg N. */
--- 107,112 ----
Index: reload.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload.c,v
retrieving revision 1.194
diff -c -p -r1.194 reload.c
*** reload.c 17 Oct 2002 15:13:10 -0000 1.194
--- reload.c 24 Oct 2002 19:20:45 -0000
*************** push_reload (in, out, inloc, outloc, cla
*** 967,975 ****
if (in != 0 && GET_CODE (in) == SUBREG
&& (subreg_lowpart_p (in) || strict_low)
! #ifdef CLASS_CANNOT_CHANGE_MODE
! && (class != CLASS_CANNOT_CHANGE_MODE
! || ! CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (SUBREG_REG (in)), inmode))
#endif
&& (CONSTANT_P (SUBREG_REG (in))
|| GET_CODE (SUBREG_REG (in)) == PLUS
--- 967,975 ----
if (in != 0 && GET_CODE (in) == SUBREG
&& (subreg_lowpart_p (in) || strict_low)
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
! && !CLASS_CANNOT_CHANGE_MODE_P (class, GET_MODE (SUBREG_REG (in)),
! inmode)
#endif
&& (CONSTANT_P (SUBREG_REG (in))
|| GET_CODE (SUBREG_REG (in)) == PLUS
*************** push_reload (in, out, inloc, outloc, cla
*** 1016,1029 ****
SUBREG_REG (in))
== NO_REGS))
#endif
! #ifdef CLASS_CANNOT_CHANGE_MODE
|| (GET_CODE (SUBREG_REG (in)) == REG
&& REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
! && (TEST_HARD_REG_BIT
! (reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE],
! REGNO (SUBREG_REG (in))))
! && CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (SUBREG_REG (in)),
! inmode))
#endif
))
{
--- 1016,1028 ----
SUBREG_REG (in))
== NO_REGS))
#endif
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
|| (GET_CODE (SUBREG_REG (in)) == REG
&& REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
! && CLASS_CANNOT_CHANGE_MODE_P
! (REGNO_REG_CLASS (REGNO (SUBREG_REG (in))),
! GET_MODE (SUBREG_REG (in)),
! inmode))
#endif
))
{
*************** push_reload (in, out, inloc, outloc, cla
*** 1081,1090 ****
and in that case the constraint should label it input-output.) */
if (out != 0 && GET_CODE (out) == SUBREG
&& (subreg_lowpart_p (out) || strict_low)
! #ifdef CLASS_CANNOT_CHANGE_MODE
! && (class != CLASS_CANNOT_CHANGE_MODE
! || ! CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (SUBREG_REG (out)),
! outmode))
#endif
&& (CONSTANT_P (SUBREG_REG (out))
|| strict_low
--- 1080,1088 ----
and in that case the constraint should label it input-output.) */
if (out != 0 && GET_CODE (out) == SUBREG
&& (subreg_lowpart_p (out) || strict_low)
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
! && !CLASS_CANNOT_CHANGE_MODE_P (class, GET_MODE (SUBREG_REG (out)),
! outmode)
#endif
&& (CONSTANT_P (SUBREG_REG (out))
|| strict_low
*************** push_reload (in, out, inloc, outloc, cla
*** 1118,1131 ****
SUBREG_REG (out))
== NO_REGS))
#endif
! #ifdef CLASS_CANNOT_CHANGE_MODE
|| (GET_CODE (SUBREG_REG (out)) == REG
&& REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
! && (TEST_HARD_REG_BIT
! (reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE],
! REGNO (SUBREG_REG (out))))
! && CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (SUBREG_REG (out)),
! outmode))
#endif
))
{
--- 1116,1127 ----
SUBREG_REG (out))
== NO_REGS))
#endif
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
|| (GET_CODE (SUBREG_REG (out)) == REG
&& REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
! && CLASS_CANNOT_CHANGE_MODE_P
! (REGNO_REG_CLASS (REGNO (SUBREG_REG (out))),
! GET_MODE (SUBREG_REG (out)), outmode))
#endif
))
{
Index: reload1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload1.c,v
retrieving revision 1.359
diff -c -p -r1.359 reload1.c
*** reload1.c 15 Oct 2002 22:46:30 -0000 1.359
--- reload1.c 24 Oct 2002 19:20:45 -0000
*************** choose_reload_regs (chain)
*** 5494,5509 ****
GET_MODE_CLASS (mode));
if (
! #ifdef CLASS_CANNOT_CHANGE_MODE
! (TEST_HARD_REG_BIT
! (reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE], i)
! ? ! CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (last_reg),
! need_mode)
! : (GET_MODE_SIZE (GET_MODE (last_reg))
! >= GET_MODE_SIZE (need_mode)))
! #else
(GET_MODE_SIZE (GET_MODE (last_reg))
>= GET_MODE_SIZE (need_mode))
#endif
&& reg_reloaded_contents[i] == regno
&& TEST_HARD_REG_BIT (reg_reloaded_valid, i)
--- 5494,5509 ----
GET_MODE_CLASS (mode));
if (
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
! (!CLASS_CANNOT_CHANGE_MODE_P (REGNO_REG_CLASS (i),
! GET_MODE (last_reg),
! need_mode)
! ||
! #endif
(GET_MODE_SIZE (GET_MODE (last_reg))
>= GET_MODE_SIZE (need_mode))
+ #ifdef CLASS_CANNOT_CHANGE_MODE_P
+ )
#endif
&& reg_reloaded_contents[i] == regno
&& TEST_HARD_REG_BIT (reg_reloaded_valid, i)
Index: rtl.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtl.h,v
retrieving revision 1.373
diff -c -p -r1.373 rtl.h
*** rtl.h 7 Oct 2002 17:55:46 -0000 1.373
--- rtl.h 24 Oct 2002 19:20:46 -0000
*************** extern void regclass PARAMS ((rtx, int
*** 2109,2114 ****
--- 2109,2122 ----
extern void reg_scan PARAMS ((rtx, unsigned int, int));
extern void reg_scan_update PARAMS ((rtx, rtx, unsigned int));
extern void fix_register PARAMS ((const char *, int, int));
+ #ifdef HARD_CONST
+ extern void cannot_change_mode_set_regs PARAMS ((HARD_REG_SET *,
+ enum machine_mode,
+ unsigned int));
+ #endif
+ extern bool invalid_mode_change_p PARAMS ((unsigned int,
+ enum reg_class,
+ enum machine_mode));
extern int delete_null_pointer_checks PARAMS ((rtx));
Index: simplify-rtx.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/simplify-rtx.c,v
retrieving revision 1.124
diff -c -p -r1.124 simplify-rtx.c
*** simplify-rtx.c 14 Oct 2002 18:16:07 -0000 1.124
--- simplify-rtx.c 24 Oct 2002 19:20:46 -0000
*************** simplify_subreg (outermode, op, innermod
*** 2583,2597 ****
if (REG_P (op)
&& (! REG_FUNCTION_VALUE_P (op)
|| ! rtx_equal_function_value_matters)
! #ifdef CLASS_CANNOT_CHANGE_MODE
! && ! (CLASS_CANNOT_CHANGE_MODE_P (outermode, innermode)
&& GET_MODE_CLASS (innermode) != MODE_COMPLEX_INT
! && GET_MODE_CLASS (innermode) != MODE_COMPLEX_FLOAT
! && (TEST_HARD_REG_BIT
! (reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE],
! REGNO (op))))
#endif
- && REGNO (op) < FIRST_PSEUDO_REGISTER
&& ((reload_completed && !frame_pointer_needed)
|| (REGNO (op) != FRAME_POINTER_REGNUM
#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
--- 2583,2595 ----
if (REG_P (op)
&& (! REG_FUNCTION_VALUE_P (op)
|| ! rtx_equal_function_value_matters)
! && REGNO (op) < FIRST_PSEUDO_REGISTER
! #ifdef CLASS_CANNOT_CHANGE_MODE_P
! && ! (CLASS_CANNOT_CHANGE_MODE_P (REGNO_REG_CLASS (REGNO (op)),
! outermode, innermode)
&& GET_MODE_CLASS (innermode) != MODE_COMPLEX_INT
! && GET_MODE_CLASS (innermode) != MODE_COMPLEX_FLOAT)
#endif
&& ((reload_completed && !frame_pointer_needed)
|| (REGNO (op) != FRAME_POINTER_REGNUM
#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
Index: config/alpha/alpha.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/alpha/alpha.h,v
retrieving revision 1.182
diff -c -p -r1.182 alpha.h
*** config/alpha/alpha.h 24 Sep 2002 12:48:50 -0000 1.182
--- config/alpha/alpha.h 24 Oct 2002 19:20:46 -0000
*************** enum reg_class {
*** 857,871 ****
#define CLASS_MAX_NREGS(CLASS, MODE) \
((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
! /* If defined, gives a class of registers that cannot be used as the
! operand of a SUBREG that changes the mode of the object illegally. */
! #define CLASS_CANNOT_CHANGE_MODE FLOAT_REGS
!
! /* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE. */
!
! #define CLASS_CANNOT_CHANGE_MODE_P(FROM,TO) \
! (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO))
/* Define the cost of moving between registers of various classes. Moving
between FLOAT_REGS and anything else except float regs is expensive.
--- 857,867 ----
#define CLASS_MAX_NREGS(CLASS, MODE) \
((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
! /* Defines invalid mode changes within a class. */
! #define CLASS_CANNOT_CHANGE_MODE_P(CLASS, FROM, TO) \
! (reg_classes_intersect_p (CLASS, FLOAT_REGS) \
! && (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO)))
/* Define the cost of moving between registers of various classes. Moving
between FLOAT_REGS and anything else except float regs is expensive.
Index: config/ia64/ia64.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64.h,v
retrieving revision 1.130
diff -c -p -r1.130 ia64.h
*** config/ia64/ia64.h 24 Sep 2002 12:48:56 -0000 1.130
--- config/ia64/ia64.h 24 Oct 2002 19:20:46 -0000
*************** enum reg_class
*** 993,1009 ****
: ((CLASS) == FR_REGS && (MODE) == TFmode) ? 1 \
: (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
! /* If defined, gives a class of registers that cannot be used as the
! operand of a SUBREG that changes the mode of the object illegally. */
!
! #define CLASS_CANNOT_CHANGE_MODE FR_REGS
!
! /* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE.
! In FP regs, we can't change FP values to integer values and vice
versa, but we can change e.g. DImode to SImode. */
! #define CLASS_CANNOT_CHANGE_MODE_P(FROM,TO) \
! (GET_MODE_CLASS (FROM) != GET_MODE_CLASS (TO))
/* A C expression that defines the machine-dependent operand constraint
letters (`I', `J', `K', .. 'P') that specify particular ranges of
--- 993,1004 ----
: ((CLASS) == FR_REGS && (MODE) == TFmode) ? 1 \
: (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
! /* In FP regs, we can't change FP values to integer values and vice
versa, but we can change e.g. DImode to SImode. */
! #define CLASS_CANNOT_CHANGE_MODE_P(CLASS, FROM, TO) \
! (reg_classes_intersect_p (FR_REGS, CLASS) \
! && (GET_MODE_CLASS (FROM) != GET_MODE_CLASS (TO)))
/* A C expression that defines the machine-dependent operand constraint
letters (`I', `J', `K', .. 'P') that specify particular ranges of
Index: config/mips/mips.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.h,v
retrieving revision 1.225
diff -c -p -r1.225 mips.h
*** config/mips/mips.h 6 Oct 2002 17:50:42 -0000 1.225
--- config/mips/mips.h 24 Oct 2002 19:20:47 -0000
*************** extern enum reg_class mips_char_to_class
*** 2343,2356 ****
We can't allow 64-bit float registers to change from a 32-bit
mode to a 64-bit mode. */
! #define CLASS_CANNOT_CHANGE_MODE \
! (TARGET_BIG_ENDIAN ? FP_REGS \
! : (TARGET_FLOAT64 ? HI_AND_FP_REGS : HI_REG))
!
! /* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE. */
!
! #define CLASS_CANNOT_CHANGE_MODE_P(FROM,TO) \
! (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO))
/* Stack layout; function entry, exit and calling. */
--- 2343,2353 ----
We can't allow 64-bit float registers to change from a 32-bit
mode to a 64-bit mode. */
! #define CLASS_CANNOT_CHANGE_MODE_P(CLASS, FROM, TO) \
! (((TARGET_BIG_ENDIAN && reg_classes_intersect_p (CLASS, FP_REGS)) \
! || (TARGET_FLOAT64 && reg_classes_intersect_p (CLASS, HI_AND_FP_REGS)) \
! || reg_classes_intersect_p (CLASS, HI_REG)) \
! && (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO)))
/* Stack layout; function entry, exit and calling. */
Index: config/pa/pa64-regs.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/pa/pa64-regs.h,v
retrieving revision 1.10
diff -c -p -r1.10 pa64-regs.h
*** config/pa/pa64-regs.h 4 Sep 2002 18:09:32 -0000 1.10
--- config/pa/pa64-regs.h 24 Oct 2002 19:20:47 -0000
*************** enum reg_class { NO_REGS, R1_REGS, GENER
*** 232,243 ****
{0x00000000, 0x10000000}, /* SHIFT_REGS */ \
{0xfffffffe, 0x1fffffff}} /* ALL_REGS */
! /* If defined, gives a class of registers that cannot be used as the
! operand of a SUBREG that changes the mode of the object illegally. */
!
! #define CLASS_CANNOT_CHANGE_MODE (FP_REGS)
!
! /* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE.
SImode loads to floating-point registers are not zero-extended.
The definition for LOAD_EXTEND_OP specifies that integer loads
--- 232,238 ----
{0x00000000, 0x10000000}, /* SHIFT_REGS */ \
{0xfffffffe, 0x1fffffff}} /* ALL_REGS */
! /* Defines invalid mode changes.
SImode loads to floating-point registers are not zero-extended.
The definition for LOAD_EXTEND_OP specifies that integer loads
*************** enum reg_class { NO_REGS, R1_REGS, GENER
*** 245,252 ****
we inhibit changes from SImode unless they are to a mode that is
identical in size. */
! #define CLASS_CANNOT_CHANGE_MODE_P(FROM,TO) \
! ((FROM) == SImode && GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO))
/* Return the class number of the smallest class containing
reg number REGNO. This could be a conditional expression
--- 240,248 ----
we inhibit changes from SImode unless they are to a mode that is
identical in size. */
! #define CLASS_CANNOT_CHANGE_MODE_P(CLASS, FROM, TO) \
! (reg_classes_intersect_p (CLASS, FP_REGS) \
! && (FROM) == SImode && GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO))
/* Return the class number of the smallest class containing
reg number REGNO. This could be a conditional expression
Index: config/rs6000/rs6000.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.232
diff -c -p -r1.232 rs6000.h
*** config/rs6000/rs6000.h 18 Oct 2002 00:30:23 -0000 1.232
--- config/rs6000/rs6000.h 24 Oct 2002 19:20:47 -0000
*************** enum reg_class
*** 1335,1350 ****
? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \
: ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
- /* If defined, gives a class of registers that cannot be used as the
- operand of a SUBREG that changes the mode of the object illegally. */
! #define CLASS_CANNOT_CHANGE_MODE FLOAT_REGS
! /* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE. */
- #define CLASS_CANNOT_CHANGE_MODE_P(FROM,TO) \
- (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO))
-
/* Stack layout; function entry, exit and calling. */
/* Enumeration to give which calling sequence to use. */
--- 1335,1349 ----
? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \
: ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
! /* Return 1 if a given mode change is invalid for CLASS. */
! #define CLASS_CANNOT_CHANGE_MODE_P(CLASS, FROM, TO) \
! ((reg_classes_intersect_p (CLASS, FLOAT_REGS) \
! && GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO)) \
! || (reg_classes_intersect_p (CLASS, GENERAL_REGS) \
! && (SPE_VECTOR_MODE (FROM) + SPE_VECTOR_MODE (TO)) == 1))
/* Stack layout; function entry, exit and calling. */
/* Enumeration to give which calling sequence to use. */
Index: config/s390/s390.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390.h,v
retrieving revision 1.45
diff -c -p -r1.45 s390.h
*** config/s390/s390.h 16 Oct 2002 19:09:25 -0000 1.45
--- config/s390/s390.h 24 Oct 2002 19:20:47 -0000
*************** do \
*** 391,402 ****
/* If defined, gives a class of registers that cannot be used as the
operand of a SUBREG that changes the mode of the object illegally. */
! #define CLASS_CANNOT_CHANGE_MODE FP_REGS
!
! /* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE. */
!
! #define CLASS_CANNOT_CHANGE_MODE_P(FROM,TO) \
! (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO))
/* This is an array of structures. Each structure initializes one pair
of eliminable registers. The "from" register number is given first,
--- 391,399 ----
/* If defined, gives a class of registers that cannot be used as the
operand of a SUBREG that changes the mode of the object illegally. */
! #define CLASS_CANNOT_CHANGE_MODE_P(CLASS, FROM, TO) \
! (reg_classes_intersect_p (CLASS, FP_REGS) \
! && GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO))
/* This is an array of structures. Each structure initializes one pair
of eliminable registers. The "from" register number is given first,
Index: config/sh/sh.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sh/sh.h,v
retrieving revision 1.171
diff -c -p -r1.171 sh.h
*** config/sh/sh.h 19 Sep 2002 13:17:57 -0000 1.171
--- config/sh/sh.h 24 Oct 2002 19:20:48 -0000
*************** extern const enum reg_class reg_class_fr
*** 1372,1385 ****
/* ??? We need to renumber the internal numbers for the frnn registers
when in little endian in order to allow mode size changes. */
! #define CLASS_CANNOT_CHANGE_MODE (TARGET_LITTLE_ENDIAN ? DF_REGS : DF_HI_REGS)
!
! /* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE. */
!
! #define CLASS_CANNOT_CHANGE_MODE_P(FROM,TO) \
! (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
! && ((TARGET_LITTLE_ENDIAN && GET_MODE_SIZE (TO) < 8) \
! || GET_MODE_SIZE (FROM) < 8))
/* Stack layout; function entry, exit and calling. */
--- 1372,1383 ----
/* ??? We need to renumber the internal numbers for the frnn registers
when in little endian in order to allow mode size changes. */
! #define CLASS_CANNOT_CHANGE_MODE_P(CLASS, FROM, TO) \
! (((TARGET_LITTLE_ENDIAN && reg_classes_intersect_p (CLASS, DF_REGS)) \
! || reg_classes_intersect_p (CLASS, DF_HI_REGS)) \
! && (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
! && ((TARGET_LITTLE_ENDIAN && GET_MODE_SIZE (TO) < 8) \
! || GET_MODE_SIZE (FROM) < 8)))
/* Stack layout; function entry, exit and calling. */
Index: doc/tm.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.177
diff -c -p -r1.177 tm.texi
*** doc/tm.texi 16 Oct 2002 00:40:38 -0000 1.177
--- doc/tm.texi 24 Oct 2002 19:20:48 -0000
*************** should be the maximum value of @code{HAR
*** 2561,2573 ****
This macro helps control the handling of multiple-word values
in the reload pass.
! @item CLASS_CANNOT_CHANGE_MODE
! If defined, a C expression for a class that contains registers for
! which the compiler may not change modes arbitrarily.
! @item CLASS_CANNOT_CHANGE_MODE_P(@var{from}, @var{to})
! A C expression that is true if, for a register in
! @code{CLASS_CANNOT_CHANGE_MODE}, the requested mode punning is invalid.
For the example, loading 32-bit integer or floating-point objects into
floating-point registers on the Alpha extends them to 64 bits.
--- 2561,2572 ----
This macro helps control the handling of multiple-word values
in the reload pass.
! @item CLASS_CANNOT_CHANGE_MODE_P(@var{class}, @var{from}, @var{to})
! If defined, a C expression that returns non-zero if changing a
! register of class @var{class} from mode @var{from} to mode @var{to} is
! invalid.
! This macro must return true for any class that intersects @var{class}.
For the example, loading 32-bit integer or floating-point objects into
floating-point registers on the Alpha extends them to 64 bits.