predicates.md (reg_or_some_mem_operand): Do not allow the 68HC12 address indirect addressing mode as it is not supported...

* config/m68hc11/predicates.md (reg_or_some_mem_operand): Do not allow
	the 68HC12 address indirect addressing mode as it is not supported by
	bset and bclr.
	* config/m68hc11/m68hc11-protos.h (m68hc11_valid_addressing_p): Declare.
	(m68hc11_add_mode): Declare.
	* config/m68hc11/m68hc11.c (m68hc11_valid_addressing_p): Rename from
	register_indirect_p and export it.
	(m68hc11_z_replacement): Use emit_insn_after when adding the save Z
	instruction so that it is part of the good BB.
	(m68hc11_gen_movhi): Fix invalid generation of indexed indirect
	addressing with movw.
	(m68hc11_gen_movqi): Use pula and pulb instead of lda and ldb for
	68HC12.
	* config/m68hc11/m68hc11.h (ADDR_STRICT, ADDR_INCDEC, ADDR_INDEXED,
	ADDR_OFFSET, ADDR_INDIRECT, ADDR__CONST): Moved from m68hc11.c.
	* config/m68hc11/m68hc11.md ("movhi_const0"): Use this pattern only
	for 68HC11.
	("*movhi_68hc12"): Handle movhi_const0.
	("*subhi3", "subqi3"): Use general_operand for operand 1.
	("*subhi3_zext"): Likewise.

From-SVN: r99405
This commit is contained in:
Stephane Carrez 2005-05-08 21:53:42 +02:00 committed by Stephane Carrez
parent 011699d905
commit 02ee533e52
6 changed files with 147 additions and 71 deletions

View File

@ -1,3 +1,26 @@
2005-05-08 Stephane Carrez <stcarrez@nerim.fr>
* config/m68hc11/predicates.md (reg_or_some_mem_operand): Do not allow
the 68HC12 address indirect addressing mode as it is not supported by
bset and bclr.
* config/m68hc11/m68hc11-protos.h (m68hc11_valid_addressing_p): Declare.
(m68hc11_add_mode): Declare.
* config/m68hc11/m68hc11.c (m68hc11_valid_addressing_p): Rename from
register_indirect_p and export it.
(m68hc11_z_replacement): Use emit_insn_after when adding the save Z
instruction so that it is part of the good BB.
(m68hc11_gen_movhi): Fix invalid generation of indexed indirect
addressing with movw.
(m68hc11_gen_movqi): Use pula and pulb instead of lda and ldb for
68HC12.
* config/m68hc11/m68hc11.h (ADDR_STRICT, ADDR_INCDEC, ADDR_INDEXED,
ADDR_OFFSET, ADDR_INDIRECT, ADDR__CONST): Moved from m68hc11.c.
* config/m68hc11/m68hc11.md ("movhi_const0"): Use this pattern only
for 68HC11.
("*movhi_68hc12"): Handle movhi_const0.
("*subhi3", "subqi3"): Use general_operand for operand 1.
("*subhi3_zext"): Likewise.
2005-05-08 Stephane Carrez <stcarrez@nerim.fr>
PR target/19051

View File

@ -98,6 +98,7 @@ extern int memory_indexed_operand (rtx, enum machine_mode);
extern void m68hc11_split_logical (enum machine_mode, int, rtx*);
extern int m68hc11_register_indirect_p (rtx, enum machine_mode);
extern int m68hc11_valid_addressing_p (rtx, enum machine_mode, int);
extern int symbolic_memory_operand (rtx, enum machine_mode);
@ -123,6 +124,7 @@ extern int m68hc11_page0_symbol_p (rtx x);
extern HOST_WIDE_INT m68hc11_min_offset;
extern HOST_WIDE_INT m68hc11_max_offset;
extern int m68hc11_addr_mode;
#endif /* HAVE_MACHINE_MODES */
#endif /* RTX_CODE */

View File

