From 39250081452e05ed0592412a95f64f0e0871f3cc Mon Sep 17 00:00:00 2001 From: Roman Zippel Date: Mon, 24 Sep 2007 21:02:40 +0000 Subject: [PATCH] m68k.c (strict_low_part_peephole_ok): Don't leave the basic block. * config/m68k/m68k.c (strict_low_part_peephole_ok): Don't leave the basic block. * config/m68k/m68k.md (movsi_m68k): Allow certain constant when reload is completed. (peephole pattern): Convert most of them to RTL peephole pattern. From-SVN: r128728 --- gcc/ChangeLog | 8 ++ gcc/config/m68k/m68k.c | 16 ++- gcc/config/m68k/m68k.md | 291 +++++++++++++++++++++------------------- 3 files changed, 172 insertions(+), 143 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c092fec34fe..100a62cbdb2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2007-09-24 Roman Zippel + + * config/m68k/m68k.c (strict_low_part_peephole_ok): Don't leave + the basic block. + * config/m68k/m68k.md (movsi_m68k): Allow certain constant when + reload is completed. + (peephole pattern): Convert most of them to RTL peephole pattern. + 2007-09-24 Roman Zippel * config/m68k/m68k.c (notice_update_cc): Recognize fp compare diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c index 1f6b4f9fde7..1df869fdf40 100644 --- a/gcc/config/m68k/m68k.c +++ b/gcc/config/m68k/m68k.c @@ -3963,14 +3963,18 @@ bool strict_low_part_peephole_ok (enum machine_mode mode, rtx first_insn, rtx target) { - rtx p; + rtx p = first_insn; - p = prev_nonnote_insn (first_insn); - - while (p) + while ((p = PREV_INSN (p))) { + if (NOTE_INSN_BASIC_BLOCK_P (p)) + return false; + + if (NOTE_P (p)) + continue; + /* If it isn't an insn, then give up. */ - if (GET_CODE (p) != INSN) + if (!INSN_P (p)) return false; if (reg_set_p (target, p)) @@ -4000,8 +4004,6 @@ strict_low_part_peephole_ok (enum machine_mode mode, rtx first_insn, else return false; } - - p = prev_nonnote_insn (p); } return false; diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md index b6ce6a8df0e..68053b33b70 100644 --- a/gcc/config/m68k/m68k.md +++ b/gcc/config/m68k/m68k.md @@ -900,12 +900,21 @@ } }) -;; General case of fullword move. The register constraints -;; force integer constants in range for a moveq to be reloaded -;; if they are headed for memory. -(define_insn "" +;; General case of fullword move. +(define_insn "*movsi_m68k" ;; Notes: make sure no alternative allows g vs g. ;; We don't allow f-regs since fixed point cannot go in them. + [(set (match_operand:SI 0 "nonimmediate_operand" "=g,d,a<") + (match_operand:SI 1 "general_src_operand" "damSnT,n,i"))] + "!TARGET_COLDFIRE && reload_completed" +{ + return output_move_simode (operands); +}) + +;; Before reload is completed the register constraints +;; force integer constants in range for a moveq to be reloaded +;; if they are headed for memory. +(define_insn "*movsi_m68k2" [(set (match_operand:SI 0 "nonimmediate_operand" "=g,d,a<") (match_operand:SI 1 "general_src_operand" "damSKT,n,i"))] @@ -7292,153 +7301,163 @@ ;; and then is moved into an FP register. ;; But it is mainly intended to test the support for these optimizations. -(define_peephole +(define_peephole2 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4))) - (set (match_operand:DF 0 "register_operand" "=f") - (match_operand:DF 1 "register_operand" "ad"))] - "FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])" -{ - rtx xoperands[2]; - xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1); - output_asm_insn ("move%.l %1,%@", xoperands); - output_asm_insn ("move%.l %1,%-", operands); - return "fmove%.d %+,%0"; -}) + (set (match_operand:DF 0 "register_operand" "") + (match_operand:DF 1 "register_operand" ""))] + "FP_REG_P (operands[0]) && !FP_REG_P (operands[1])" + [(set (mem:SI (reg:SI SP_REG)) (match_dup 1)) + (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 2)) + (set (match_dup 0) (mem:DF (post_inc:SI (reg:SI SP_REG))))] + "split_di(operands + 1, 1, operands + 1, operands + 2);") ;; Optimize a stack-adjust followed by a push of an argument. ;; This is said to happen frequently with -msoft-float ;; when there are consecutive library calls. -(define_peephole +(define_peephole2 + [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4))) + (set (match_operand:SF 0 "push_operand" "") + (match_operand:SF 1 "general_operand" ""))] + "!reg_mentioned_p (stack_pointer_rtx, operands[0])" + [(set (match_dup 0) (match_dup 1))] + "operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);") + +(define_peephole2 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) - (match_operand:SI 0 "const_int_operand" "n"))) - (set (match_operand:SF 1 "push_operand" "=m") - (match_operand:SF 2 "general_operand" "rmfF"))] - "INTVAL (operands[0]) >= 4 - && ! reg_mentioned_p (stack_pointer_rtx, operands[2])" + (match_operand:SI 0 "const_int_operand" ""))) + (set (match_operand:SF 1 "push_operand" "") + (match_operand:SF 2 "general_operand" ""))] + "INTVAL (operands[0]) > 4 + && !reg_mentioned_p (stack_pointer_rtx, operands[2])" + [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 0))) + (set (match_dup 1) (match_dup 2))] { - if (INTVAL (operands[0]) > 4) - { - rtx xoperands[2]; - xoperands[0] = stack_pointer_rtx; - xoperands[1] = GEN_INT (INTVAL (operands[0]) - 4); - if (INTVAL (xoperands[1]) <= 8) - { - if (!TARGET_COLDFIRE) - output_asm_insn ("addq%.w %1,%0", xoperands); - else - output_asm_insn ("addq%.l %1,%0", xoperands); - } - else if (TUNE_CPU32 && INTVAL (xoperands[1]) <= 16) - { - xoperands[1] = GEN_INT (INTVAL (xoperands[1]) - 8); - output_asm_insn ("addq%.w #8,%0\;addq%.w %1,%0", xoperands); - } - else if (INTVAL (xoperands[1]) <= 0x7FFF) - { - if (TUNE_68040) - output_asm_insn ("add%.w %1,%0", xoperands); - else if (MOTOROLA) - output_asm_insn ("lea (%c1,%0),%0", xoperands); - else - output_asm_insn ("lea %0@(%c1),%0", xoperands); - } - else - output_asm_insn ("add%.l %1,%0", xoperands); - } - if (FP_REG_P (operands[2])) - return "fmove%.s %2,%@"; - return "move%.l %2,%@"; + operands[0] = GEN_INT (INTVAL (operands[0]) - 4); + operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx); }) ;; Speed up stack adjust followed by a fullword fixedpoint push. +;; Constant operands need special care, as replacing a "pea X.w" with +;; "move.l #X,(%sp)" is often not a win. -(define_peephole +;; Already done by the previous csa pass, left as reference. +(define_peephole2 + [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4))) + (set (match_operand:SI 0 "push_operand" "") + (match_operand:SI 1 "general_operand" ""))] + "!reg_mentioned_p (stack_pointer_rtx, operands[1])" + [(set (match_dup 0) (match_dup 1))] + "operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);") + +;; Try to use moveq, after stack push has been changed into a simple move. +(define_peephole2 + [(match_scratch:SI 2 "d") + (set (match_operand:SI 0 "memory_operand" "") + (match_operand:SI 1 "const_int_operand" ""))] + "GET_CODE (XEXP (operands[0], 0)) != PRE_DEC + && INTVAL (operands[1]) != 0 + && IN_RANGE (INTVAL (operands[1]), -0x80, 0x7f) + && !valid_mov3q_const (INTVAL (operands[1]))" + [(set (match_dup 2) (match_dup 1)) + (set (match_dup 0) (match_dup 2))]) + +;; This sequence adds an instruction, but is two bytes shorter. +(define_peephole2 + [(match_scratch:SI 2 "d") + (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 12))) + (set (match_operand:SI 0 "push_operand" "") + (match_operand:SI 1 "const_int_operand" ""))] + "INTVAL (operands[1]) != 0 + && IN_RANGE (INTVAL (operands[1]), -0x80, 0x7f) + && !valid_mov3q_const (INTVAL (operands[1]))" + [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8))) + (set (match_dup 2) (match_dup 1)) + (set (match_dup 0) (match_dup 2))] + "operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);") + +;; Changing pea X.w into a move.l is no real win here. +(define_peephole2 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) - (match_operand:SI 0 "const_int_operand" "n"))) - (set (match_operand:SI 1 "push_operand" "=m") - (match_operand:SI 2 "general_operand" "g"))] - "INTVAL (operands[0]) >= 4 - && ! reg_mentioned_p (stack_pointer_rtx, operands[2])" -{ - if (INTVAL (operands[0]) > 4) - { - rtx xoperands[2]; - xoperands[0] = stack_pointer_rtx; - xoperands[1] = GEN_INT (INTVAL (operands[0]) - 4); - if (INTVAL (xoperands[1]) <= 8) - { - if (!TARGET_COLDFIRE) - output_asm_insn ("addq%.w %1,%0", xoperands); - else - output_asm_insn ("addq%.l %1,%0", xoperands); - } - else if (TUNE_CPU32 && INTVAL (xoperands[1]) <= 16) - { - xoperands[1] = GEN_INT (INTVAL (xoperands[1]) - 8); - output_asm_insn ("addq%.w #8,%0\;addq%.w %1,%0", xoperands); - } - else if (INTVAL (xoperands[1]) <= 0x7FFF) - { - if (TUNE_68040) - output_asm_insn ("add%.w %1,%0", xoperands); - else if (MOTOROLA) - output_asm_insn ("lea (%c1,%0),%0", xoperands); - else - output_asm_insn ("lea %0@(%c1),%0", xoperands); - } - else - output_asm_insn ("add%.l %1,%0", xoperands); - } - if (operands[2] == const0_rtx) - return "clr%.l %@"; - return "move%.l %2,%@"; -}) - -;; Speed up pushing a single byte but leaving four bytes of space. - -(define_peephole - [(set (mem:QI (pre_dec:SI (reg:SI SP_REG))) - (match_operand:QI 1 "general_operand" "dami")) - (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (const_int 2)))] - "! reg_mentioned_p (stack_pointer_rtx, operands[1])" -{ - rtx xoperands[4]; - - if (GET_CODE (operands[1]) == REG) - return "move%.l %1,%-"; - - xoperands[1] = operands[1]; - xoperands[2] - = gen_rtx_MEM (QImode, plus_constant (stack_pointer_rtx, 3)); - xoperands[3] = stack_pointer_rtx; - if (!TARGET_COLDFIRE) - output_asm_insn ("subq%.w #4,%3\;move%.b %1,%2", xoperands); - else - output_asm_insn ("subq%.l #4,%3\;move%.b %1,%2", xoperands); - return ""; -}) + (match_operand:SI 0 "const_int_operand" ""))) + (set (match_operand:SI 1 "push_operand" "") + (match_operand:SI 2 "general_operand" ""))] + "INTVAL (operands[0]) > 4 + && !reg_mentioned_p (stack_pointer_rtx, operands[2]) + && !(CONST_INT_P (operands[2]) && INTVAL (operands[2]) != 0 + && IN_RANGE (INTVAL (operands[2]), -0x8000, 0x7fff) + && !valid_mov3q_const (INTVAL (operands[2])))" + [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 0))) + (set (match_dup 1) (match_dup 2))] +{ + operands[0] = GEN_INT (INTVAL (operands[0]) - 4); + operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx); +}) + +;; Speed up pushing a single byte/two bytes but leaving four bytes of space +;; (which differs slightly between m680x0 and ColdFire). + +(define_peephole2 + [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4))) + (set (match_operand:QI 0 "memory_operand" "") + (match_operand:QI 1 "register_operand" ""))] + "!reg_mentioned_p (stack_pointer_rtx, operands[1]) + && GET_CODE (XEXP (operands[0], 0)) == PLUS + && rtx_equal_p (XEXP (XEXP (operands[0], 0), 0), stack_pointer_rtx) + && CONST_INT_P (XEXP (XEXP (operands[0], 0), 1)) + && INTVAL (XEXP (XEXP (operands[0], 0), 1)) == 3" + [(set (match_dup 0) (match_dup 1))] +{ + rtx addr = gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx); + operands[0] = adjust_automodify_address (operands[0], SImode, addr, -3); + operands[1] = simplify_gen_subreg (SImode, operands[1], QImode, 0); +}) + +(define_peephole2 + [(set (match_operand:QI 0 "push_operand" "") + (match_operand:QI 1 "register_operand" "")) + (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -3)))] + "!reg_mentioned_p (stack_pointer_rtx, operands[1])" + [(set (match_dup 0) (match_dup 1))] +{ + operands[0] = adjust_automodify_address (operands[0], SImode, + XEXP (operands[0], 0), -3); + operands[1] = simplify_gen_subreg (SImode, operands[1], QImode, 0); +}) + +(define_peephole2 + [(set (match_operand:HI 0 "push_operand" "") + (match_operand:HI 1 "register_operand" "")) + (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -2)))] + "!reg_mentioned_p (stack_pointer_rtx, operands[1])" + [(set (match_dup 0) (match_dup 1))] +{ + operands[0] = adjust_automodify_address (operands[0], SImode, + XEXP (operands[0], 0), -2); + operands[1] = simplify_gen_subreg (SImode, operands[1], HImode, 0); +}) + +;; Optimize a series of strict_low_part assignments + +(define_peephole2 + [(set (match_operand:SI 0 "register_operand" "") + (const_int 0)) + (set (strict_low_part (match_operand:HI 1 "register_operand" "")) + (match_operand:HI 2 "general_operand" ""))] + "REGNO (operands[0]) == REGNO (operands[1]) + && strict_low_part_peephole_ok (HImode, insn, operands[0])" + [(set (strict_low_part (match_dup 1)) (match_dup 2))] + "") -(define_peephole - [(set (match_operand:SI 0 "register_operand" "=d") +(define_peephole2 + [(set (match_operand:SI 0 "register_operand" "") (const_int 0)) - (set (strict_low_part (subreg:HI (match_dup 0) 2)) - (match_operand:HI 1 "general_operand" "rmn"))] - "strict_low_part_peephole_ok (HImode, prev_nonnote_insn (insn), operands[0])" -{ - if (GET_CODE (operands[1]) == CONST_INT) - { - if (operands[1] == const0_rtx - && (DATA_REG_P (operands[0]) - || GET_CODE (operands[0]) == MEM) - /* clr insns on 68000 read before writing. */ - && ((TARGET_68010 || TARGET_COLDFIRE) - || !(GET_CODE (operands[0]) == MEM - && MEM_VOLATILE_P (operands[0])))) - return "clr%.w %0"; - } - return "move%.w %1,%0"; -}) + (set (strict_low_part (match_operand:QI 1 "register_operand" "")) + (match_operand:QI 2 "general_operand" ""))] + "REGNO (operands[0]) == REGNO (operands[1]) + && strict_low_part_peephole_ok (QImode, insn, operands[0])" + [(set (strict_low_part (match_dup 1)) (match_dup 2))] + "") ;; dbCC peepholes ;; -- 2.30.2