aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorStephane Carrez <Stephane.Carrez@worldnet.fr>2002-03-16 13:52:20 +0100
committerStephane Carrez <ciceron@gcc.gnu.org>2002-03-16 13:52:20 +0100
commit840e2ff10988bf7a1adf0bc0a0ac94e51e96ba6c (patch)
tree601ce27d41448786593b04667da83dcbf7421f16 /gcc
parent3c9a5efec97e3684486d0d861610d9c9fd1c8391 (diff)
downloadgcc-840e2ff10988bf7a1adf0bc0a0ac94e51e96ba6c.zip
gcc-840e2ff10988bf7a1adf0bc0a0ac94e51e96ba6c.tar.gz
gcc-840e2ff10988bf7a1adf0bc0a0ac94e51e96ba6c.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/config/m68hc11/m68hc11-protos.h1
-rw-r--r--gcc/config/m68hc11/m68hc11.md228
3 files changed, 134 insertions, 110 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ba8d64a..87181f2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,20 @@
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
allocating QImode in address registers.
("*movqi_m68hc11"): Likewise.
diff --git a/gcc/config/m68hc11/m68hc11-protos.h b/gcc/config/m68hc11/m68hc11-protos.h
index 27358b7..3611485 100644
--- a/gcc/config/m68hc11/m68hc11-protos.h
+++ b/gcc/config/m68hc11/m68hc11-protos.h
@@ -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));
diff --git a/gcc/config/m68hc11/m68hc11.md b/gcc/config/m68hc11/m68hc11.md
index df82cd4..092b903 100644
--- a/gcc/config/m68hc11/m68hc11.md
+++ b/gcc/config/m68hc11/m68hc11.md
@@ -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