m68hc11.c (m68hc11_autoinc_compatible_p): New function.
* config/m68hc11/m68hc11.c (m68hc11_autoinc_compatible_p): New function. (m68hc11_split_move): Call it to see if the source and destination operands use the same direction auto inc/dec mode, otherwise make the source an offsetable operand and generate an add. From-SVN: r51264
This commit is contained in:
parent
2e3d348133
commit
7590cfd0ca
@ -1,3 +1,10 @@
|
||||
2002-03-24 Stephane Carrez <Stephane.Carrez@worldnet.fr>
|
||||
|
||||
* config/m68hc11/m68hc11.c (m68hc11_autoinc_compatible_p): New function.
|
||||
(m68hc11_split_move): Call it to see if the source and destination
|
||||
operands use the same direction auto inc/dec mode, otherwise make the
|
||||
source an offsetable operand and generate an add.
|
||||
|
||||
2002-03-24 Stephane Carrez <Stephane.Carrez@worldnet.fr>
|
||||
|
||||
* config/m68hc11/m68hc11.md ("*subsi3_zero_extendhi"): Allow address
|
||||
|
@ -2683,6 +2683,39 @@ m68hc11_expand_compare_and_branch (code, op0, op1, label)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return 1 if the TO and FROM operands contain compatible address
|
||||
increment and decrement modes for a split_move. One of the two
|
||||
operands must not use an autoinc mode or both must go in the
|
||||
same direction. */
|
||||
static int
|
||||
m68hc11_autoinc_compatible_p (to, from)
|
||||
rtx to, from;
|
||||
{
|
||||
enum { INCOP, DECOP } type_to, type_from;
|
||||
|
||||
/* If one of them is not a MEM, it is ok. */
|
||||
if (GET_CODE (to) != MEM || GET_CODE (from) != MEM)
|
||||
return 1;
|
||||
|
||||
to = XEXP (to, 0);
|
||||
from = XEXP (from, 0);
|
||||
|
||||
if (GET_CODE (to) == PRE_INC || GET_CODE (to) == POST_INC)
|
||||
type_to = INCOP;
|
||||
else if (GET_CODE (to) == PRE_DEC || GET_CODE (to) == POST_DEC)
|
||||
type_to = DECOP;
|
||||
else
|
||||
return 1;
|
||||
|
||||
if (GET_CODE (from) == PRE_INC || GET_CODE (from) == POST_INC)
|
||||
type_from = INCOP;
|
||||
else if (GET_CODE (from) == PRE_DEC || GET_CODE (from) == POST_DEC)
|
||||
type_from = DECOP;
|
||||
else
|
||||
return 1;
|
||||
|
||||
return type_to == type_from;
|
||||
}
|
||||
|
||||
/* Split a DI, SI or HI move into several smaller move operations.
|
||||
The scratch register 'scratch' is used as a temporary to load
|
||||
@ -2704,6 +2737,30 @@ m68hc11_split_move (to, from, scratch)
|
||||
else
|
||||
mode = QImode;
|
||||
|
||||
/* If the TO and FROM contain autoinc modes that are not compatible
|
||||
together (one pop and the other a push), we must change one to
|
||||
an offsetable operand and generate an appropriate add at the end. */
|
||||
if (TARGET_M6812 && m68hc11_autoinc_compatible_p (to, from) == 0)
|
||||
{
|
||||
rtx reg;
|
||||
int code;
|
||||
|
||||
/* Decide to change the source. */
|
||||
code = GET_CODE (XEXP (from, 0));
|
||||
reg = XEXP (XEXP (from, 0), 0);
|
||||
offset = GET_MODE_SIZE (GET_MODE (from));
|
||||
if (code == PRE_DEC || code == POST_DEC)
|
||||
offset = -offset;
|
||||
|
||||
if (code == PRE_DEC || code == PRE_INC)
|
||||
emit_insn (gen_addhi3 (reg, reg, GEN_INT (offset)));
|
||||
m68hc11_split_move (to, gen_rtx_MEM (GET_MODE (from), reg), scratch);
|
||||
if (code == POST_DEC || code == POST_INC)
|
||||
emit_insn (gen_addhi3 (reg, reg, GEN_INT (offset)));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (TARGET_M6812
|
||||
&& IS_STACK_PUSH (to)
|
||||
&& reg_mentioned_p (gen_rtx (REG, HImode, HARD_SP_REGNUM), from))
|
||||
|
Loading…
Reference in New Issue
Block a user