predicates.md: New file.

* config/mmix/predicates.md: New file.
	* config/mmix/mmix.c (mmix_symbolic_or_address_operand)
	(mmix_reg_or_constant_operand, mmix_reg_cc_operand)
	(mmix_foldable_comparison_operator, mmix_comparison_operator)
	(mmix_reg_or_0_operand, mmix_reg_or_8bit_operand): Remove.
	* config/mmix/mmix.h (PREDICATE_CODES, SPECIAL_MODE_PREDICATES):
	Don't define.
	* config/mmix/mmix.md: Include predicates.md.
	("call", "call_value"): Force address to register if it isn't a
	mmix_symbolic_or_address_operand.

From-SVN: r99235
This commit is contained in:
Hans-Peter Nilsson 2005-05-04 22:36:14 +00:00 committed by Hans-Peter Nilsson
parent 29572b4dae
commit cc73528f07
5 changed files with 188 additions and 154 deletions

View file

@ -1,3 +1,16 @@
2005-05-05 Hans-Peter Nilsson <hp@bitrange.com>
* config/mmix/predicates.md: New file.
* config/mmix/mmix.c (mmix_symbolic_or_address_operand)
(mmix_reg_or_constant_operand, mmix_reg_cc_operand)
(mmix_foldable_comparison_operator, mmix_comparison_operator)
(mmix_reg_or_0_operand, mmix_reg_or_8bit_operand): Remove.
* config/mmix/mmix.h (PREDICATE_CODES, SPECIAL_MODE_PREDICATES):
Don't define.
* config/mmix/mmix.md: Include predicates.md.
("call", "call_value"): Force address to register if it isn't a
mmix_symbolic_or_address_operand.
2005-05-04 Andrew MacLeod <amacleod@redhat.com>
* tree-flow-inline.h (op_iter_init_use, op_iter_init_def): Assert that

View file

@ -2343,139 +2343,6 @@ mmix_shiftable_wyde_value (unsigned HOST_WIDEST_INT value)
return 1;
}
/* True if this is an address_operand or a symbolic operand. */
int
mmix_symbolic_or_address_operand (rtx op, enum machine_mode mode)
{
switch (GET_CODE (op))
{
case SYMBOL_REF:
case LABEL_REF:
return 1;
case CONST:
op = XEXP (op, 0);
if ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
|| GET_CODE (XEXP (op, 0)) == LABEL_REF)
&& (GET_CODE (XEXP (op, 1)) == CONST_INT
|| (GET_CODE (XEXP (op, 1)) == CONST_DOUBLE
&& GET_MODE (XEXP (op, 1)) == VOIDmode)))
return 1;
/* Fall through. */
default:
return address_operand (op, mode);
}
}
/* True if this is a register or CONST_INT (or CONST_DOUBLE for DImode).
We could narrow the value down with a couple of predicated, but that
doesn't seem to be worth it at the moment. */
int
mmix_reg_or_constant_operand (rtx op, enum machine_mode mode)
{
return register_operand (op, mode)
|| (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == VOIDmode)
|| GET_CODE (op) == CONST_INT;
}
/* True if this is a register with a condition-code mode. */
int
mmix_reg_cc_operand (rtx op, enum machine_mode mode)
{
if (mode == VOIDmode)
mode = GET_MODE (op);
return register_operand (op, mode)
&& (mode == CCmode || mode == CC_UNSmode || mode == CC_FPmode
|| mode == CC_FPEQmode || mode == CC_FUNmode);
}
/* True if this is a foldable comparison operator
- one where a the result of (compare:CC (reg) (const_int 0)) can be
replaced by (reg). */
int
mmix_foldable_comparison_operator (rtx op, enum machine_mode mode)
{
RTX_CODE code = GET_CODE (op);
if (mode == VOIDmode)
mode = GET_MODE (op);
if (mode == VOIDmode && COMPARISON_P (op))
mode = GET_MODE (XEXP (op, 0));
return ((mode == CCmode || mode == DImode)
&& (code == NE || code == EQ || code == GE || code == GT
|| code == LE))
/* FIXME: This may be a stupid trick. What happens when GCC wants to
reverse the condition? Can it do that by itself? Maybe it can
even reverse the condition to fit a foldable one in the first
place? */
|| (mode == CC_UNSmode && (code == GTU || code == LEU));
}
/* Like comparison_operator, but only true if this comparison operator is
applied to a valid mode. Needed to avoid jump.c generating invalid
code with -ffast-math (gcc.dg/20001228-1.c). */
int
mmix_comparison_operator (rtx op, enum machine_mode mode)
{
RTX_CODE code = GET_CODE (op);
/* Comparison operators usually don't have a mode, but let's try and get
one anyway for the day that changes. */
if (mode == VOIDmode)
mode = GET_MODE (op);
/* Get the mode from the first operand if we don't have one. */
if (mode == VOIDmode && COMPARISON_P (op))
mode = GET_MODE (XEXP (op, 0));
/* FIXME: This needs to be kept in sync with the tables in
mmix_output_condition. */
return
(mode == VOIDmode && COMPARISON_P (op))
|| (mode == CC_FUNmode
&& (code == ORDERED || code == UNORDERED))
|| (mode == CC_FPmode
&& (code == GT || code == LT))
|| (mode == CC_FPEQmode
&& (code == NE || code == EQ))
|| (mode == CC_UNSmode
&& (code == GEU || code == GTU || code == LEU || code == LTU))
|| (mode == CCmode
&& (code == NE || code == EQ || code == GE || code == GT
|| code == LE || code == LT))
|| (mode == DImode
&& (code == NE || code == EQ || code == GE || code == GT
|| code == LE || code == LT || code == LEU || code == GTU));
}
/* True if this is a register or 0 (int or float). */
int
mmix_reg_or_0_operand (rtx op, enum machine_mode mode)
{
/* FIXME: Is mode calculation necessary and correct? */
return
op == CONST0_RTX (mode == VOIDmode ? GET_MODE (op) : mode)
|| register_operand (op, mode);
}
/* True if this is a register or an int 0..255. */
int
mmix_reg_or_8bit_operand (rtx op, enum machine_mode mode)
{
return register_operand (op, mode)
|| (GET_CODE (op) == CONST_INT
&& CONST_OK_FOR_LETTER_P (INTVAL (op), 'I'));
}
/* Returns zero if code and mode is not a valid condition from a
compare-type insn. Nonzero if it is. The parameter op, if non-NULL,
is the comparison of mode is CC-somethingmode. */

