diff options
author | Stephane Carrez <Stephane.Carrez@worldnet.fr> | 2002-03-15 22:44:49 +0100 |
---|---|---|
committer | Stephane Carrez <ciceron@gcc.gnu.org> | 2002-03-15 22:44:49 +0100 |
commit | 6272bc6859f211cf4cc9b8b02f56a87a0c381834 (patch) | |
tree | 759002b68a793dc6da200bcb82381ed2d98e1098 /gcc/config | |
parent | 1d2d9def8281db63e5ea232ce2d29fccd0268ecb (diff) | |
download | gcc-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.c | 45 | ||||
-rw-r--r-- | gcc/config/m68hc11/m68hc11.h | 9 |
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 */ \ |