aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2003-02-01 00:34:17 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2003-01-31 23:34:17 +0000
commitb0c42aed3116a712a4c4da3ec2f124c542271f18 (patch)
tree138fc4b6ba88f9caad65f412fbe421e92fc1dcf1 /gcc
parent1f61a15d9e3cde5dbe910c23b045f300d03f3c6f (diff)
downloadgcc-b0c42aed3116a712a4c4da3ec2f124c542271f18.zip
gcc-b0c42aed3116a712a4c4da3ec2f124c542271f18.tar.gz
gcc-b0c42aed3116a712a4c4da3ec2f124c542271f18.tar.bz2
loop.c (emit_prefetch_instructions): Do conversion at right place in RTL chain.
* loop.c (emit_prefetch_instructions): Do conversion at right place in RTL chain. * combine.c (simplify_set): Reverse order of ragumetns to REG_CANNOT_CHANGE_MODE_P * df.c (df_def_record_1): Likewise. * recog.c (register_operand): Likewise. * simplify-rtx.c (simplify_subreg): Likewise. * hard-reg-set.h (REG_CANNOT_CHANGE_MODE_P): Update use of CANNOT_CHANGE_MODE_CLASS. * regclass.c (cannot_change_mode_set_regs, invalid_mode_change_p): Likewise. * reload.c (push_reload): Likewise. * alpha.h (CANNOT_CHANGE_MODE_CLASS): Update definition. * ia64.h (CANNOT_CHANGE_MODE_CLASS): Update definition. * mips.h (CANNOT_CHANGE_MODE_CLASS): Update definition. * mips-protos.h (mips_cannot_change_mode_class): Update prototype. * mips.c (mips_cannot_change_mode_class): Update. * pa64-regs.h (CANNOT_CHANGE_MODE_CLASS): Update definition. * rs6000.h (CANNOT_CHANGE_MODE_CLASS): Update definition. * s390.h (CANNOT_CHANGE_MODE_CLASS): Update definition. * sh.h (CANNOT_CHANGE_MODE_CLASS): Update definition. * sh-protos.h (sh_cannot_change_mode_class): Update prototype. * sh.c (sh_cannot_change_mode_class): Update. * i386.h (CANNOT_CHANGE_MODE_CLASS): New. * tm.texi (CANNOT_CHANGE_MODE_CLASS): Update documentation. From-SVN: r62212
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog29
-rw-r--r--gcc/combine.c4
-rw-r--r--gcc/config/alpha/alpha.h5
-rw-r--r--gcc/config/i386/i386.c1
-rw-r--r--gcc/config/i386/i386.h14
-rw-r--r--gcc/config/ia64/ia64.h5
-rw-r--r--gcc/config/mips/mips-protos.h5
-rw-r--r--gcc/config/mips/mips.c13
-rw-r--r--gcc/config/mips/mips.h4
-rw-r--r--gcc/config/pa/pa64-regs.h4
-rw-r--r--gcc/config/rs6000/rs6000.h10
-rw-r--r--gcc/config/s390/s390.h5
-rw-r--r--gcc/config/sh/sh-protos.h4
-rw-r--r--gcc/config/sh/sh.c11
-rw-r--r--gcc/config/sh/sh.h4
-rw-r--r--gcc/df.c8
-rw-r--r--gcc/doc/tm.texi12
-rw-r--r--gcc/hard-reg-set.h4
-rw-r--r--gcc/loop.c10
-rw-r--r--gcc/recog.c2
-rw-r--r--gcc/regclass.c12
-rw-r--r--gcc/reload.c8
-rw-r--r--gcc/simplify-rtx.c2
23 files changed, 114 insertions, 62 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 009dcb1..769983a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,32 @@
+Sat Feb 1 00:28:30 CET 2003 Jan Hubicka <jh@suse.cz>
+
+ * loop.c (emit_prefetch_instructions): Do conversion at right place in
+ RTL chain.
+
+ * combine.c (simplify_set): Reverse order of ragumetns to
+ REG_CANNOT_CHANGE_MODE_P
+ * df.c (df_def_record_1): Likewise.
+ * recog.c (register_operand): Likewise.
+ * simplify-rtx.c (simplify_subreg): Likewise.
+ * hard-reg-set.h (REG_CANNOT_CHANGE_MODE_P): Update use of
+ CANNOT_CHANGE_MODE_CLASS.
+ * regclass.c (cannot_change_mode_set_regs, invalid_mode_change_p):
+ Likewise.
+ * reload.c (push_reload): Likewise.
+ * alpha.h (CANNOT_CHANGE_MODE_CLASS): Update definition.
+ * ia64.h (CANNOT_CHANGE_MODE_CLASS): Update definition.
+ * mips.h (CANNOT_CHANGE_MODE_CLASS): Update definition.
+ * mips-protos.h (mips_cannot_change_mode_class): Update prototype.
+ * mips.c (mips_cannot_change_mode_class): Update.
+ * pa64-regs.h (CANNOT_CHANGE_MODE_CLASS): Update definition.
+ * rs6000.h (CANNOT_CHANGE_MODE_CLASS): Update definition.
+ * s390.h (CANNOT_CHANGE_MODE_CLASS): Update definition.
+ * sh.h (CANNOT_CHANGE_MODE_CLASS): Update definition.
+ * sh-protos.h (sh_cannot_change_mode_class): Update prototype.
+ * sh.c (sh_cannot_change_mode_class): Update.
+ * i386.h (CANNOT_CHANGE_MODE_CLASS): New.
+ * tm.texi (CANNOT_CHANGE_MODE_CLASS): Update documentation.
+
2003-01-31 Geoffrey Keating <geoffk@apple.com>
* config/darwin.h (LINK_COMMAND_SPEC): Update for Nathan's recent
diff --git a/gcc/combine.c b/gcc/combine.c
index 90c4482..d3203fe 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -5238,8 +5238,8 @@ simplify_set (x)
#ifdef CANNOT_CHANGE_MODE_CLASS
&& ! (GET_CODE (dest) == REG && REGNO (dest) < FIRST_PSEUDO_REGISTER
&& REG_CANNOT_CHANGE_MODE_P (REGNO (dest),
- GET_MODE (src),
- GET_MODE (SUBREG_REG (src))))
+ GET_MODE (SUBREG_REG (src)),
+ GET_MODE (src)))
#endif
&& (GET_CODE (dest) == REG
|| (GET_CODE (dest) == SUBREG
diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h
index 0522ba6..8824f12 100644
--- a/gcc/config/alpha/alpha.h
+++ b/gcc/config/alpha/alpha.h
@@ -869,8 +869,9 @@ enum reg_class {
/* Return the class of registers that cannot change mode from FROM to TO. */
-#define CANNOT_CHANGE_MODE_CLASS(FROM, TO) \
- (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) ? FLOAT_REGS : NO_REGS)
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
+ (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
+ ? reg_classes_intersect_p (FLOAT_REGS, CLASS) : 0)
/* Define the cost of moving between registers of various classes. Moving
between FLOAT_REGS and anything else except float regs is expensive.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index d70054b..edf6d44 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -10153,7 +10153,6 @@ ix86_expand_int_addcc (operands)
rtx compare_op;
rtx val = const0_rtx;
bool fpcmp = false;
- rtx pat, clob;
enum machine_mode mode = GET_MODE (operands[0]);
if (operands[3] != const1_rtx
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 1e38d10..e46a19f 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -1558,6 +1558,20 @@ enum reg_class
|| ((CLASS) == SIREG) \
|| ((CLASS) == DIREG))
+/* Return a class of registers that cannot change FROM mode to TO mode.
+
+ x87 registers can't do subreg as all values are reformated to extended
+ precision. XMM registers does not support with nonzero offsets equal
+ to 4, 8 and 12 otherwise valid for integer registers. Since we can't
+ determine these, prohibit all nonparadoxical subregs changing size. */
+
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
+ (GET_MODE_SIZE (TO) < GET_MODE_SIZE (FROM) \
+ ? reg_classes_intersect_p (FLOAT_SSE_REGS, (CLASS)) \
+ || MAYBE_MMX_CLASS_P (CLASS) \
+ : GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
+ ? reg_classes_intersect_p (FLOAT_REGS, (CLASS)) : 0)
+
/* A C statement that adds to CLOBBERS any hard regs the port wishes
to automatically clobber for all asms.
diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h
index 3e1f295..835c93f 100644
--- a/gcc/config/ia64/ia64.h
+++ b/gcc/config/ia64/ia64.h
@@ -1036,8 +1036,9 @@ enum reg_class
/* 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 CANNOT_CHANGE_MODE_CLASS(FROM, TO) \
- (GET_MODE_CLASS (FROM) != GET_MODE_CLASS (TO) ? FR_REGS : NO_REGS)
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
+ (GET_MODE_CLASS (FROM) != GET_MODE_CLASS (TO) \
+ ? reg_classes_intersect_p (CLASS, FR_REGS) : 0)
/* A C expression that defines the machine-dependent operand constraint
letters (`I', `J', `K', .. 'P') that specify particular ranges of
diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h
index 902f1be..75489de 100644
--- a/gcc/config/mips/mips-protos.h
+++ b/gcc/config/mips/mips-protos.h
@@ -121,8 +121,9 @@ extern int mips_adjust_insn_length PARAMS ((rtx, int));
extern enum reg_class mips_secondary_reload_class PARAMS ((enum reg_class,
enum machine_mode,
rtx, int));
-extern enum reg_class mips_cannot_change_mode_class
- PARAMS ((enum machine_mode, enum machine_mode));
+extern bool mips_cannot_change_mode_class
+ PARAMS ((enum machine_mode, enum machine_mode,
+ enum reg_class));
extern int mips_class_max_nregs PARAMS ((enum reg_class,
enum machine_mode));
extern int mips_register_move_cost PARAMS ((enum machine_mode,
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index a6ad4c0..bcfc0f6 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -8779,19 +8779,20 @@ function_arg_pass_by_reference (cum, mode, type, named)
We can't allow 64-bit float registers to change from a 32-bit
mode to a 64-bit mode. */
-enum reg_class
-mips_cannot_change_mode_class (from, to)
+bool
+mips_cannot_change_mode_class (from, to, class)
enum machine_mode from, to;
+ enum reg_class class;
{
if (GET_MODE_SIZE (from) != GET_MODE_SIZE (to))
{
if (TARGET_BIG_ENDIAN)
- return FP_REGS;
+ return reg_classes_intersect_p (FP_REGS, class);
if (TARGET_FLOAT64)
- return HI_AND_FP_REGS;
- return HI_REG;
+ return reg_classes_intersect_p (HI_AND_FP_REGS, class);
+ return reg_classes_intersect_p (HI_REG, class);
}
- return NO_REGS;
+ return false;
}
/* This function returns the register class required for a secondary
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index 24b668b..e76a739 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -2376,8 +2376,8 @@ extern enum reg_class mips_char_to_class[256];
#define CLASS_MAX_NREGS(CLASS, MODE) mips_class_max_nregs (CLASS, MODE)
-#define CANNOT_CHANGE_MODE_CLASS(FROM, TO) \
- mips_cannot_change_mode_class (FROM, TO)
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
+ mips_cannot_change_mode_class (FROM, TO, CLASS)
/* Stack layout; function entry, exit and calling. */
diff --git a/gcc/config/pa/pa64-regs.h b/gcc/config/pa/pa64-regs.h
index 2d0ebe3..ced7df7 100644
--- a/gcc/config/pa/pa64-regs.h
+++ b/gcc/config/pa/pa64-regs.h
@@ -240,9 +240,9 @@ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FPUPPER_REGS, FP_REGS,
we inhibit changes from SImode unless they are to a mode that is
identical in size. */
-#define CANNOT_CHANGE_MODE_CLASS(FROM, TO) \
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
((FROM) == SImode && GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
- ? FP_REGS : NO_REGS)
+ ? reg_classes_intersect_p (CLASS, FP_REGS) : 0)
/* Return the class number of the smallest class containing
reg number REGNO. This could be a conditional expression
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index a96984d..7cfb3cc 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -1329,10 +1329,12 @@ enum reg_class
/* Return a class of registers that cannot change FROM mode to TO mode. */
-#define CANNOT_CHANGE_MODE_CLASS(FROM, TO) \
- (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) ? FLOAT_REGS \
- : (SPE_VECTOR_MODE (FROM) + SPE_VECTOR_MODE (TO)) == 1 ? GENERAL_REGS \
- : NO_REGS)
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
+ (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
+ ? reg_classes_intersect_p (FLOAT_REGS, CLASS) \
+ : (SPE_VECTOR_MODE (FROM) + SPE_VECTOR_MODE (TO)) == 1 \
+ ? reg_classes_intersect_p (GENERAL_REGS, CLASS) \
+ : 0)
/* Stack layout; function entry, exit and calling. */
diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h
index 1623666..3cc731c 100644
--- a/gcc/config/s390/s390.h
+++ b/gcc/config/s390/s390.h
@@ -374,8 +374,9 @@ do \
/* If a 4-byte value is loaded into a FPR, it is placed into the
*upper* half of the register, not the lower. Therefore, we
cannot use SUBREGs to switch between modes in FP registers. */
-#define CANNOT_CHANGE_MODE_CLASS(FROM, TO) \
- (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) ? FP_REGS : NO_REGS)
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
+ (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
+ ? reg_classes_intersect_p (FP_REGS, CLASS) : 0)
/* Register classes. */
diff --git a/gcc/config/sh/sh-protos.h b/gcc/config/sh/sh-protos.h
index 535fb30..f04ab01 100644
--- a/gcc/config/sh/sh-protos.h
+++ b/gcc/config/sh/sh-protos.h
@@ -123,8 +123,8 @@ extern int sh_pr_n_sets PARAMS ((void));
extern int sh_hard_regno_rename_ok PARAMS ((unsigned int, unsigned int));
extern int sh_cfun_interrupt_handler_p PARAMS ((void));
extern void sh_initialize_trampoline PARAMS ((rtx, rtx, rtx));
-extern enum reg_class sh_cannot_change_mode_class
- PARAMS ((enum machine_mode, enum machine_mode));
+extern bool sh_cannot_change_mode_class
+ PARAMS ((enum machine_mode, enum machine_mode, enum reg_class));
extern void sh_mark_label PARAMS ((rtx, int));
extern int sh_register_move_cost
PARAMS ((enum machine_mode mode, enum reg_class, enum reg_class));
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 0d83910..b1df940 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -8030,24 +8030,25 @@ sh_expand_binop_v2sf (code, op0, op1, op2)
/* Return the class of registers for which a mode change from FROM to TO
is invalid. */
-enum reg_class
-sh_cannot_change_mode_class (from, to)
+bool
+sh_cannot_change_mode_class (from, to, class)
enum machine_mode from, to;
+ enum reg_class class;
{
if (GET_MODE_SIZE (from) != GET_MODE_SIZE (to))
{
if (TARGET_LITTLE_ENDIAN)
{
if (GET_MODE_SIZE (to) < 8 || GET_MODE_SIZE (from) < 8)
- return DF_REGS;
+ return reg_classes_intersect_p (DF_REGS, class);
}
else
{
if (GET_MODE_SIZE (from) < 8)
- return DF_HI_REGS;
+ return reg_classes_intersect_p (DF_HI_REGS, class);
}
}
- return NO_REGS;
+ return 0;
}
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index cf8ac7f..25406a1 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -1395,8 +1395,8 @@ extern enum reg_class reg_class_from_letter[];
/* ??? We need to renumber the internal numbers for the frnn registers
when in little endian in order to allow mode size changes. */
-#define CANNOT_CHANGE_MODE_CLASS(FROM, TO) \
- sh_cannot_change_mode_class (FROM, TO)
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
+ sh_cannot_change_mode_class (FROM, TO, CLASS)
/* Stack layout; function entry, exit and calling. */
diff --git a/gcc/df.c b/gcc/df.c
index cce6a3c..c151249 100644
--- a/gcc/df.c
+++ b/gcc/df.c
@@ -928,8 +928,8 @@ df_def_record_1 (df, x, bb, insn)
#ifdef CLASS_CANNOT_CHANGE_MODE
if (GET_CODE (dst) == SUBREG
- && CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (dst),
- GET_MODE (SUBREG_REG (dst))))
+ && CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (SUBREG_REG (dst)),
+ GET_MODE (dst)))
flags |= DF_REF_MODE_CHANGE;
#endif
@@ -949,8 +949,8 @@ df_def_record_1 (df, x, bb, insn)
}
#ifdef CLASS_CANNOT_CHANGE_MODE
if (GET_CODE (dst) == SUBREG
- && CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (dst),
- GET_MODE (SUBREG_REG (dst))))
+ && CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (SUBREG_REG (dst)),
+ GET_MODE (dst)))
flags |= DF_REF_MODE_CHANGE;
#endif
loc = &XEXP (dst, 0);
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 382df86..b5cb240 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -2599,10 +2599,9 @@ should be the maximum value of @code{HARD_REGNO_NREGS (@var{regno},
This macro helps control the handling of multiple-word values
in the reload pass.
-@item CANNOT_CHANGE_MODE_CLASS(@var{from}, @var{to})
-If defined, a C expression that returns a register class for which
-a change from mode @var{from} to mode @var{to} is invalid, otherwise the
-macro returns @code{NO_REGS}.
+@item CANNOT_CHANGE_MODE_CLASS(@var{from}, @var{to}, @var{class})
+If defined, a C expression that returns nonzero for a @var{class} for which
+a change 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.
@@ -2612,8 +2611,9 @@ register. Therefore, @file{alpha.h} defines @code{CANNOT_CHANGE_MODE_CLASS}
as below:
@example
-#define CANNOT_CHANGE_MODE_CLASS \
- (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) ? FLOAT_REGS : NO_REGS)
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
+ (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
+ ? reg_classes_intersect_p (FLOAT_REGS, (CLASS)) : 0)
@end example
@end table
diff --git a/gcc/hard-reg-set.h b/gcc/hard-reg-set.h
index 0574738..53330cf 100644
--- a/gcc/hard-reg-set.h
+++ b/gcc/hard-reg-set.h
@@ -491,8 +491,6 @@ extern const char * reg_names[FIRST_PSEUDO_REGISTER];
/* Given a hard REGN a FROM mode and a TO mode, return nonzero if
REGN cannot change modes between the specified modes. */
#define REG_CANNOT_CHANGE_MODE_P(REGN, FROM, TO) \
- (TEST_HARD_REG_BIT \
- (reg_class_contents[(int) CANNOT_CHANGE_MODE_CLASS (FROM, TO)], \
- REGN))
+ CANNOT_CHANGE_MODE_CLASS (FROM, TO, REGNO_REG_CLASS (REGN))
#endif /* ! GCC_HARD_REG_SET_H */
diff --git a/gcc/loop.c b/gcc/loop.c
index b366b54..4bdef2d 100644
--- a/gcc/loop.c
+++ b/gcc/loop.c
@@ -4199,7 +4199,15 @@ emit_prefetch_instructions (loop)
non-constant INIT_VAL to have the same mode as REG, which
in this case we know to be Pmode. */
if (GET_MODE (init_val) != Pmode && !CONSTANT_P (init_val))
- init_val = convert_to_mode (Pmode, init_val, 0);
+ {
+ rtx seq;
+
+ start_sequence ();
+ init_val = convert_to_mode (Pmode, init_val, 0);
+ seq = get_insns ();
+ end_sequence ();
+ loop_insn_emit_before (loop, 0, loop_start, seq);
+ }
loop_iv_add_mult_emit_before (loop, init_val,
info[i].giv->mult_val,
add_val, reg, 0, loop_start);
diff --git a/gcc/recog.c b/gcc/recog.c
index d7618b9..34eaeb3 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -1088,7 +1088,7 @@ register_operand (op, mode)
#ifdef CANNOT_CHANGE_MODE_CLASS
if (GET_CODE (sub) == REG
&& REGNO (sub) < FIRST_PSEUDO_REGISTER
- && REG_CANNOT_CHANGE_MODE_P (REGNO (sub), mode, GET_MODE (sub))
+ && REG_CANNOT_CHANGE_MODE_P (REGNO (sub), GET_MODE (sub), mode)
&& GET_MODE_CLASS (GET_MODE (sub)) != MODE_COMPLEX_INT
&& GET_MODE_CLASS (GET_MODE (sub)) != MODE_COMPLEX_FLOAT)
return 0;
diff --git a/gcc/regclass.c b/gcc/regclass.c
index ea6c86b..5481ea2 100644
--- a/gcc/regclass.c
+++ b/gcc/regclass.c
@@ -2633,14 +2633,15 @@ cannot_change_mode_set_regs (used, from, regno)
unsigned int regno;
{
enum machine_mode to;
- enum reg_class class;
for (to = VOIDmode; to < MAX_MACHINE_MODE; ++to)
if (REGNO_REG_SET_P (&subregs_of_mode[to], regno))
{
- class = CANNOT_CHANGE_MODE_CLASS (from, to);
- if (class != NO_REGS)
- IOR_HARD_REG_SET (*used, reg_class_contents [(int) class]);
+ int i;
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ if (! TEST_HARD_REG_BIT (*used, i)
+ && REG_CANNOT_CHANGE_MODE_P (from, to, i))
+ SET_HARD_REG_BIT (*used, i);
}
}
@@ -2657,8 +2658,7 @@ invalid_mode_change_p (regno, class, from_mode)
for (to_mode = 0; to_mode < NUM_MACHINE_MODES; ++to_mode)
if (REGNO_REG_SET_P (&subregs_of_mode[(int) to_mode], regno)
- && reg_classes_intersect_p
- (class, CANNOT_CHANGE_MODE_CLASS (from_mode, to_mode)))
+ && CANNOT_CHANGE_MODE_CLASS (from_mode, to_mode, class))
return 1;
return 0;
}
diff --git a/gcc/reload.c b/gcc/reload.c
index a16012c..46d0d64 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -976,9 +976,7 @@ push_reload (in, out, inloc, outloc, class,
if (in != 0 && GET_CODE (in) == SUBREG
&& (subreg_lowpart_p (in) || strict_low)
#ifdef CANNOT_CHANGE_MODE_CLASS
- && !reg_classes_intersect_p
- (class, CANNOT_CHANGE_MODE_CLASS (GET_MODE (SUBREG_REG (in)),
- inmode))
+ && !CANNOT_CHANGE_MODE_CLASS (GET_MODE (SUBREG_REG (in)), inmode, class)
#endif
&& (CONSTANT_P (SUBREG_REG (in))
|| GET_CODE (SUBREG_REG (in)) == PLUS
@@ -1088,9 +1086,7 @@ push_reload (in, out, inloc, outloc, class,
if (out != 0 && GET_CODE (out) == SUBREG
&& (subreg_lowpart_p (out) || strict_low)
#ifdef CANNOT_CHANGE_MODE_CLASS
- && !reg_classes_intersect_p
- (class, CANNOT_CHANGE_MODE_CLASS (GET_MODE (SUBREG_REG (out)),
- outmode))
+ && !CANNOT_CHANGE_MODE_CLASS (GET_MODE (SUBREG_REG (out)), outmode, class)
#endif
&& (CONSTANT_P (SUBREG_REG (out))
|| strict_low
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 1cef92a..d563cae 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -2544,7 +2544,7 @@ simplify_subreg (outermode, op, innermode, byte)
|| ! rtx_equal_function_value_matters)
&& REGNO (op) < FIRST_PSEUDO_REGISTER
#ifdef CANNOT_CHANGE_MODE_CLASS
- && ! (REG_CANNOT_CHANGE_MODE_P (REGNO (op), outermode, innermode)
+ && ! (REG_CANNOT_CHANGE_MODE_P (REGNO (op), innermode, outermode)
&& GET_MODE_CLASS (innermode) != MODE_COMPLEX_INT
&& GET_MODE_CLASS (innermode) != MODE_COMPLEX_FLOAT)
#endif