View file

@ -964,27 +964,6 @@ typedef struct { int regs; int lib; } CUMULATIVE_ARGS;
/* Node: Misc */
#define PREDICATE_CODES \
{"mmix_reg_cc_operand", {SUBREG, REG}}, \
{"mmix_foldable_comparison_operator", \
{NE, EQ, GE, GT, LE, LT}}, \
/* All '<', actually. */ \
{"mmix_comparison_operator", \
{NE, EQ, GE, GT, LE, LT, GEU, GTU, LEU, \
LTU, UNORDERED, ORDERED, UNEQ, UNGE, UNLE, \
UNLT, LTGT}}, \
{"mmix_symbolic_or_address_operand", \
{SYMBOL_REF, LABEL_REF, CONST, \
SUBREG, REG, PLUS}}, \
{"mmix_reg_or_constant_operand", \
{CONST_INT, CONST_DOUBLE, SUBREG, REG}}, \
{"mmix_reg_or_8bit_operand", \
{CONST_INT, CONST_DOUBLE, SUBREG, REG}}, \
{"mmix_reg_or_0_operand", \
{CONST_INT, CONST_DOUBLE, SUBREG, REG}},
#define SPECIAL_MODE_PREDICATES "mmix_symbolic_or_address_operand",
/* There's no way to get a PC-relative offset into tables for SImode, so
for the moment we have absolute entries in DImode.
When we're going ELF, these should be SImode and 1. */

View file

