From e2eeb731666dc753048f8dd72199b6011f715cc4 Mon Sep 17 00:00:00 2001 From: rth Date: Fri, 6 Aug 2004 07:14:56 +0000 Subject: [PATCH] * config/m68k/m68k.c (post_inc_operand,pre_dec_operand): New. * config/m68k/m68k.h (PREDICATE_CODES): add post_inc_operand, pre_dec_operand. * config/m68k/m68k.md (zero_extend*2): delay the splitting of the pattern until reload is finished to allow better code generation and split them completely into separate instrunctions. (*andsi3_split): New pattern. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@85631 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 10 ++ gcc/config/m68k/m68k.c | 12 ++ gcc/config/m68k/m68k.h | 4 +- gcc/config/m68k/m68k.md | 331 +++++++++++++++++++----------------------------- 4 files changed, 154 insertions(+), 203 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d7d4abd4ff7..b35bb6a8367 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2004-08-06 Roman Zippel + + * config/m68k/m68k.c (post_inc_operand,pre_dec_operand): New. + * config/m68k/m68k.h (PREDICATE_CODES): add post_inc_operand, + pre_dec_operand. + * config/m68k/m68k.md (zero_extend*2): delay the splitting of the + pattern until reload is finished to allow better code generation + and split them completely into separate instrunctions. + (*andsi3_split): New pattern. + 2004-08-05 Mark Mitchell * tree.c (handle_dll_attribute): Move here from i383/winnt.c. diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c index 4f2b71e06f9..e44f490c5a6 100644 --- a/gcc/config/m68k/m68k.c +++ b/gcc/config/m68k/m68k.c @@ -3185,6 +3185,18 @@ memory_src_operand (rtx op, enum machine_mode mode) return memory_operand (op, mode); } +int +post_inc_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) +{ + return MEM_P (op) && GET_CODE (XEXP (op, 0)) == POST_INC; +} + +int +pre_dec_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) +{ + return MEM_P (op) && GET_CODE (XEXP (op, 0)) == PRE_DEC; +} + /* Predicate that accepts only a pc-relative address. This is needed because pc-relative addresses don't satisfy the predicate "general_src_operand". */ diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h index 14a8b9bb8ae..6af7116f78b 100644 --- a/gcc/config/m68k/m68k.h +++ b/gcc/config/m68k/m68k.h @@ -1271,4 +1271,6 @@ extern int m68k_last_compare_had_fp_operands; {"valid_dbcc_comparison_p", {EQ, NE, GTU, LTU, GEU, LEU, \ GT, LT, GE, LE}}, \ {"extend_operator", {SIGN_EXTEND, ZERO_EXTEND}}, \ - {"symbolic_operand", {SYMBOL_REF, LABEL_REF, CONST}}, + {"symbolic_operand", {SYMBOL_REF, LABEL_REF, CONST}}, \ + {"post_inc_operand", {MEM}}, \ + {"pre_dec_operand", {MEM}}, diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md index cc69553683c..57ddd4a78f3 100644 --- a/gcc/config/m68k/m68k.md +++ b/gcc/config/m68k/m68k.md @@ -1136,236 +1136,153 @@ ;; zero extension instructions -(define_insn "zero_extendqidi2" - [(set (match_operand:DI 0 "nonimmediate_operand" "=&d") - (zero_extend:DI (match_operand:QI 1 "general_operand" "dm")))] +;; two special patterns to match various post_inc/pre_dec patterns +(define_insn_and_split "*zero_extend_inc" + [(set (match_operand 0 "post_inc_operand" "") + (zero_extend (match_operand 1 "register_operand" "")))] + "GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT && + GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT && + GET_MODE_SIZE (GET_MODE (operands[0])) == GET_MODE_SIZE (GET_MODE (operands[1])) * 2" + "#" + "" + [(set (match_dup 0) + (const_int 0)) + (set (match_dup 0) + (match_dup 1))] +{ + operands[0] = adjust_address (operands[0], GET_MODE (operands[1]), 0); +}) + +(define_insn_and_split "*zero_extend_dec" + [(set (match_operand 0 "pre_dec_operand" "") + (zero_extend (match_operand 1 "register_operand" "")))] + "(GET_MODE (operands[0]) != HImode || XEXP (XEXP (operands[0], 0), 0) != stack_pointer_rtx) && + GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT && + GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT && + GET_MODE_SIZE (GET_MODE (operands[0])) == GET_MODE_SIZE (GET_MODE (operands[1])) * 2" + "#" "" + [(set (match_dup 0) + (match_dup 1)) + (set (match_dup 0) + (const_int 0))] { - CC_STATUS_INIT; - operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); - return "moveq #0,%0\;moveq #0,%2\;move%.b %1,%2"; + operands[0] = adjust_address (operands[0], GET_MODE (operands[1]), 0); }) -(define_insn "zero_extendhidi2" - [(set (match_operand:DI 0 "nonimmediate_operand" "=&d") - (zero_extend:DI (match_operand:HI 1 "general_operand" "rm")))] +(define_insn_and_split "zero_extendqidi2" + [(set (match_operand:DI 0 "register_operand" "") + (zero_extend:DI (match_operand:QI 1 "nonimmediate_src_operand" "")))] + "" + "#" "" + [(set (match_dup 2) + (zero_extend:SI (match_dup 1))) + (set (match_dup 3) + (const_int 0))] { - CC_STATUS_INIT; - operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); - return "moveq #0,%0\;moveq #0,%2\;move%.w %1,%2"; + operands[2] = gen_lowpart (SImode, operands[0]); + operands[3] = gen_highpart (SImode, operands[0]); +}) + +(define_insn_and_split "zero_extendhidi2" + [(set (match_operand:DI 0 "register_operand" "") + (zero_extend:DI (match_operand:HI 1 "nonimmediate_src_operand" "")))] + "" + "#" + "" + [(set (match_dup 2) + (zero_extend:SI (match_dup 1))) + (set (match_dup 3) + (const_int 0))] +{ + operands[2] = gen_lowpart (SImode, operands[0]); + operands[3] = gen_highpart (SImode, operands[0]); }) -;; this is the canonical form for (lshiftrt:DI x 32) (define_expand "zero_extendsidi2" [(set (match_operand:DI 0 "nonimmediate_operand" "") - (zero_extend:DI (match_operand:SI 1 "general_operand" "")))] + (zero_extend:DI (match_operand:SI 1 "nonimmediate_src_operand" "")))] "" "") -(define_insn "*zero_extendsidi2_cf" - [(set (match_operand:DI 0 "nonimmediate_operand" "=r,m") - (zero_extend:DI (match_operand:SI 1 "general_operand" "rm,r")))] - "TARGET_COLDFIRE" +(define_insn_and_split "*zero_extendsidi2" + [(set (match_operand:DI 0 "nonimmediate_operand" "") + (zero_extend:DI (match_operand:SI 1 "nonimmediate_src_operand" "")))] + "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" + "#" + "" + [(set (match_dup 2) + (match_dup 1)) + (set (match_dup 3) + (const_int 0))] { - CC_STATUS_INIT; - if (GET_CODE (operands[0]) == REG) - operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); - else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) - return "move%.l %1,%0\;clr%.l %0"; - else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC) - return "clr%.l %0\;move%.l %1,%0"; - else - operands[2] = adjust_address (operands[0], SImode, 4); - if (GET_CODE (operands[1]) != REG || GET_CODE (operands[2]) != REG - || REGNO (operands[1]) != REGNO (operands[2])) - output_asm_insn ("move%.l %1,%2", operands); - if (ADDRESS_REG_P (operands[0])) - return "sub%.l %0,%0"; - else - return "clr%.l %0"; + operands[2] = gen_lowpart (SImode, operands[0]); + operands[3] = gen_highpart (SImode, operands[0]); }) -(define_insn "*zero_extendsidi2" - [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") - (zero_extend:DI (match_operand:SI 1 "general_operand" "rm")))] - "!TARGET_COLDFIRE" -{ - CC_STATUS_INIT; - if (GET_CODE (operands[0]) == REG) - operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); - else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) - return "move%.l %1,%0\;clr%.l %0"; - else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC) - return "clr%.l %0\;move%.l %1,%0"; - else - operands[2] = adjust_address (operands[0], SImode, 4); - if (GET_CODE (operands[1]) != REG || GET_CODE (operands[2]) != REG - || REGNO (operands[1]) != REGNO (operands[2])) - output_asm_insn ("move%.l %1,%2", operands); - if (ADDRESS_REG_P (operands[0])) - return "sub%.l %0,%0"; - else - return "clr%.l %0"; -}) +(define_insn "*zero_extendhisi2_cf" + [(set (match_operand:SI 0 "register_operand" "=d") + (zero_extend:SI (match_operand:HI 1 "nonimmediate_src_operand" "rmS")))] + "TARGET_CFV4" + "mvz%.w %1,%0") -(define_expand "zero_extendhisi2" - [(set (match_operand:SI 0 "register_operand" "") - (const_int 0)) - (set (strict_low_part (match_dup 2)) - (match_operand:HI 1 "general_operand" ""))] +(define_insn "zero_extendhisi2" + [(set (match_operand:SI 0 "register_operand" "=d") + (zero_extend:SI (match_operand:HI 1 "nonimmediate_src_operand" "rmS")))] "" - " -{ - operands[1] = make_safe_from (operands[1], operands[0]); - operands[2] = gen_lowpart_SUBREG (HImode, operands[0]); -}") + "#") (define_expand "zero_extendqihi2" [(set (match_operand:HI 0 "register_operand" "") - (const_int 0)) - (set (strict_low_part (match_dup 2)) - (match_operand:QI 1 "general_operand" ""))] - "" - " -{ - operands[1] = make_safe_from (operands[1], operands[0]); - operands[2] = gen_lowpart_SUBREG (QImode, operands[0]); -}") + (zero_extend:HI (match_operand:QI 1 "nonimmediate_src_operand" "")))] + "!TARGET_COLDFIRE" + "") -(define_expand "zero_extendqisi2" - [(set (match_operand:SI 0 "register_operand" "") - (const_int 0)) - (set (strict_low_part (match_dup 2)) - (match_operand:QI 1 "general_operand" ""))] - "" - " -{ - operands[1] = make_safe_from (operands[1], operands[0]); - operands[2] = gen_lowpart_SUBREG (QImode, operands[0]); -}") - -;; Patterns to recognize zero-extend insns produced by the combiner. -;; We don't allow both operands in memory, because of aliasing problems. -;; Explicitly disallow two memory operands via the condition since reloading -;; of this case will result in worse code than the uncombined patterns. +(define_insn "*zero_extendqihi2" + [(set (match_operand:HI 0 "register_operand" "=d") + (zero_extend:HI (match_operand:QI 1 "nonimmediate_src_operand" "dmS")))] + "!TARGET_COLDFIRE" + "#") -(define_insn "" - [(set (match_operand:SI 0 "nonimmediate_operand" "=do<>,d<") - (zero_extend:SI (match_operand:HI 1 "nonimmediate_src_operand" "r,mS")))] - "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" -{ - if (DATA_REG_P (operands[0])) - { - if (TARGET_CFV4) - return "mvz%.w %1,%0"; - if (GET_CODE (operands[1]) == REG - && REGNO (operands[0]) == REGNO (operands[1])) - return "and%.l #0xFFFF,%0"; - if (reg_mentioned_p (operands[0], operands[1])) - return "move%.w %1,%0\;and%.l #0xFFFF,%0"; - return "clr%.l %0\;move%.w %1,%0"; - } - else if (GET_CODE (operands[0]) == MEM - && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) - return "move%.w %1,%0\;clr%.w %0"; - else if (GET_CODE (operands[0]) == MEM - && GET_CODE (XEXP (operands[0], 0)) == POST_INC) - return "clr%.w %0\;move%.w %1,%0"; - else - { - output_asm_insn ("clr%.w %0", operands); - operands[0] = adjust_address (operands[0], HImode, 2); - return "move%.w %1,%0"; - } -}) +(define_insn "*zero_extendqisi2_cfv4" + [(set (match_operand:SI 0 "register_operand" "=d") + (zero_extend:SI (match_operand:QI 1 "nonimmediate_src_operand" "dmS")))] + "TARGET_CFV4" + "mvz%.b %1,%0") -(define_insn "" - [(set (match_operand:HI 0 "nonimmediate_operand" "=do<>,d") - (zero_extend:HI (match_operand:QI 1 "nonimmediate_src_operand" "d,mS")))] - "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" +(define_insn "zero_extendqisi2" + [(set (match_operand:SI 0 "register_operand" "=d") + (zero_extend:SI (match_operand:QI 1 "nonimmediate_src_operand" "dmS")))] + "" + "#") + +;; these two pattern split everything else which isn't matched by +;; something else above +(define_split + [(set (match_operand 0 "register_operand" "") + (zero_extend (match_operand 1 "nonimmediate_src_operand" "")))] + "!TARGET_CFV4 && reload_completed && reg_mentioned_p (operands[0], operands[1])" + [(set (strict_low_part (match_dup 2)) + (match_dup 1)) + (set (match_dup 0) + (match_op_dup 4 [(match_dup 0) (match_dup 3)]))] { - if (DATA_REG_P (operands[0])) - { - if (GET_CODE (operands[1]) == REG - && REGNO (operands[0]) == REGNO (operands[1])) - { - if (TARGET_CFV4) - return "mvz%.b %0,%0"; - return (!TARGET_COLDFIRE ? "and%.w #0xFF,%0" : "and%.l #0xFF,%0"); - } - if (reg_mentioned_p (operands[0], operands[1])) - { - if (TARGET_CFV4) - return "mvz%.b %1,%0"; - return (!TARGET_COLDFIRE ? "move%.b %1,%0\;and%.w #0xFF,%0" - : "move%.b %1,%0\;and%.l #0xFF,%0"); - } - return "clr%.w %0\;move%.b %1,%0"; - } - else if (GET_CODE (operands[0]) == MEM - && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) - { - if (REGNO (XEXP (XEXP (operands[0], 0), 0)) - == STACK_POINTER_REGNUM) - { - output_asm_insn ("clr%.w %-", operands); - operands[0] = gen_rtx_MEM (GET_MODE (operands[0]), - plus_constant (stack_pointer_rtx, 1)); - return "move%.b %1,%0"; - } - else - return "move%.b %1,%0\;clr%.b %0"; - } - else if (GET_CODE (operands[0]) == MEM - && GET_CODE (XEXP (operands[0], 0)) == POST_INC) - return "clr%.b %0\;move%.b %1,%0"; - else - { - output_asm_insn ("clr%.b %0", operands); - operands[0] = adjust_address (operands[0], QImode, 1); - return "move%.b %1,%0"; - } + operands[2] = gen_lowpart (GET_MODE (operands[1]), operands[0]); + operands[3] = GEN_INT (GET_MODE_MASK (GET_MODE (operands[1]))); + operands[4] = gen_rtx_AND (GET_MODE (operands[0]), operands[0], operands[3]); }) -(define_insn "" - [(set (match_operand:SI 0 "nonimmediate_operand" "=do<>,d") - (zero_extend:SI (match_operand:QI 1 "nonimmediate_src_operand" "d,mS")))] - "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" +(define_split + [(set (match_operand 0 "register_operand" "") + (zero_extend (match_operand 1 "nonimmediate_src_operand" "")))] + "!TARGET_CFV4 && reload_completed" + [(set (match_dup 0) + (const_int 0)) + (set (strict_low_part (match_dup 2)) + (match_dup 1))] { - if (DATA_REG_P (operands[0])) - { - if (TARGET_CFV4) - return "mvz%.b %1,%0"; - if (GET_CODE (operands[1]) == REG - && REGNO (operands[0]) == REGNO (operands[1])) - return "and%.l #0xFF,%0"; - if (reg_mentioned_p (operands[0], operands[1])) - return "move%.b %1,%0\;and%.l #0xFF,%0"; - return "clr%.l %0\;move%.b %1,%0"; - } - else if (GET_CODE (operands[0]) == MEM - && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) - { - operands[0] = XEXP (XEXP (operands[0], 0), 0); - return MOTOROLA ? - "clr%.l -(%0)\;move%.b %1,(3,%0)" : - "clrl %0@-\;moveb %1,%0@(3)"; - } - else if (GET_CODE (operands[0]) == MEM - && GET_CODE (XEXP (operands[0], 0)) == POST_INC) - { - operands[0] = XEXP (XEXP (operands[0], 0), 0); - return MOTOROLA ? - "clr%.l (%0)+\;move%.b %1,(-1,%0)" : - "clrl %0@+\;moveb %1,%0@(-1)"; - } - else - { - output_asm_insn ("clr%.l %0", operands); - operands[0] = adjust_address (operands[0], QImode, 3); - return "move%.b %1,%0"; - } + operands[2] = gen_lowpart (GET_MODE (operands[1]), operands[0]); }) ;; sign extension instructions @@ -3131,6 +3048,16 @@ "" "") +;; produced by split operations after reload finished +(define_insn "*andsi3_split" + [(set (match_operand:SI 0 "register_operand" "=d") + (and:SI (match_operand:SI 1 "register_operand" "0") + (match_operand:SI 2 "const_int_operand" "i")))] + "reload_completed && !TARGET_COLDFIRE" +{ + return output_andsi3 (operands); +}) + (define_insn "andsi3_internal" [(set (match_operand:SI 0 "not_sp_operand" "=m,d") (and:SI (match_operand:SI 1 "general_operand" "%0,0") -- 2.11.4.GIT