summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2004-08-06 07:14:56 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2004-08-06 07:14:56 +0000
commite2eeb731666dc753048f8dd72199b6011f715cc4 (patch)
tree7f79d73b2213c45dae68d04784ca43a1df49250f
parentea8d3d75f4a48045a1f09c0928d305f756627862 (diff)
downloadgcc-e2eeb731666dc753048f8dd72199b6011f715cc4.tar.gz
* 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
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/config/m68k/m68k.c12
-rw-r--r--gcc/config/m68k/m68k.h4
-rw-r--r--gcc/config/m68k/m68k.md331
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 <zippel@linux-m68k.org>
+
+ * 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 <mark@codesourcery.com>
* 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")