m68hc11-protos.h (ix_reg): Declare.

* config/m68hc11/m68hc11-protos.h (ix_reg): Declare.
	* config/m68hc11/m68hc11.md ("addsi3"): Use general_operand for sources.
	(splits): Remove unused add splits.
	("*addhi3_68hc12"): Tune constraints.
	("addhi_sp"): Try to use X instead of Y in all cases and if the
	constant fits in 8-bits and D is dead use abx/aby instructions.
	("*addhi3"): Remove extern declaration of ix_reg.
	("*subsi3"): Optimize and provide new split.
	("subhi3"): Cleanup.
	("*subhi3_sp"): Avoid saving X if we know it is dead.
	(arith splits): For 68hc12 save the address register on the stack
	and do the arithmetic operation with a pop.

From-SVN: r50880
This commit is contained in:
Stephane Carrez 2002-03-16 13:52:20 +01:00 committed by Stephane Carrez
parent 3c9a5efec9
commit 840e2ff109
3 changed files with 134 additions and 110 deletions

View file

@ -1,3 +1,18 @@
2002-03-16 Stephane Carrez <Stephane.Carrez@worldnet.fr>
* config/m68hc11/m68hc11-protos.h (ix_reg): Declare.
* config/m68hc11/m68hc11.md ("addsi3"): Use general_operand for sources.
(splits): Remove unused add splits.
("*addhi3_68hc12"): Tune constraints.
("addhi_sp"): Try to use X instead of Y in all cases and if the
constant fits in 8-bits and D is dead use abx/aby instructions.
("*addhi3"): Remove extern declaration of ix_reg.
("*subsi3"): Optimize and provide new split.
("subhi3"): Cleanup.
("*subhi3_sp"): Avoid saving X if we know it is dead.
(arith splits): For 68hc12 save the address register on the stack
and do the arithmetic operation with a pop.
2002-03-16 Stephane Carrez <Stephane.Carrez@worldnet.fr>
* config/m68hc11/m68hc11.md ("*movqi_68hc12"): Fix constraints, avoid

View file

@ -49,6 +49,7 @@ extern rtx m68hc11_compare_op0;
extern rtx m68hc11_compare_op1;
extern rtx m68hc11_soft_tmp_reg;
extern rtx iy_reg;
extern rtx ix_reg;
extern rtx d_reg;
extern void m68hc11_initialize_trampoline PARAMS((rtx, rtx, rtx));

View file

