From 840e2ff10988bf7a1adf0bc0a0ac94e51e96ba6c Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Sat, 16 Mar 2002 13:52:20 +0100 Subject: [PATCH] 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 --- gcc/ChangeLog | 15 ++ gcc/config/m68hc11/m68hc11-protos.h | 1 + gcc/config/m68hc11/m68hc11.md | 228 ++++++++++++++-------------- 3 files changed, 134 insertions(+), 110 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ba8d64a36a6..87181f2fa8b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2002-03-16 Stephane Carrez + + * 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 * config/m68hc11/m68hc11.md ("*movqi_68hc12"): Fix constraints, avoid diff --git a/gcc/config/m68hc11/m68hc11-protos.h b/gcc/config/m68hc11/m68hc11-protos.h index 27358b7b62f..36114850ca2 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 df82cd40384..092b903f54b 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