summaryrefslogtreecommitdiff
path: root/gcc/config/m68k
diff options
context:
space:
mode:
authorKazu Hirata <kazu@cs.umass.edu>2005-04-05 01:59:58 +0000
committerKazu Hirata <kazu@gcc.gnu.org>2005-04-05 01:59:58 +0000
commit41b6a5e2c06e315f3fc465b78421090d86a51021 (patch)
tree5a6f48d552c3daa41428a576776c6e55334e0702 /gcc/config/m68k
parentacaa3bf7a13e5589d1b554c1a13432900ee2d219 (diff)
downloadgcc-41b6a5e2c06e315f3fc465b78421090d86a51021.tar.gz
m68k-protos.h: Add a prototype for valid_dbcc_comparison_p_2.
* config/m68k/m68k-protos.h: Add a prototype for valid_dbcc_comparison_p_2. * config/m68k/m68k.c (not_sp_operand, symbolic_operand, extend_operator, const_uint32_operand, const_sint32_operand, general_src_operand, nonimmediate_src_operand, memory_src_operand, post_inc_operand, pre_dec_operand, pcrel_address): Move to predicates to predicates.md. * config/m68k/m68k.h (PREDICATE_CODES): Remove. * config/m68k/m68k.md: Include predicates.md. * config/m68k/predicates.md: New. From-SVN: r97595
Diffstat (limited to 'gcc/config/m68k')
-rw-r--r--gcc/config/m68k/m68k-protos.h1
-rw-r--r--gcc/config/m68k/m68k.c165
-rw-r--r--gcc/config/m68k/m68k.h19
-rw-r--r--gcc/config/m68k/m68k.md2
-rw-r--r--gcc/config/m68k/predicates.md196
5 files changed, 200 insertions, 183 deletions
diff --git a/gcc/config/m68k/m68k-protos.h b/gcc/config/m68k/m68k-protos.h
index 4b66927d239..0f92d0df89f 100644
--- a/gcc/config/m68k/m68k-protos.h
+++ b/gcc/config/m68k/m68k-protos.h
@@ -50,6 +50,7 @@ extern void print_operand_address (FILE *, rtx);
extern void print_operand (FILE *, rtx, int);
extern void notice_update_cc (rtx, rtx);
extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx);
+extern int valid_dbcc_comparison_p_2 (rtx, enum machine_mode);
#endif /* RTX_CODE */
diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
index 7e24c2557ee..7cf87d383c6 100644
--- a/gcc/config/m68k/m68k.c
+++ b/gcc/config/m68k/m68k.c
@@ -912,14 +912,6 @@ m68k_output_function_epilogue (FILE *stream, HOST_WIDE_INT size ATTRIBUTE_UNUSED
fprintf (stream, "\trts\n");
}
-/* Similar to general_operand, but exclude stack_pointer_rtx. */
-
-int
-not_sp_operand (rtx op, enum machine_mode mode)
-{
- return op != stack_pointer_rtx && nonimmediate_operand (op, mode);
-}
-
/* Return true if X is a valid comparison operator for the dbcc
instruction.
@@ -929,7 +921,7 @@ not_sp_operand (rtx op, enum machine_mode mode)
It also rejects some comparisons when CC_NO_OVERFLOW is set. */
int
-valid_dbcc_comparison_p (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED)
+valid_dbcc_comparison_p_2 (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED)
{
switch (GET_CODE (x))
{
@@ -1284,53 +1276,6 @@ output_btst (rtx *operands, rtx countop, rtx dataop, rtx insn, int signpos)
return "btst %0,%1";
}
-/* Returns true if OP is either a symbol reference or a sum of a symbol
- reference and a constant. */
-
-int
-symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
- switch (GET_CODE (op))
- {
- case SYMBOL_REF:
- case LABEL_REF:
- return true;
-
- case CONST:
- op = XEXP (op, 0);
- return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
- || GET_CODE (XEXP (op, 0)) == LABEL_REF)
- && GET_CODE (XEXP (op, 1)) == CONST_INT);
-
-#if 0 /* Deleted, with corresponding change in m68k.h,
- so as to fit the specs. No CONST_DOUBLE is ever symbolic. */
- case CONST_DOUBLE:
- return GET_MODE (op) == mode;
-#endif
-
- default:
- return false;
- }
-}
-
-/* Check for sign_extend or zero_extend. Used for bit-count operands. */
-
-int
-extend_operator(rtx x, enum machine_mode mode)
-{
- if (mode != VOIDmode && GET_MODE(x) != mode)
- return 0;
- switch (GET_CODE(x))
- {
- case SIGN_EXTEND :
- case ZERO_EXTEND :
- return 1;
- default :
- return 0;
- }
-}
-
-
/* Legitimize PIC addresses. If the address is already
position-independent, we return ORIG. Newly generated
position-independent addresses go to REG. If we need more
@@ -3047,45 +2992,6 @@ strict_low_part_peephole_ok (enum machine_mode mode, rtx first_insn,
return false;
}
-/* Accept integer operands in the range 0..0xffffffff. We have to check the
- range carefully since this predicate is used in DImode contexts. Also, we
- need some extra crud to make it work when hosted on 64-bit machines. */
-
-int
-const_uint32_operand (rtx op, enum machine_mode mode)
-{
- /* It doesn't make sense to ask this question with a mode that is
- not larger than 32 bits. */
- if (GET_MODE_BITSIZE (mode) <= 32)
- abort ();
-
-#if HOST_BITS_PER_WIDE_INT > 32
- /* All allowed constants will fit a CONST_INT. */
- return (GET_CODE (op) == CONST_INT
- && (INTVAL (op) >= 0 && INTVAL (op) <= 0xffffffffL));
-#else
- return (GET_CODE (op) == CONST_INT
- || (GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_HIGH (op) == 0));
-#endif
-}
-
-/* Accept integer operands in the range -0x80000000..0x7fffffff. We have
- to check the range carefully since this predicate is used in DImode
- contexts. */
-
-int
-const_sint32_operand (rtx op, enum machine_mode mode)
-{
- /* It doesn't make sense to ask this question with a mode that is
- not larger than 32 bits. */
- if (GET_MODE_BITSIZE (mode) <= 32)
- abort ();
-
- /* All allowed constants will fit a CONST_INT. */
- return (GET_CODE (op) == CONST_INT
- && (INTVAL (op) >= (-0x7fffffff - 1) && INTVAL (op) <= 0x7fffffff));
-}
-
/* Operand predicates for implementing asymmetric pc-relative addressing
on m68k. The m68k supports pc-relative addressing (mode 7, register 2)
when used as a source operand, but not as a destination operand.
@@ -3143,75 +3049,6 @@ const_sint32_operand (rtx op, enum machine_mode mode)
***************************************************************************/
-/* Special case of a general operand that's used as a source operand.
- Use this to permit reads from PC-relative memory when -mpcrel
- is specified. */
-
-int
-general_src_operand (rtx op, enum machine_mode mode)
-{
- if (TARGET_PCREL
- && GET_CODE (op) == MEM
- && (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
- || GET_CODE (XEXP (op, 0)) == LABEL_REF
- || GET_CODE (XEXP (op, 0)) == CONST))
- return 1;
- return general_operand (op, mode);
-}
-
-/* Special case of a nonimmediate operand that's used as a source.
- Use this to permit reads from PC-relative memory when -mpcrel
- is specified. */
-
-int
-nonimmediate_src_operand (rtx op, enum machine_mode mode)
-{
- if (TARGET_PCREL && GET_CODE (op) == MEM
- && (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
- || GET_CODE (XEXP (op, 0)) == LABEL_REF
- || GET_CODE (XEXP (op, 0)) == CONST))
- return 1;
- return nonimmediate_operand (op, mode);
-}
-
-/* Special case of a memory operand that's used as a source.
- Use this to permit reads from PC-relative memory when -mpcrel
- is specified. */
-
-int
-memory_src_operand (rtx op, enum machine_mode mode)
-{
- if (TARGET_PCREL && GET_CODE (op) == MEM
- && (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
- || GET_CODE (XEXP (op, 0)) == LABEL_REF
- || GET_CODE (XEXP (op, 0)) == CONST))
- return 1;
- 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". */
-
-int
-pcrel_address (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
- return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF
- || GET_CODE (op) == CONST);
-}
-
const char *
output_andsi3 (rtx *operands)
{
diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h
index 4a832b4ccda..98a6004d5f7 100644
--- a/gcc/config/m68k/m68k.h
+++ b/gcc/config/m68k/m68k.h
@@ -1260,22 +1260,3 @@ do { if (cc_prev_status.flags & CC_IN_68881) \
/* Variables in m68k.c */
extern const char *m68k_library_id_string;
extern int m68k_last_compare_had_fp_operands;
-
-
-/* Define the codes that are matched by predicates in m68k.c. */
-
-#define PREDICATE_CODES \
- {"general_src_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF, \
- LABEL_REF, SUBREG, REG, MEM}}, \
- {"nonimmediate_src_operand", {SUBREG, REG, MEM}}, \
- {"memory_src_operand", {SUBREG, MEM}}, \
- {"not_sp_operand", {SUBREG, REG, MEM}}, \
- {"pcrel_address", {SYMBOL_REF, LABEL_REF, CONST}}, \
- {"const_uint32_operand", {CONST_INT, CONST_DOUBLE}}, \
- {"const_sint32_operand", {CONST_INT}}, \
- {"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}}, \
- {"post_inc_operand", {MEM}}, \
- {"pre_dec_operand", {MEM}},
diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
index 57ddd4a78f3..3cee90c3c6c 100644
--- a/gcc/config/m68k/m68k.md
+++ b/gcc/config/m68k/m68k.md
@@ -128,6 +128,8 @@
[(A0_REG 8)
(SP_REG 15)
])
+
+(include "predicates.md")
(define_insn ""
[(set (match_operand:DF 0 "push_operand" "=m")
diff --git a/gcc/config/m68k/predicates.md b/gcc/config/m68k/predicates.md
new file mode 100644
index 00000000000..183c4e7d5fc
--- /dev/null
+++ b/gcc/config/m68k/predicates.md
@@ -0,0 +1,196 @@
+;; Predicate definitions for Motorola 68000.
+;; Copyright (C) 2005 Free Software Foundation, Inc.
+;;
+;; This file is part of GCC.
+;;
+;; GCC is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+;;
+;; GCC is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING. If not, write to
+;; the Free Software Foundation, 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;; Special case of a general operand that's used as a source
+;; operand. Use this to permit reads from PC-relative memory when
+;; -mpcrel is specified.
+
+(define_predicate "general_src_operand"
+ (match_code "const_int,const_double,const,symbol_ref,label_ref,subreg,reg,mem")
+{
+ if (TARGET_PCREL
+ && GET_CODE (op) == MEM
+ && (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
+ || GET_CODE (XEXP (op, 0)) == LABEL_REF
+ || GET_CODE (XEXP (op, 0)) == CONST))
+ return 1;
+ return general_operand (op, mode);
+})
+
+;; Special case of a nonimmediate operand that's used as a source. Use
+;; this to permit reads from PC-relative memory when -mpcrel is
+;; specified.
+
+(define_predicate "nonimmediate_src_operand"
+ (match_code "subreg,reg,mem")
+{
+ if (TARGET_PCREL && GET_CODE (op) == MEM
+ && (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
+ || GET_CODE (XEXP (op, 0)) == LABEL_REF
+ || GET_CODE (XEXP (op, 0)) == CONST))
+ return 1;
+ return nonimmediate_operand (op, mode);
+})
+
+;; Special case of a memory operand that's used as a source. Use this
+;; to permit reads from PC-relative memory when -mpcrel is specified.
+
+(define_predicate "memory_src_operand"
+ (match_code "subreg,mem")
+{
+ if (TARGET_PCREL && GET_CODE (op) == MEM
+ && (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
+ || GET_CODE (XEXP (op, 0)) == LABEL_REF
+ || GET_CODE (XEXP (op, 0)) == CONST))
+ return 1;
+ return memory_operand (op, mode);
+})
+
+;; Similar to general_operand, but exclude stack_pointer_rtx.
+
+(define_predicate "not_sp_operand"
+ (match_code "subreg,reg,mem")
+{
+ return op != stack_pointer_rtx && nonimmediate_operand (op, mode);
+})
+
+;; Predicate that accepts only a pc-relative address. This is needed
+;; because pc-relative addresses don't satisfy the predicate
+;; "general_src_operand".
+
+(define_predicate "pcrel_address"
+ (match_code "symbol_ref,label_ref,const")
+{
+ return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF
+ || GET_CODE (op) == CONST);
+})
+
+;; Accept integer operands in the range 0..0xffffffff. We have to
+;; check the range carefully since this predicate is used in DImode
+;; contexts. Also, we need some extra crud to make it work when
+;; hosted on 64-bit machines.
+
+(define_predicate "const_uint32_operand"
+ (match_code "const_int,const_double")
+{
+ /* It doesn't make sense to ask this question with a mode that is
+ not larger than 32 bits. */
+ if (GET_MODE_BITSIZE (mode) <= 32)
+ abort ();
+
+#if HOST_BITS_PER_WIDE_INT > 32
+ /* All allowed constants will fit a CONST_INT. */
+ return (GET_CODE (op) == CONST_INT
+ && (INTVAL (op) >= 0 && INTVAL (op) <= 0xffffffffL));
+#else
+ return (GET_CODE (op) == CONST_INT
+ || (GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_HIGH (op) == 0));
+#endif
+})
+
+;; Accept integer operands in the range -0x80000000..0x7fffffff. We
+;; have to check the range carefully since this predicate is used in
+;; DImode contexts.
+
+(define_predicate "const_sint32_operand"
+ (match_code "const_int")
+{
+ /* It doesn't make sense to ask this question with a mode that is
+ not larger than 32 bits. */
+ if (GET_MODE_BITSIZE (mode) <= 32)
+ abort ();
+
+ /* All allowed constants will fit a CONST_INT. */
+ return (GET_CODE (op) == CONST_INT
+ && (INTVAL (op) >= (-0x7fffffff - 1) && INTVAL (op) <= 0x7fffffff));
+})
+
+;; Return true if X is a valid comparison operator for the dbcc
+;; instruction. Note it rejects floating point comparison
+;; operators. (In the future we could use Fdbcc). It also rejects
+;; some comparisons when CC_NO_OVERFLOW is set.
+
+(define_predicate "valid_dbcc_comparison_p"
+ (match_code "eq,ne,gtu,ltu,geu,leu,gt,lt,ge,le")
+{
+ return valid_dbcc_comparison_p_2 (op, mode);
+})
+
+;; Check for sign_extend or zero_extend. Used for bit-count operands.
+
+(define_predicate "extend_operator"
+ (match_code "sign_extend,zero_extend")
+{
+ if (mode != VOIDmode && GET_MODE (op) != mode)
+ return 0;
+ switch (GET_CODE (op))
+ {
+ case SIGN_EXTEND:
+ case ZERO_EXTEND:
+ return 1;
+ default:
+ return 0;
+ }
+})
+
+;; Returns true if OP is either a symbol reference or a sum of a
+;; symbol reference and a constant.
+
+(define_predicate "symbolic_operand"
+ (match_code "symbol_ref,label_ref,const")
+{
+ switch (GET_CODE (op))
+ {
+ case SYMBOL_REF:
+ case LABEL_REF:
+ return true;
+
+ case CONST:
+ op = XEXP (op, 0);
+ return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
+ || GET_CODE (XEXP (op, 0)) == LABEL_REF)
+ && GET_CODE (XEXP (op, 1)) == CONST_INT);
+
+#if 0 /* Deleted, with corresponding change in m68k.h,
+ so as to fit the specs. No CONST_DOUBLE is ever symbolic. */
+ case CONST_DOUBLE:
+ return GET_MODE (op) == mode;
+#endif
+
+ default:
+ return false;
+ }
+})
+
+;; TODO: Add a comment here.
+
+(define_predicate "post_inc_operand"
+ (match_code "mem")
+{
+ return MEM_P (op) && GET_CODE (XEXP (op, 0)) == POST_INC;
+})
+
+;; TODO: Add a comment here.
+
+(define_predicate "pre_dec_operand"
+ (match_code "mem")
+{
+ return MEM_P (op) && GET_CODE (XEXP (op, 0)) == PRE_DEC;
+})