aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorStephane Carrez <Stephane.Carrez@worldnet.fr>2002-03-15 22:44:49 +0100
committerStephane Carrez <ciceron@gcc.gnu.org>2002-03-15 22:44:49 +0100
commit6272bc6859f211cf4cc9b8b02f56a87a0c381834 (patch)
tree759002b68a793dc6da200bcb82381ed2d98e1098 /gcc/config
parent1d2d9def8281db63e5ea232ce2d29fccd0268ecb (diff)
downloadgcc-6272bc6859f211cf4cc9b8b02f56a87a0c381834.zip
gcc-6272bc6859f211cf4cc9b8b02f56a87a0c381834.tar.gz
gcc-6272bc6859f211cf4cc9b8b02f56a87a0c381834.tar.bz2
m68hc11.c (emit_move_after_reload): Add a REG_INC note on the insn that sets the soft frame register.
* config/m68hc11/m68hc11.c (emit_move_after_reload): Add a REG_INC note on the insn that sets the soft frame register. (must_parenthesize): ix and iy are also reserved names. (print_operand_address): One more place where parenthesis are required to avoid confusion with register names. (m68hc11_gen_movhi): Allow push of stack pointer. (m68hc11_check_z_replacement): Fix handling of parallel with a clobber. (m68hc11_z_replacement): Must update the REG_INC notes to tell what the replacement register is. * config/m68hc11/m68hc11.h (REG_CLASS_CONTENTS): Switch Z_REGS and D8_REGS classes. (MODES_TIEABLE_P): All modes are tieable except QImode. From-SVN: r50837
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/m68hc11/m68hc11.c45
-rw-r--r--gcc/config/m68hc11/m68hc11.h9
2 files changed, 49 insertions, 5 deletions
diff --git a/gcc/config/m68hc11/m68hc11.c b/gcc/config/m68hc11/m68hc11.c
index 252b4e6..e9b1bb9 100644
--- a/gcc/config/m68hc11/m68hc11.c
+++ b/gcc/config/m68hc11/m68hc11.c
@@ -1520,6 +1520,17 @@ emit_move_after_reload (to, from, scratch)
XEXP (XEXP (from, 0), 0),
REG_NOTES (insn));
}
+
+ /* For 68HC11, put a REG_INC note on `sts _.frame' to prevent the cse-reg
+ to think that sp == _.frame and later replace a x = sp with x = _.frame.
+ The problem is that we are lying to gcc and use `txs' for x = sp
+ (which is not really true because txs is really x = sp + 1). */
+ else if (TARGET_M6811 && SP_REG_P (from))
+ {
+ REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC,
+ from,
+ REG_NOTES (insn));
+ }
}
int
@@ -2263,6 +2274,8 @@ must_parenthesize (op)
|| strcasecmp (name, "d") == 0
|| strcasecmp (name, "x") == 0
|| strcasecmp (name, "y") == 0
+ || strcasecmp (name, "ix") == 0
+ || strcasecmp (name, "iy") == 0
|| strcasecmp (name, "pc") == 0
|| strcasecmp (name, "sp") == 0
|| strcasecmp (name, "ccr") == 0) ? 1 : 0;
@@ -2404,7 +2417,13 @@ print_operand_address (file, addr)
}
else
{
+ need_parenthesis = must_parenthesize (offset);
+ if (need_parenthesis)
+ asm_fprintf (file, "(");
+
output_addr_const (file, offset);
+ if (need_parenthesis)
+ asm_fprintf (file, ")");
asm_fprintf (file, ",");
asm_print_register (file, REGNO (base));
}
@@ -2965,6 +2984,9 @@ m68hc11_gen_movhi (insn, operands)
case HARD_D_REGNUM:
output_asm_insn ("psh%1", operands);
break;
+ case HARD_SP_REGNUM:
+ output_asm_insn ("sts\t-2,sp", operands);
+ break;
default:
abort ();
}
@@ -4361,7 +4383,12 @@ m68hc11_check_z_replacement (insn, info)
info->must_save_reg = 0;
info->must_restore_reg = 0;
}
- info->last = NEXT_INSN (insn);
+ if (info->first != insn
+ && ((info->y_used && ix_clobber)
+ || (info->x_used && iy_clobber)))
+ info->last = insn;
+ else
+ info->last = NEXT_INSN (insn);
info->save_before_last = 1;
}
return 0;
@@ -4645,6 +4672,8 @@ m68hc11_z_replacement (insn)
if (GET_CODE (body) == SET || GET_CODE (body) == PARALLEL
|| GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == JUMP_INSN)
{
+ rtx note;
+
if (debug_m6811 && reg_mentioned_p (replace_reg, body))
{
printf ("Reg mentioned here...:\n");
@@ -4685,6 +4714,20 @@ m68hc11_z_replacement (insn)
replace_reg_qi = gen_rtx (REG, QImode, REGNO (replace_reg));
validate_replace_rtx (z_reg_qi, replace_reg_qi, insn);
}
+
+ /* If there is a REG_INC note on Z, replace it with a
+ REG_INC note on the replacement register. This is necessary
+ to make sure that the flow pass will identify the change
+ and it will not remove a possible insn that saves Z. */
+ for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
+ {
+ if (REG_NOTE_KIND (note) == REG_INC
+ && GET_CODE (XEXP (note, 0)) == REG
+ && REGNO (XEXP (note, 0)) == REGNO (z_reg))
+ {
+ XEXP (note, 0) = replace_reg;
+ }
+ }
}
if (GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == JUMP_INSN)
break;
diff --git a/gcc/config/m68hc11/m68hc11.h b/gcc/config/m68hc11/m68hc11.h
index 53f38d7..829e244 100644
--- a/gcc/config/m68hc11/m68hc11.h
+++ b/gcc/config/m68hc11/m68hc11.h
@@ -482,11 +482,12 @@ SOFT_REG_FIRST+28, SOFT_REG_FIRST+29,SOFT_REG_FIRST+30,SOFT_REG_FIRST+31
/* Value is 1 if it is a good idea to tie two pseudo registers when one has
mode MODE1 and one has mode MODE2. If HARD_REGNO_MODE_OK could produce
different values for MODE1 and MODE2, for any hard reg, then this must be
- 0 for correct output. */
+ 0 for correct output.
+
+ All modes are tieable except QImode. */
#define MODES_TIEABLE_P(MODE1, MODE2) \
(((MODE1) == (MODE2)) \
- || ((MODE1) == SImode && (MODE2) == HImode) \
- || ((MODE1) == HImode && (MODE2) == SImode))
+ || ((MODE1) != QImode && (MODE2) != QImode))
/* Define the classes of registers for register constraints in the
@@ -637,8 +638,8 @@ enum reg_class
/* SP_REGS */ { 0x00000008, 0x00000000 }, /* SP */ \
/* DA_REGS */ { 0x00000020, 0x00000000 }, /* A */ \
/* DB_REGS */ { 0x00000040, 0x00000000 }, /* B */ \
-/* D8_REGS */ { 0x00000060, 0x00000000 }, /* A B */ \
/* Z_REGS */ { 0x00000100, 0x00000000 }, /* Z */ \
+/* D8_REGS */ { 0x00000060, 0x00000000 }, /* A B */ \
/* Q_REGS */ { 0x00000062, 0x00000000 }, /* A B D */ \
/* D_OR_X_REGS */ { 0x00000003, 0x00000000 }, /* D X */ \
/* D_OR_Y_REGS */ { 0x00000006, 0x00000000 }, /* D Y */ \