@ -40,7 +40,11 @@
(MMIX_rR_REGNUM 260)
(MMIX_fp_rO_OFFSET -24)]
)
;; Operand and operator predicates.
(include "predicates.md")
;; FIXME: Can we remove the reg-to-reg for smaller modes? Shouldn't they
;; be synthesized ok?
(define_insn "movqi"
@ -1078,6 +1082,16 @@ DIVU %1,%1,%2\;GET %0,:rR\;NEGU %2,0,%0\;CSNN %0,$255,%2")
""
"
{
/* The caller checks that the operand is generally valid as an
address, but at -O0 nothing makes sure that it's also a valid
call address for a *call*; a mmix_symbolic_or_address_operand.
Force into a register if it isn't. */
if (!mmix_symbolic_or_address_operand (XEXP (operands[0], 0),
GET_MODE (XEXP (operands[0], 0))))
operands[0]
= replace_equiv_address (operands[0],
force_reg (Pmode, XEXP (operands[0], 0)));
/* Since the epilogue 'uses' the return address, and it is clobbered
in the call, and we set it back after every call (all but one setting
will be optimized away), integrity is maintained. */
@ -1105,6 +1119,16 @@ DIVU %1,%1,%2\;GET %0,:rR\;NEGU %2,0,%0\;CSNN %0,$255,%2")
""
"
{
/* The caller checks that the operand is generally valid as an
address, but at -O0 nothing makes sure that it's also a valid
call address for a *call*; a mmix_symbolic_or_address_operand.
Force into a register if it isn't. */
if (!mmix_symbolic_or_address_operand (XEXP (operands[1], 0),
GET_MODE (XEXP (operands[1], 0))))
operands[1]
= replace_equiv_address (operands[1],
force_reg (Pmode, XEXP (operands[1], 0)));
/* Since the epilogue 'uses' the return address, and it is clobbered
in the call, and we set it back after every call (all but one setting
will be optimized away), integrity is maintained. */

View file

@ -0,0 +1,151 @@
;; Operand and operator predicates for the GCC MMIX port.
;; 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, 51 Franklin Street - Fifth Floor,
;; Boston, MA 02110-1301, USA.
;; True if this is a foldable comparison operator
;; - one where a the result of (compare:CC (reg) (const_int 0)) can be
;; replaced by (reg). */
(define_predicate "mmix_foldable_comparison_operator"
(match_code "ne, eq, ge, gt, le, lt, gtu, leu")
{
RTX_CODE code = GET_CODE (op);
if (mode == VOIDmode)
mode = GET_MODE (op);
/* This little bit is why the body of this predicate is kept as C. */
if (mode == VOIDmode)
mode = GET_MODE (XEXP (op, 0));
return ((mode == CCmode || mode == DImode)
&& (code == NE || code == EQ || code == GE || code == GT
|| code == LE || code == LT))
/* FIXME: This may be a stupid trick. What happens when GCC wants to
reverse the condition? Can it do that by itself? Maybe it can
even reverse the condition to fit a foldable one in the first
place? */
|| (mode == CC_UNSmode && (code == GTU || code == LEU));
})
;; Like comparison_operator, but only true if this comparison operator is
;; applied to a valid mode. Needed to avoid jump.c generating invalid
;; code with -ffast-math (gcc.dg/20001228-1.c).
(define_predicate "mmix_comparison_operator"
(match_operand 0 "comparison_operator")
{
RTX_CODE code = GET_CODE (op);
/* Comparison operators usually don't have a mode, but let's try and get
one anyway for the day that changes. */
if (mode == VOIDmode)
mode = GET_MODE (op);
/* Get the mode from the first operand if we don't have one.
Also the reason why we do this in C. */
if (mode == VOIDmode)
mode = GET_MODE (XEXP (op, 0));
/* FIXME: This needs to be kept in sync with the tables in
mmix_output_condition. */
return
mode == VOIDmode
|| (mode == CC_FUNmode
&& (code == ORDERED || code == UNORDERED))
|| (mode == CC_FPmode
&& (code == GT || code == LT))
|| (mode == CC_FPEQmode
&& (code == NE || code == EQ))
|| (mode == CC_UNSmode
&& (code == GEU || code == GTU || code == LEU || code == LTU))
|| (mode == CCmode
&& (code == NE || code == EQ || code == GE || code == GT
|| code == LE || code == LT))
|| (mode == DImode
&& (code == NE || code == EQ || code == GE || code == GT
|| code == LE || code == LT || code == LEU || code == GTU));
})
;; True if this is a register with a condition-code mode.
(define_predicate "mmix_reg_cc_operand"
(and (match_operand 0 "register_operand")
(ior (match_test "GET_MODE (op) == CCmode")
(ior (match_test "GET_MODE (op) == CC_UNSmode")
(ior (match_test "GET_MODE (op) == CC_FPmode")
(ior (match_test "GET_MODE (op) == CC_FPEQmode")
(match_test "GET_MODE (op) == CC_FUNmode")))))))
;; True if this is an address_operand or a symbolic operand.
(define_predicate "mmix_symbolic_or_address_operand"
(match_code "symbol_ref, label_ref, const, subreg, reg, plus")
{
switch (GET_CODE (op))
{
case SYMBOL_REF:
case LABEL_REF:
return 1;
case CONST:
/* The reason why this body still is C. */
op = XEXP (op, 0);
if ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
|| GET_CODE (XEXP (op, 0)) == LABEL_REF)
&& (GET_CODE (XEXP (op, 1)) == CONST_INT
|| (GET_CODE (XEXP (op, 1)) == CONST_DOUBLE
&& GET_MODE (XEXP (op, 1)) == VOIDmode)))
return 1;
/* Fall through. */
default:
return address_operand (op, mode);
}
})
;; True if this is a register or CONST_INT (or CONST_DOUBLE for DImode).
;; We could narrow the value down with a couple of predicates, but that
;; doesn't seem to be worth it at the moment.
(define_predicate "mmix_reg_or_constant_operand"
(ior (match_operand 0 "register_operand")
(ior (match_code "const_int")
(and (match_code "const_double")
(match_test "GET_MODE (op) == VOIDmode")))))
;; True if this is a register or 0 (int or float).
(define_predicate "mmix_reg_or_0_operand"
(ior
(match_operand 0 "register_operand")
(ior
(and (match_code "const_int")
(match_test "op == const0_rtx"))
(and
(match_code "const_double")
;; FIXME: Is mode calculation necessary and correct?
(match_test
"op == CONST0_RTX (mode == VOIDmode ? GET_MODE (op) : mode)")))))
;; True if this is a register or an int 0..255.
(define_predicate "mmix_reg_or_8bit_operand"
(ior
(match_operand 0 "register_operand")
(and (match_code "const_int")
(match_test "CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')"))))