@ -65,7 +65,6 @@ static rtx simplify_logical (enum machine_mode, int, rtx, rtx *);
static void m68hc11_emit_logical (enum machine_mode, int, rtx *);
static void m68hc11_reorg (void);
static int go_if_legitimate_address_internal (rtx, enum machine_mode, int);
static int register_indirect_p (rtx, enum machine_mode, int);
static rtx m68hc11_expand_compare (enum rtx_code, rtx, rtx);
static int must_parenthesize (rtx);
static int m68hc11_address_cost (rtx);
@ -140,13 +139,6 @@ unsigned char m68hc11_reg_valid_for_index[FIRST_PSEUDO_REGISTER];
This is 1 for 68HC11 and 0 for 68HC12. */
int m68hc11_sp_correction;
#define ADDR_STRICT 0x01 /* Accept only registers in class A_REGS */
#define ADDR_INCDEC 0x02 /* Post/Pre inc/dec */
#define ADDR_INDEXED 0x04 /* D-reg index */
#define ADDR_OFFSET 0x08
#define ADDR_INDIRECT 0x10 /* Accept (mem (mem ...)) for [n,X] */
#define ADDR_CONST 0x20 /* Accept const and symbol_ref */
int m68hc11_addr_mode;
int m68hc11_mov_addr_mode;
@ -560,8 +552,8 @@ preferred_reload_class (rtx operand, enum reg_class class)
/* Return 1 if the operand is a valid indexed addressing mode.
For 68hc11: n,r with n in [0..255] and r in A_REGS class
For 68hc12: n,r no constraint on the constant, r in A_REGS class. */
static int
register_indirect_p (rtx operand, enum machine_mode mode, int addr_mode)
int
m68hc11_valid_addressing_p (rtx operand, enum machine_mode mode, int addr_mode)
{
rtx base, offset;
@ -569,8 +561,8 @@ register_indirect_p (rtx operand, enum machine_mode mode, int addr_mode)
{
case MEM:
if ((addr_mode & ADDR_INDIRECT) && GET_MODE_SIZE (mode) <= 2)
return register_indirect_p (XEXP (operand, 0), mode,
addr_mode & (ADDR_STRICT | ADDR_OFFSET));
return m68hc11_valid_addressing_p (XEXP (operand, 0), mode,
addr_mode & (ADDR_STRICT | ADDR_OFFSET));
return 0;
case POST_INC:
@ -578,8 +570,8 @@ register_indirect_p (rtx operand, enum machine_mode mode, int addr_mode)
case POST_DEC:
case PRE_DEC:
if (addr_mode & ADDR_INCDEC)
return register_indirect_p (XEXP (operand, 0), mode,
addr_mode & ADDR_STRICT);
return m68hc11_valid_addressing_p (XEXP (operand, 0), mode,
addr_mode & ADDR_STRICT);
return 0;
case PLUS:
@ -675,7 +667,7 @@ m68hc11_small_indexed_indirect_p (rtx operand, enum machine_mode mode)
return 1;
addr_mode = m68hc11_mov_addr_mode | (reload_completed ? ADDR_STRICT : 0);
if (!register_indirect_p (operand, mode, addr_mode))
if (!m68hc11_valid_addressing_p (operand, mode, addr_mode))
return 0;
if (TARGET_M6812 && GET_CODE (operand) == PLUS
@ -730,7 +722,7 @@ m68hc11_register_indirect_p (rtx operand, enum machine_mode mode)
operand = XEXP (operand, 0);
addr_mode = m68hc11_addr_mode | (reload_completed ? ADDR_STRICT : 0);
return register_indirect_p (operand, mode, addr_mode);
return m68hc11_valid_addressing_p (operand, mode, addr_mode);
}
static int
@ -749,7 +741,7 @@ go_if_legitimate_address_internal (rtx operand, enum machine_mode mode,
return 1;
}
addr_mode = m68hc11_addr_mode | (strict ? ADDR_STRICT : 0);
if (register_indirect_p (operand, mode, addr_mode))
if (m68hc11_valid_addressing_p (operand, mode, addr_mode))
{
return 1;
}
@ -995,7 +987,7 @@ m68hc11_indirect_p (rtx operand, enum machine_mode mode)
operand = XEXP (operand, 0);
addr_mode = m68hc11_addr_mode | (reload_completed ? ADDR_STRICT : 0);
return register_indirect_p (operand, mode, addr_mode);
return m68hc11_valid_addressing_p (operand, mode, addr_mode);
}
return 0;
}
@ -3110,10 +3102,13 @@ m68hc11_gen_movhi (rtx insn, rtx *operands)
if (TARGET_M6812)
{
if (IS_STACK_PUSH (operands[0]) && H_REG_P (operands[1]))
rtx from = operands[1];
rtx to = operands[0];
if (IS_STACK_PUSH (to) && H_REG_P (from))
{
cc_status = cc_prev_status;
switch (REGNO (operands[1]))
switch (REGNO (from))
{
case HARD_X_REGNUM:
case HARD_Y_REGNUM:
@ -3128,10 +3123,10 @@ m68hc11_gen_movhi (rtx insn, rtx *operands)
}
return;
}
if (IS_STACK_POP (operands[1]) && H_REG_P (operands[0]))
if (IS_STACK_POP (from) && H_REG_P (to))
{
cc_status = cc_prev_status;
switch (REGNO (operands[0]))
switch (REGNO (to))
{
case HARD_X_REGNUM:
case HARD_Y_REGNUM:
@ -3162,11 +3157,52 @@ m68hc11_gen_movhi (rtx insn, rtx *operands)
else
output_asm_insn ("st%1\t%0", operands);
}
/* The 68hc12 does not support (MEM:HI (MEM:HI)) with the movw
instruction. We have to use a scratch register as temporary location.
Trying to use a specific pattern or constrain failed. */
else if (GET_CODE (to) == MEM && GET_CODE (XEXP (to, 0)) == MEM)
{
rtx ops[4];
ops[0] = to;
ops[2] = from;
ops[3] = 0;
if (dead_register_here (insn, d_reg))
ops[1] = d_reg;
else if (dead_register_here (insn, ix_reg))
ops[1] = ix_reg;
else if (dead_register_here (insn, iy_reg))
ops[1] = iy_reg;
else
{
ops[1] = d_reg;
ops[3] = d_reg;
output_asm_insn ("psh%3", ops);
}
ops[0] = to;
ops[2] = from;
output_asm_insn ("ld%1\t%2", ops);
output_asm_insn ("st%1\t%0", ops);
if (ops[3])
output_asm_insn ("pul%3", ops);
}
/* Use movw for non-null constants or when we are clearing
a volatile memory reference. However, this is possible
only if the memory reference has a small offset or is an
absolute address. */
else if (GET_CODE (from) == CONST_INT
&& INTVAL (from) == 0
&& (MEM_VOLATILE_P (to) == 0
|| m68hc11_small_indexed_indirect_p (to, HImode) == 0))
{
output_asm_insn ("clr\t%h0", operands);
output_asm_insn ("clr\t%b0", operands);
}
else
{
rtx from = operands[1];
rtx to = operands[0];
if ((m68hc11_register_indirect_p (from, GET_MODE (from))
&& !m68hc11_small_indexed_indirect_p (from, GET_MODE (from)))
|| (m68hc11_register_indirect_p (to, GET_MODE (to))
@ -3183,6 +3219,7 @@ m68hc11_gen_movhi (rtx insn, rtx *operands)
ops[0] = to;
ops[1] = operands[2];
m68hc11_gen_movhi (insn, ops);
return;
}
else
{
@ -3190,19 +3227,11 @@ m68hc11_gen_movhi (rtx insn, rtx *operands)
fatal_insn ("move insn not handled", insn);
}
}
else
{
if (GET_CODE (from) == CONST_INT && INTVAL (from) == 0)
{
output_asm_insn ("clr\t%h0", operands);
output_asm_insn ("clr\t%b0", operands);
}
else
{
m68hc11_notice_keep_cc (operands[0]);
output_asm_insn ("movw\t%1,%0", operands);
}
}
else
{
m68hc11_notice_keep_cc (operands[0]);
output_asm_insn ("movw\t%1,%0", operands);
}
}
return;
}
@ -3530,8 +3559,10 @@ m68hc11_gen_movqi (rtx insn, rtx *operands)
}
else if (H_REG_P (operands[0]))
{
if (Q_REG_P (operands[0]))
output_asm_insn ("lda%0\t%b1", operands);
if (IS_STACK_POP (operands[1]))
output_asm_insn ("pul%b0", operands);
else if (Q_REG_P (operands[0]))
output_asm_insn ("lda%0\t%b1", operands);
else if (D_REG_P (operands[0]))
output_asm_insn ("ldab\t%b1", operands);
else

View File

@ -1037,6 +1037,13 @@ typedef struct m68hc11_args
/* Addressing modes, and classification of registers for them. */
#define ADDR_STRICT 0x01 /* Accept only registers in class A_REGS */
#define ADDR_INCDEC 0x02 /* Post/Pre inc/dec */
#define ADDR_INDEXED 0x04 /* D-reg index */
#define ADDR_OFFSET 0x08
#define ADDR_INDIRECT 0x10 /* Accept (mem (mem ...)) for [n,X] */
#define ADDR_CONST 0x20 /* Accept const and symbol_ref */
/* The 68HC12 has all the post/pre increment/decrement modes. */
#define HAVE_POST_INCREMENT (TARGET_M6812 && TARGET_AUTO_INC_DEC)
#define HAVE_PRE_INCREMENT (TARGET_M6812 && TARGET_AUTO_INC_DEC)

View File

@ -689,8 +689,8 @@
DONE;")
(define_insn_and_split "movdf_internal"
[(set (match_operand:DF 0 "non_push_operand" "=mu,U,!u,U,m,m,!u")
(match_operand:DF 1 "general_operand" "G,iU,iU,!u,mi,!u,!mu"))
[(set (match_operand:DF 0 "non_push_operand" "=mu,U,m,!u,U,m,!u")
(match_operand:DF 1 "general_operand" "G,iU,mi,iU,!u,!u,!mu"))
(clobber (match_scratch:HI 2 "=X,&d,&d,&d,&d,&d,&d"))]
""
"#"
@ -886,18 +886,9 @@
}
}")
(define_insn "movhi_const0"
[(set (match_operand:HI 0 "splitable_operand" "=d,A,um")
(const_int 0))]
""
"@
clra\\n\\tclrb
ld%0\\t#0
clr\\t%b0\\n\\tclr\\t%h0")
(define_insn "*movhi_68hc12"
[(set (match_operand:HI 0 "nonimmediate_operand" "=U,dAw,dAw,U,U,m,!u")
(match_operand:HI 1 "general_operand" "U,dAwim,!u,dAwi,!u,dAw,riU"))]
[(set (match_operand:HI 0 "nonimmediate_operand" "=U,dAw,dAw,m,U,U,m,!u")
(match_operand:HI 1 "general_operand" "U,dAwim,!u,K,dAwi,!u,dAw,riU"))]
"TARGET_M6812"
"*
{
@ -905,6 +896,15 @@
return \"\";
}")
(define_insn "movhi_const0"
[(set (match_operand:HI 0 "nonimmediate_operand" "=d,A,um")
(const_int 0))]
"TARGET_M6811"
"@
clra\\n\\tclrb
ld%0\\t#0
clr\\t%b0\\n\\tclr\\t%h0")
(define_insn "*movhi_m68hc11"
[(set (match_operand:HI 0 "nonimmediate_operand" "=dAw,!u,m,m,dAw,!*u")
(match_operand:HI 1 "general_operand" "dAwim,dAw,dA,?Aw,!*u,dAw"))]
@ -1237,7 +1237,7 @@
[(set (match_operand:DI 0 "nonimmediate_operand" "=m,m,!u,!u")
(zero_extend:DI
(match_operand:SI 1 "nonimmediate_operand" "m,Du,m,Du")))
(clobber (match_scratch:HI 2 "=d,d,&d,d"))]
(clobber (match_scratch:HI 2 "=d,d,d,d"))]
""
"#")
@ -2382,7 +2382,7 @@
[(set (match_operand:HI 0 "hard_reg_operand" "=A,d")
(plus:HI (zero_extend:HI
(match_operand:QI 1 "nonimmediate_operand" "d,um*A"))
(match_operand:HI 2 "hard_reg_operand" "0,0")))]
(match_operand:HI 2 "general_operand" "0,0")))]
""
"*
{
@ -2716,7 +2716,7 @@
(define_insn "*subhi3"
[(set (match_operand:HI 0 "register_operand" "=d,*A,d,*A")
(minus:HI (match_operand:HI 1 "register_operand" "0,0,0,0")
(minus:HI (match_operand:HI 1 "general_operand" "0,0,0,0")
(match_operand:HI 2 "general_operand" "im*A*d,im*d*A,u,!u")))]
""
"*
@ -2731,7 +2731,7 @@
(define_insn "*subhi3_zext"
[(set (match_operand:HI 0 "hard_reg_operand" "=d,d")
(minus:HI (match_operand:HI 1 "hard_reg_operand" "0,0")
(minus:HI (match_operand:HI 1 "general_operand" "0,0")
(zero_extend:HI (match_operand:QI 2 "general_operand" "mi*A,!u"))))]
""
"*
@ -2751,7 +2751,7 @@
(define_insn "subqi3"
[(set (match_operand:QI 0 "hard_reg_operand" "=dq,!*x*y")
(minus:QI (match_operand:QI 1 "hard_reg_operand" "0,0")
(minus:QI (match_operand:QI 1 "general_operand" "0,0")
(match_operand:QI 2 "general_operand" "uim*A*d,uim*A*d")))]
""
"*
@ -3326,8 +3326,8 @@
(define_insn "*andqi3_gen"
[(set (match_operand:QI 0 "register_operand" "=d,d,d,?*A,?*A,!*q")
(and:QI (match_operand:QI 1 "register_operand" "%0,0,0,0,0,0")
(match_operand:QI 2 "general_operand" "mi,!u,?*A,!um,?*A*d,!um*A")))]
(and:QI (match_operand:QI 1 "general_operand" "%0,0,0,0,0,0")
(match_operand:QI 2 "general_operand" "mi,!*u,?*A,!*um,?*A*d,!*um*A")))]
""
"*
{
@ -3544,8 +3544,8 @@
(define_insn "*iorqi3_gen"
[(set (match_operand:QI 0 "register_operand" "=d,d,d,?*A,?*A,!*q")
(ior:QI (match_operand:QI 1 "register_operand" "%0,0,0,0,0,0")
(match_operand:QI 2 "general_operand" "mi,!u,!*A,!um,?*A*d,!um*A")))]
(ior:QI (match_operand:QI 1 "general_operand" "%0,0,0,0,0,0")
(match_operand:QI 2 "general_operand" "mi,!*u,!*A,!*um,?*A*d,!*um*A")))]
""
"*
{
@ -3636,8 +3636,8 @@
(define_insn "xorqi3"
[(set (match_operand:QI 0 "register_operand" "=d,d,d,?*A,?*A,!*q")
(xor:QI (match_operand:QI 1 "register_operand" "%0,0,0,0,0,0")
(match_operand:QI 2 "general_operand" "im,!u,!*A,!ium,?*A*d,!ium*A")))]
(xor:QI (match_operand:QI 1 "general_operand" "%0,0,0,0,0,0")
(match_operand:QI 2 "general_operand" "im,!*u,!*A,!i*um,?*A*d,!i*um*A")))]
""
"*
{
@ -6914,14 +6914,16 @@
;;
;; Replace "leas 2,sp" with a "pulx" or a "puly".
;; On 68HC12, this is one cycle slower but one byte smaller.
;; pr target/6899: This peephole is not valid because a register CSE
;; pass removes the pulx/puly.
;; pr target/6899: This peephole was not valid because a register CSE
;; pass removes the pulx/puly. The 'use' clause ensure that the pulx is
;; not removed.
;;
(define_peephole2
[(set (reg:HI SP_REGNUM) (plus:HI (reg:HI SP_REGNUM) (const_int 2)))
(match_scratch:HI 0 "xy")]
"0 && TARGET_M6812 && optimize_size"
[(set (match_dup 0) (match_dup 1))]
"TARGET_M6812 && optimize_size"
[(set (match_dup 0) (match_dup 1))
(use (match_dup 0))]
"operands[1] = gen_rtx_MEM (HImode,
gen_rtx_POST_INC (HImode,
gen_rtx_REG (HImode, HARD_SP_REGNUM)));")

View File

@ -173,6 +173,7 @@
if (GET_CODE (op) == MEM)
{
rtx op0 = XEXP (op, 0);
int addr_mode;
if (symbolic_memory_operand (op0, mode))
return 1;
@ -180,10 +181,20 @@
if (IS_STACK_PUSH (op))
return 1;
if (m68hc11_register_indirect_p (op, mode))
return 1;
if (GET_CODE (op) == REG && reload_in_progress
&& REGNO (op) >= FIRST_PSEUDO_REGISTER
&& reg_equiv_memory_loc[REGNO (op)])
{
op = reg_equiv_memory_loc[REGNO (op)];
op = eliminate_regs (op, 0, NULL_RTX);
}
if (GET_CODE (op) != MEM)
return 0;
return 0;
op0 = XEXP (op, 0);
addr_mode = m68hc11_addr_mode | (reload_completed ? ADDR_STRICT : 0);
addr_mode &= ~ADDR_INDIRECT;
return m68hc11_valid_addressing_p (op0, mode, addr_mode);
}
return register_operand (op, mode);