@ -1418,7 +1418,6 @@
""
"*
{
extern rtx ix_reg;
rtx ops[3];
int need_tst = 0;
@ -1598,7 +1597,6 @@
""
"*
{
extern rtx ix_reg;
rtx ops[2];
int x_reg_used;
@ -1765,35 +1763,12 @@
;;
(define_expand "addsi3"
[(parallel [(set (match_operand:SI 0 "register_operand" "")
(plus:SI (match_operand:SI 1 "register_operand" "")
(plus:SI (match_operand:SI 1 "general_operand" "")
(match_operand:SI 2 "general_operand" "")))
(clobber (match_scratch:HI 3 ""))])]
""
"")
;;
;; Translate D = D + D into D = D << 1
;; We have to do this because adding a register to itself is not possible.
;;
;; Manipulation of A and B registers directly confuses the cse-regs pass
;; so the split must be made after z-replacement register.
;;
(define_split
[(set (match_operand:SI 0 "register_operand" "=D")
(plus:SI (match_dup 0)
(match_dup 0)))
(clobber (match_scratch:HI 1 "=X"))]
"reload_completed && z_replacement_completed == 2"
[(set (reg:HI D_REGNUM) (ashift:HI (reg:HI D_REGNUM) (const_int 1)))
(parallel [(set (reg:HI D_REGNUM) (reg:HI X_REGNUM))
(set (reg:HI X_REGNUM) (reg:HI D_REGNUM))])
(set (reg:QI B_REGNUM) (rotate:QI (reg:QI B_REGNUM) (reg:QI CC_REGNUM)))
(set (reg:QI A_REGNUM) (rotate:QI (reg:QI A_REGNUM) (reg:QI CC_REGNUM)))
(parallel [(set (reg:HI D_REGNUM) (reg:HI X_REGNUM))
(set (reg:HI X_REGNUM) (reg:HI D_REGNUM))])]
"")
(define_insn "*addsi3_zero_extendhi"
[(set (match_operand:SI 0 "register_operand" "=D,D,D,D")
(plus:SI (zero_extend:SI
@ -2113,36 +2088,17 @@
}
}")
(define_split /* "*addhi3_strict_low_part" */
[(set (strict_low_part (match_operand:QI 0 "register_operand" "+dxy"))
(plus:QI (match_operand:QI 1 "register_operand" "")
(match_operand:QI 2 "general_operand" "")))]
"0 && z_replacement_completed == 2"
[(set (match_dup 0)
(plus:QI (match_dup 1) (match_dup 2)))]
"")
(define_split /* "*addhi3_strict_low_part" */
[(set (match_operand:HI 0 "register_operand" "=dA")
(plus:HI (match_operand:HI 1 "register_operand" "%0")
(match_operand:HI 2 "general_operand" "")))
(clobber (match_scratch:HI 3 ""))]
"0 && z_replacement_completed == 2 && !SP_REG_P (operands[0])"
[(set (match_dup 0)
(plus:HI (match_dup 1) (match_dup 2)))]
"")
(define_insn "*addhi3_68hc12"
[(set (match_operand:HI 0 "register_operand" "=*d,A*w,A*w,A")
(plus:HI (match_operand:HI 1 "register_operand" "%0,0,Aw,0")
(match_operand:HI 2 "general_operand" "imA*wu,id,id,!muA")))]
[(set (match_operand:HI 0 "register_operand" "=xy,d,xy*z*w,xy*z*w,xy*z")
(plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,xy*zw,0")
(match_operand:HI 2 "general_operand" "N,im*A*wu,id,id,!mu*A")))]
"TARGET_M6812"
"*
{
int val;
const char* insn_code;
if (which_alternative >= 3)
if (which_alternative >= 4)
{
if (A_REG_P (operands[2]))
{
@ -2183,7 +2139,7 @@
else
val = 1000;
if (val != -1 || val != 1 || !rtx_equal_p (operands[0], operands[1]))
if ((val != -1 && val != 1) || !rtx_equal_p (operands[0], operands[1]))
{
m68hc11_notice_keep_cc (operands[0]);
switch (REGNO (operands[0]))
@ -2256,14 +2212,15 @@
{
HOST_WIDE_INT val;
if (optimize && Y_REG_P (operands[3])
&& dead_register_here (insn, gen_rtx (REG, HImode, HARD_X_REGNUM)))
operands[3] = gen_rtx (REG, HImode, HARD_X_REGNUM);
if (GET_CODE (operands[2]) == CONST_INT
&& (val = INTVAL (operands[2])) != 0
&& (CONST_OK_FOR_LETTER_P (val, 'P')
|| (val > 0 && val <= 8)))
{
if (optimize && Y_REG_P (operands[3])
&& dead_register_here (insn, gen_rtx (REG, HImode, HARD_X_REGNUM)))
operands[3] = gen_rtx (REG, HImode, HARD_X_REGNUM);
while (val > 1 || val < -1)
{
if (val > 0)
@ -2297,31 +2254,29 @@
return \"\";
}
/* Need to transfer to SP to IY and then to D register.
Register IY is lost, this is specified by the (clobber) statement. */
/* Need to transfer to SP to X/Y and then to D register.
Register X/Y is lost, this is specified by the (clobber) statement. */
output_asm_insn (\"ts%3\", operands);
output_asm_insn (\"xgd%3\", operands);
output_asm_insn (\"addd\\t%2\", operands);
output_asm_insn (\"xgd%3\", operands);
if (GET_CODE (operands[2]) == CONST_INT
&& ((val = INTVAL (operands[2]) >= 0 && val < 0x100))
&& dead_register_here (insn, gen_rtx (REG, HImode, HARD_D_REGNUM)))
{
output_asm_insn (\"ldab\\t%2\", operands);
output_asm_insn (\"ab%3\", operands);
CC_STATUS_INIT;
}
else
{
output_asm_insn (\"xgd%3\", operands);
output_asm_insn (\"addd\\t%2\", operands);
output_asm_insn (\"xgd%3\", operands);
}
/* The status flags correspond to the addd. xgdy and tys do not
modify the flags. */
return \"t%3s\";
}")
;;
;; Translate d = d + d into d = d << 1
;; We have to do this because adding a register to itself is not possible.
;; ??? It's not clear whether this is really necessary.
;;
(define_split
[(set (match_operand:HI 0 "hard_reg_operand" "=dA")
(plus:HI (match_dup 0)
(match_dup 0)))]
"reload_completed"
[(set (match_dup 0) (ashift:HI (match_dup 0) (const_int 1)))]
"")
(define_insn "*addhi3"
[(set (match_operand:HI 0 "hard_reg_operand" "=A,d,!A,d*A,!d*A")
(plus:HI (match_operand:HI 1 "general_operand" "%0,0,0,0,0")
@ -2331,7 +2286,6 @@
{
const char* insn_code;
int val;
extern rtx ix_reg;
if (D_REG_P (operands[0]) && SP_REG_P (operands[2]))
{
@ -2545,10 +2499,10 @@
"")
(define_insn "*subsi3"
[(set (match_operand:SI 0 "register_operand" "=D,D")
(minus:SI (match_operand:SI 1 "general_operand" "0,!mui")
(match_operand:SI 2 "general_operand" "!mui,!D")))
(clobber (match_scratch:HI 3 "=X,X"))]
[(set (match_operand:SI 0 "register_operand" "=D,D,D,D,!u")
(minus:SI (match_operand:SI 1 "general_operand" "0,mi,0,!u,0")
(match_operand:SI 2 "general_operand" "mi,D,!u,D,!mui")))
(clobber (match_scratch:HI 3 "=X,X,X,X,d"))]
""
"#")
@ -2634,6 +2588,27 @@
operands[5] = m68hc11_gen_highpart (QImode, operands[4]);
operands[4] = m68hc11_gen_lowpart (QImode, operands[4]);")
(define_split /* "*subsi3" */
[(set (match_operand:SI 0 "nonimmediate_operand" "=u")
(minus:SI (match_operand:SI 1 "general_operand" "0")
(match_operand:SI 2 "general_operand" "mui")))
(clobber (match_scratch:HI 3 "=d"))]
"reload_completed && z_replacement_completed == 2
&& !X_REG_P (operands[0])"
[(set (match_dup 3) (match_dup 4))
(set (match_dup 3) (minus:HI (match_dup 3) (match_dup 5)))
(set (match_dup 4) (match_dup 3))
(set (match_dup 3) (match_dup 6))
(set (reg:QI 6) (minus:QI (minus:QI (reg:QI 7) (reg:QI 6)) (match_dup 7)))
(set (reg:QI 5) (minus:QI (minus:QI (reg:QI 7) (reg:QI 5)) (match_dup 8)))
(set (match_dup 6) (match_dup 3))]
"operands[4] = m68hc11_gen_lowpart (HImode, operands[1]);
operands[5] = m68hc11_gen_lowpart (HImode, operands[2]);
operands[6] = m68hc11_gen_highpart (HImode, operands[1]);
operands[7] = m68hc11_gen_highpart (HImode, operands[2]);
operands[8] = m68hc11_gen_highpart (QImode, operands[7]);
operands[7] = m68hc11_gen_lowpart (QImode, operands[7]);")
;;
;; - 16-bit Subtract.
;;
@ -2642,20 +2617,7 @@
(minus:HI (match_operand:HI 1 "register_operand" "0")
(match_operand:HI 2 "general_operand" "g")))]
""
"
{
if (TARGET_M6811 && SP_REG_P (operands[0]))
{
emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
gen_rtx (SET, VOIDmode,
operand0,
gen_rtx (MINUS, HImode,
operand1, operand2)),
gen_rtx (CLOBBER, VOIDmode,
gen_rtx (SCRATCH, HImode, 0)))));
DONE;
}
}")
"")
;;
;; Subtract from stack. This is better if we provide a pattern.
@ -2686,7 +2648,11 @@
if (D_REG_P (operands[3]))
{
output_asm_insn (\"xgdx\", operands);
int save_x;
save_x = !dead_register_here (insn, ix_reg);
if (save_x)
output_asm_insn (\"xgdx\", operands);
output_asm_insn (\"tsx\", operands);
output_asm_insn (\"xgdx\", operands);
output_asm_insn (\"subd\\t%2\", operands);
@ -2695,7 +2661,10 @@
/* The status flags correspond to the addd. xgdx/y and tx/ys do not
modify the flags. */
output_asm_insn (\"txs\", operands);
return \"xgdx\";
if (save_x)
return \"xgdx\";
else
return \"\";
}
/* Need to transfer to SP to X,Y and then to D register.
@ -4014,17 +3983,39 @@
(match_operator:HI 3 "m68hc11_non_shift_operator"
[(match_operand:HI 1 "d_register_operand" "%0")
(match_operand:HI 2 "hard_reg_operand" "*d*A")]))]
"z_replacement_completed == 2 && !SP_REG_P (operands[2])"
"TARGET_M6811
&& z_replacement_completed == 2 && !SP_REG_P (operands[2])"
[(set (match_dup 4) (match_dup 2))
(set (match_dup 0) (match_op_dup 3 [(match_dup 0) (match_dup 4)]))]
"operands[4] = gen_rtx (REG, HImode, SOFT_TMP_REGNUM);")
;;
;; For 68HC12, push the operand[2] value on the stack and do the
;; logical/arithmetic operation with a pop.
;;
(define_split
[(set (match_operand:HI 0 "d_register_operand" "=d")
(match_operator:HI 3 "m68hc11_non_shift_operator"
[(match_operand:HI 1 "d_register_operand" "%0")
(match_operand:HI 2 "hard_reg_operand" "*d*A")]))]
"TARGET_M6812
&& z_replacement_completed == 2 && !SP_REG_P (operands[2])"
[(set (match_dup 4) (match_dup 2))
(set (match_dup 0) (match_op_dup 3 [(match_dup 0) (match_dup 5)]))]
"operands[4] = gen_rtx (MEM, HImode,
gen_rtx (PRE_DEC, HImode,
gen_rtx (REG, HImode, HARD_SP_REGNUM)));
operands[5] = gen_rtx (MEM, HImode,
gen_rtx (POST_INC, HImode,
gen_rtx (REG, HImode, HARD_SP_REGNUM)));
")
;;--------------------------------------------------------------------
;; 16-bit Unary operations on X and Y:
;;
;; NOT NEG
;;
;; Operations on X or Y registers are split here. Instructions are
;; Operations on X or Y registers are split here. Instructions are
;; changed into:
;; - xgdx/xgdy instruction pattern,
;; - The same operation on register D,
@ -4038,9 +4029,9 @@
;; (set (REG:HI X) (PLUS:HI (REG:HI X) (REG:HI X)))
;;
(define_split
[(set (match_operand:HI 0 "hard_addr_reg_operand" "=A")
[(set (match_operand:HI 0 "hard_addr_reg_operand" "")
(match_operator:HI 2 "m68hc11_unary_operator"
[(match_operand 1 "general_operand" "uim*d*A")]))]
[(match_operand 1 "general_operand" "")]))]
"z_replacement_completed == 2"
[(set (match_dup 4) (match_dup 5))
(parallel [(set (reg:HI D_REGNUM) (match_dup 0))
@ -4135,10 +4126,10 @@
;; The shift operators are special and must not appear here.
;;
(define_split
[(set (match_operand:QI 0 "d_register_operand" "=d")
[(set (match_operand:QI 0 "d_register_operand" "")
(match_operator:QI 3 "m68hc11_non_shift_operator"
[(match_operand:QI 1 "d_register_operand" "%0")
(match_operand:QI 2 "hard_reg_operand" "*d*x*y")]))]
[(match_operand:QI 1 "d_register_operand" "")
(match_operand:QI 2 "hard_reg_operand" "")]))]
"reload_completed"
[(set (match_dup 5) (match_dup 6))
(set (match_dup 0) (match_op_dup 3 [(match_dup 0) (match_dup 4)]))]
@ -4151,7 +4142,7 @@
;;
;; NOT NEG
;;
;; Operations on X or Y registers are split here. Instructions are
;; Operations on X or Y registers are split here. Instructions are
;; changed into:
;; - xgdx/xgdy instruction pattern,
;; - The same operation on register D,
@ -4165,9 +4156,9 @@
;; (set (REG:HI X) (PLUS:HI (REG:HI X) (REG:HI X)))
;;
(define_split
[(set (match_operand:QI 0 "hard_addr_reg_operand" "=xy")
[(set (match_operand:QI 0 "hard_addr_reg_operand" "")
(match_operator:QI 2 "m68hc11_unary_operator"
[(match_operand:QI 1 "general_operand" "uim*d*x*y")]))]
[(match_operand:QI 1 "general_operand" "")]))]
"z_replacement_completed == 2"
[(set (match_dup 4) (match_dup 5))
(parallel [(set (reg:HI D_REGNUM) (match_dup 3))
@ -4420,23 +4411,40 @@
operands[8] = m68hc11_gen_lowpart (HImode, operands[8]);")
(define_insn "addsi_silshr16"
[(set (match_operand:SI 0 "register_operand" "=D")
(plus:SI (lshiftrt:SI (match_operand:SI 1 "general_operand" "uim")
[(set (match_operand:SI 0 "register_operand" "=D,D")
(plus:SI (lshiftrt:SI (match_operand:SI 1 "general_operand" "!*uim,0")
(const_int 16))
(match_operand:SI 2 "general_operand" "0")))]
(match_operand:SI 2 "general_operand" "0,m!*u")))]
""
"#")
(define_split
[(set (match_operand:SI 0 "register_operand" "=D")
(plus:SI (lshiftrt:SI (match_operand:SI 1 "general_operand" "uim")
[(set (match_operand:SI 0 "register_operand" "")
(plus:SI (lshiftrt:SI (match_operand:SI 1 "general_operand" "")
(const_int 16))
(match_operand:SI 2 "general_operand" "0")))]
"z_replacement_completed == 2"
(match_operand:SI 2 "general_operand" "")))]
"z_replacement_completed == 2 && !X_REG_P (operands[1])"
[(set (reg:HI D_REGNUM) (plus:HI (reg:HI D_REGNUM) (match_dup 3)))
(set (reg:HI X_REGNUM) (plus:HI (plus:HI (reg:HI X_REGNUM) (const_int 0)) (reg:HI CC_REGNUM)))]
(set (reg:HI X_REGNUM) (plus:HI (plus:HI (reg:HI X_REGNUM)
(const_int 0))
(reg:HI CC_REGNUM)))]
"operands[3] = m68hc11_gen_highpart (HImode, operands[1]);")
(define_split
[(set (match_operand:SI 0 "register_operand" "")
(plus:SI (lshiftrt:SI (match_operand:SI 1 "general_operand" "")
(const_int 16))
(match_operand:SI 2 "general_operand" "")))]
"z_replacement_completed == 2 && X_REG_P (operands[1])"
[(set (reg:HI D_REGNUM) (reg:HI X_REGNUM))
(set (reg:HI X_REGNUM) (match_dup 3))
(set (reg:HI D_REGNUM) (plus:HI (reg:HI D_REGNUM) (match_dup 4)))
(set (reg:HI X_REGNUM) (plus:HI (plus:HI (reg:HI X_REGNUM)
(const_int 0))
(reg:HI CC_REGNUM)))]
"operands[3] = m68hc11_gen_highpart (HImode, operands[2]);
operands[4] = m68hc11_gen_lowpart (HImode, operands[2]);")
(define_insn "addsi_ashift16"
[(set (match_operand:SI 0 "register_operand" "=D")
(plus:SI