aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/mmix
diff options
context:
space:
mode:
authorPaolo Bonzini <bonzini@gnu.org>2009-05-12 09:43:48 +0000
committerPaolo Bonzini <bonzini@gcc.gnu.org>2009-05-12 09:43:48 +0000
commitf90b7a5a7913cc7239cce42f6ca328b9a741b387 (patch)
tree06c940a96a184a178bfadd53e04213225655a68d /gcc/config/mmix
parentb7a0af68063c79655c561750e9863799bf846cae (diff)
downloadgcc-f90b7a5a7913cc7239cce42f6ca328b9a741b387.zip
gcc-f90b7a5a7913cc7239cce42f6ca328b9a741b387.tar.gz
gcc-f90b7a5a7913cc7239cce42f6ca328b9a741b387.tar.bz2
Merge cond-optab branch.
From-SVN: r147425
Diffstat (limited to 'gcc/config/mmix')
-rw-r--r--gcc/config/mmix/mmix-protos.h1
-rw-r--r--gcc/config/mmix/mmix.c62
-rw-r--r--gcc/config/mmix/mmix.h5
-rw-r--r--gcc/config/mmix/mmix.md250
-rw-r--r--gcc/config/mmix/predicates.md5
5 files changed, 71 insertions, 252 deletions
diff --git a/gcc/config/mmix/mmix-protos.h b/gcc/config/mmix/mmix-protos.h
index d71064a..d294d8f 100644
--- a/gcc/config/mmix/mmix-protos.h
+++ b/gcc/config/mmix/mmix-protos.h
@@ -96,7 +96,6 @@ extern void mmix_setup_frame_addresses (void);
/* Needs to be ifdef:d for sake of enum rtx_code. */
extern enum machine_mode mmix_select_cc_mode (enum rtx_code, rtx, rtx);
extern void mmix_canonicalize_comparison (enum rtx_code *, rtx *, rtx *);
-extern int mmix_valid_comparison (enum rtx_code, enum machine_mode, rtx);
extern rtx mmix_gen_compare_reg (enum rtx_code, rtx, rtx);
#endif
diff --git a/gcc/config/mmix/mmix.c b/gcc/config/mmix/mmix.c
index ceed8db..6ced05c 100644
--- a/gcc/config/mmix/mmix.c
+++ b/gcc/config/mmix/mmix.c
@@ -2359,70 +2359,14 @@ mmix_shiftable_wyde_value (unsigned HOST_WIDEST_INT value)
return 1;
}
-/* 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. */
-
-int
-mmix_valid_comparison (RTX_CODE code, enum machine_mode mode, rtx op)
-{
- if (mode == VOIDmode && op != NULL_RTX)
- mode = GET_MODE (op);
-
- /* We don't care to look at these, they should always be valid. */
- if (mode == CCmode || mode == CC_UNSmode || mode == DImode)
- return 1;
-
- if ((mode == CC_FPmode || mode == DFmode)
- && (code == GT || code == LT))
- return 1;
-
- if ((mode == CC_FPEQmode || mode == DFmode)
- && (code == EQ || code == NE))
- return 1;
-
- if ((mode == CC_FUNmode || mode == DFmode)
- && (code == ORDERED || code == UNORDERED))
- return 1;
-
- return 0;
-}
-
-/* X and Y are two things to compare using CODE. Emit a compare insn if
- possible and return the rtx for the cc-reg in the proper mode, or
- NULL_RTX if this is not a valid comparison. */
+/* X and Y are two things to compare using CODE. Return the rtx for
+ the cc-reg in the proper mode. */
rtx
mmix_gen_compare_reg (RTX_CODE code, rtx x, rtx y)
{
enum machine_mode ccmode = SELECT_CC_MODE (code, x, y);
- rtx cc_reg;
-
- /* FIXME: Do we get constants here? Of double mode? */
- enum machine_mode mode
- = GET_MODE (x) == VOIDmode
- ? GET_MODE (y)
- : GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT ? DFmode : DImode;
-
- if (! mmix_valid_comparison (code, mode, x))
- return NULL_RTX;
-
- cc_reg = gen_reg_rtx (ccmode);
-
- /* FIXME: Can we avoid emitting a compare insn here? */
- if (! REG_P (x) && ! REG_P (y))
- x = force_reg (mode, x);
-
- /* If it's not quite right yet, put y in a register. */
- if (! REG_P (y)
- && (GET_CODE (y) != CONST_INT
- || ! CONST_OK_FOR_LETTER_P (INTVAL (y), 'I')))
- y = force_reg (mode, y);
-
- emit_insn (gen_rtx_SET (VOIDmode, cc_reg,
- gen_rtx_COMPARE (ccmode, x, y)));
-
- return cc_reg;
+ return gen_reg_rtx (ccmode);
}
/* Local (static) helper functions. */
diff --git a/gcc/config/mmix/mmix.h b/gcc/config/mmix/mmix.h
index a7fb6e5..5a0582d 100644
--- a/gcc/config/mmix/mmix.h
+++ b/gcc/config/mmix/mmix.h
@@ -81,11 +81,6 @@ along with GCC; see the file COPYING3. If not see
#define MMIX_FUNCTION_ARG_SIZE(MODE, TYPE) \
((MODE) != BLKmode ? GET_MODE_SIZE (MODE) : int_size_in_bytes (TYPE))
-/* Declarations for helper variables that are not tied to a particular
- target macro. */
-extern GTY(()) rtx mmix_compare_op0;
-extern GTY(()) rtx mmix_compare_op1;
-
/* Per-function machine data. This is normally an opaque type just
defined and used in the tm.c file, but we need to see the definition in
mmix.md too. */
diff --git a/gcc/config/mmix/mmix.md b/gcc/config/mmix/mmix.md
index aa878af..44263e47 100644
--- a/gcc/config/mmix/mmix.md
+++ b/gcc/config/mmix/mmix.md
@@ -440,30 +440,6 @@ DIVU %1,%1,%2\;GET %0,:rR\;NEGU %2,0,%0\;CSNN %0,$255,%2")
""
"NOR %0,%1,0")
-;; Since we don't have cc0, we do what is recommended in the manual;
-;; store away the operands for use in the branch, scc or movcc insn.
-(define_expand "cmpdi"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "mmix_reg_or_8bit_operand" "")]
- ""
- "
-{
- mmix_compare_op0 = operands[0];
- mmix_compare_op1 = operands[1];
- DONE;
-}")
-
-(define_expand "cmpdf"
- [(match_operand:DF 0 "register_operand" "")
- (match_operand:DF 1 "register_operand" "")]
- ""
- "
-{
- mmix_compare_op0 = operands[0];
- mmix_compare_op1 = operands[1];
- DONE;
-}")
-
;; When the user-patterns expand, the resulting insns will match the
;; patterns below.
@@ -474,7 +450,7 @@ DIVU %1,%1,%2\;GET %0,:rR\;NEGU %2,0,%0\;CSNN %0,$255,%2")
;; unsigned, so that has to be done another way.
;; FIXME: Perhaps a peep2 changing CCcode to a new code, that
;; gets folded here.
-(define_insn "*cmpcc_folded"
+(define_insn "*cmpdi_folded"
[(set (match_operand:CC 0 "register_operand" "=r")
(compare:CC
(match_operand:DI 1 "register_operand" "r")
@@ -485,7 +461,7 @@ DIVU %1,%1,%2\;GET %0,:rR\;NEGU %2,0,%0\;CSNN %0,$255,%2")
&& REGNO (operands[1]) == REGNO (operands[0])"
"%% folded: cmp %0,%1,0")
-(define_insn "*cmpcc"
+(define_insn "*cmps"
[(set (match_operand:CC 0 "register_operand" "=r")
(compare:CC
(match_operand:DI 1 "register_operand" "r")
@@ -724,7 +700,8 @@ DIVU %1,%1,%2\;GET %0,:rR\;NEGU %2,0,%0\;CSNN %0,$255,%2")
;; 0 to use in movdfcc.
(define_expand "movdfcc"
- [(set (match_operand:DF 0 "register_operand" "")
+ [(set (match_dup 4) (match_dup 5))
+ (set (match_operand:DF 0 "register_operand" "")
(if_then_else:DF
(match_operand 1 "comparison_operator" "")
(match_operand:DF 2 "mmix_reg_or_0_operand" "")
@@ -733,15 +710,20 @@ DIVU %1,%1,%2\;GET %0,:rR\;NEGU %2,0,%0\;CSNN %0,$255,%2")
"
{
enum rtx_code code = GET_CODE (operands[1]);
- rtx cc_reg = mmix_gen_compare_reg (code, mmix_compare_op0,
- mmix_compare_op1);
- if (cc_reg == NULL_RTX)
+ if (code == LE || code == GE)
FAIL;
- operands[1] = gen_rtx_fmt_ee (code, VOIDmode, cc_reg, const0_rtx);
+
+ operands[4] = mmix_gen_compare_reg (code, XEXP (operands[1], 0),
+ XEXP (operands[1], 1));
+ operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
+ XEXP (operands[1], 0),
+ XEXP (operands[1], 1));
+ operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[4], const0_rtx);
}")
(define_expand "movdicc"
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_dup 4) (match_dup 5))
+ (set (match_operand:DI 0 "register_operand" "")
(if_then_else:DI
(match_operand 1 "comparison_operator" "")
(match_operand:DI 2 "mmix_reg_or_8bit_operand" "")
@@ -750,11 +732,15 @@ DIVU %1,%1,%2\;GET %0,:rR\;NEGU %2,0,%0\;CSNN %0,$255,%2")
"
{
enum rtx_code code = GET_CODE (operands[1]);
- rtx cc_reg = mmix_gen_compare_reg (code, mmix_compare_op0,
- mmix_compare_op1);
- if (cc_reg == NULL_RTX)
+ if (code == LE || code == GE)
FAIL;
- operands[1] = gen_rtx_fmt_ee (code, VOIDmode, cc_reg, const0_rtx);
+
+ operands[4] = mmix_gen_compare_reg (code, XEXP (operands[1], 0),
+ XEXP (operands[1], 1));
+ operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
+ XEXP (operands[1], 0),
+ XEXP (operands[1], 1));
+ operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[4], const0_rtx);
}")
;; FIXME: Is this the right way to do "folding" of CCmode -> DImode?
@@ -854,175 +840,65 @@ DIVU %1,%1,%2\;GET %0,:rR\;NEGU %2,0,%0\;CSNN %0,$255,%2")
CS%d2 %0,%3,%1
ZS%d2 %0,%3,%1")
-;; FIXME: scc patterns will probably help, I just skip them
+;; FIXME: scc insns will probably help, I just skip them
;; right now. Revisit.
-(define_expand "beq"
- [(set (pc)
- (if_then_else (eq (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1]
- = mmix_gen_compare_reg (EQ, mmix_compare_op0, mmix_compare_op1);
-}")
-
-(define_expand "bne"
- [(set (pc)
- (if_then_else (ne (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
+(define_expand "cbranchdi4"
+ [(set (match_dup 4)
+ (match_op_dup 5
+ [(match_operand:DI 1 "register_operand" "")
+ (match_operand:DI 2 "mmix_reg_or_8bit_operand" "")]))
+ (set (pc)
+ (if_then_else
+ (match_operator 0 "ordered_comparison_operator"
+ [(match_dup 4)
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
""
"
{
- operands[1]
- = mmix_gen_compare_reg (NE, mmix_compare_op0, mmix_compare_op1);
+ operands[4] = mmix_gen_compare_reg (GET_CODE (operands[0]),
+ operands[1], operands[2]);
+ operands[5] = gen_rtx_fmt_ee (COMPARE,
+ GET_MODE (operands[4]),
+ operands[1], operands[2]);
}")
-(define_expand "bgt"
- [(set (pc)
- (if_then_else (gt (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
+(define_expand "cbranchdf4"
+ [(set (match_dup 4)
+ (match_op_dup 5
+ [(match_operand:DF 1 "register_operand" "")
+ (match_operand:DF 2 "register_operand" "")]))
+ (set (pc)
+ (if_then_else
+ (match_operator 0 "float_comparison_operator"
+ [(match_dup 4)
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
""
"
{
- operands[1]
- = mmix_gen_compare_reg (GT, mmix_compare_op0, mmix_compare_op1);
-}")
-
-(define_expand "ble"
- [(set (pc)
- (if_then_else (le (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1]
- = mmix_gen_compare_reg (LE, mmix_compare_op0, mmix_compare_op1);
-
/* The head comment of optabs.c:can_compare_p says we're required to
implement this, so we have to clean up the mess here. */
- if (operands[1] == NULL_RTX)
+ if (GET_CODE (operands[0]) == LE || GET_CODE (operands[0]) == GE)
{
- /* FIXME: Watch out for sharing/unsharing of rtx:es. */
- emit_jump_insn ((*bcc_gen_fctn[(int) LT]) (operands[0]));
- emit_jump_insn ((*bcc_gen_fctn[(int) EQ]) (operands[0]));
+ enum rtx_code ltgt_code = GET_CODE (operands[0]) == LE ? LT : GT;
+ emit_cmp_and_jump_insns (operands[1], operands[2], ltgt_code, NULL_RTX,
+ DFmode, 0, operands[3]);
+ emit_cmp_and_jump_insns (operands[1], operands[2], EQ, NULL_RTX,
+ DFmode, 0, operands[3]);
DONE;
}
-}")
-
-(define_expand "bge"
- [(set (pc)
- (if_then_else (ge (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1]
- = mmix_gen_compare_reg (GE, mmix_compare_op0, mmix_compare_op1);
- /* The head comment of optabs.c:can_compare_p says we're required to
- implement this, so we have to clean up the mess here. */
- if (operands[1] == NULL_RTX)
- {
- /* FIXME: Watch out for sharing/unsharing of rtx:es. */
- emit_jump_insn ((*bcc_gen_fctn[(int) GT]) (operands[0]));
- emit_jump_insn ((*bcc_gen_fctn[(int) EQ]) (operands[0]));
- DONE;
- }
+ operands[4] = mmix_gen_compare_reg (GET_CODE (operands[0]),
+ operands[1], operands[2]);
+ operands[5] = gen_rtx_fmt_ee (COMPARE,
+ GET_MODE (operands[4]),
+ operands[1], operands[2]);
}")
-(define_expand "blt"
- [(set (pc)
- (if_then_else (lt (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1]
- = mmix_gen_compare_reg (LT, mmix_compare_op0, mmix_compare_op1);
-}")
-
-(define_expand "bgtu"
- [(set (pc)
- (if_then_else (gtu (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1]
- = mmix_gen_compare_reg (GTU, mmix_compare_op0, mmix_compare_op1);
-}")
-
-(define_expand "bleu"
- [(set (pc)
- (if_then_else (leu (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1]
- = mmix_gen_compare_reg (LEU, mmix_compare_op0, mmix_compare_op1);
-}")
-
-(define_expand "bgeu"
- [(set (pc)
- (if_then_else (geu (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1]
- = mmix_gen_compare_reg (GEU, mmix_compare_op0, mmix_compare_op1);
-}")
-
-(define_expand "bltu"
- [(set (pc)
- (if_then_else (ltu (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1]
- = mmix_gen_compare_reg (LTU, mmix_compare_op0, mmix_compare_op1);
-}")
-
-(define_expand "bunordered"
- [(set (pc)
- (if_then_else (unordered (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1]
- = mmix_gen_compare_reg (UNORDERED, mmix_compare_op0, mmix_compare_op1);
-
- if (operands[1] == NULL_RTX)
- FAIL;
-}")
-
-(define_expand "bordered"
- [(set (pc)
- (if_then_else (ordered (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1]
- = mmix_gen_compare_reg (ORDERED, mmix_compare_op0, mmix_compare_op1);
-}")
;; FIXME: we can emit an unordered-or-*not*-equal compare in one insn, but
;; there's no RTL code for it. Maybe revisit in future.
diff --git a/gcc/config/mmix/predicates.md b/gcc/config/mmix/predicates.md
index 5c5792e..b5773b8 100644
--- a/gcc/config/mmix/predicates.md
+++ b/gcc/config/mmix/predicates.md
@@ -17,6 +17,11 @@
;; along with GCC; see the file COPYING3. If not see
;; <http://www.gnu.org/licenses/>.
+;; Return 1 if OP is a valid comparison operator for "cbranch" instructions.
+;; LE and GE are further lowered by the cbranchdf4 pattern.
+(define_predicate "float_comparison_operator"
+ (match_code "ne, eq, le, ge, lt, gt, ordered, unordered"))
+
;; 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). */