| Index: gcc/gcc/config/mmix/mmix.md
|
| diff --git a/gcc/gcc/config/mmix/mmix.md b/gcc/gcc/config/mmix/mmix.md
|
| index aa878af0f825e983f9c711f430fcdef2f586d6da..8c3109b57b3ba042d6d44474dc36e90c3a120d0d 100644
|
| --- a/gcc/gcc/config/mmix/mmix.md
|
| +++ b/gcc/gcc/config/mmix/mmix.md
|
| @@ -333,7 +333,7 @@
|
| ;; The %2-is-%1-case is there just to make sure things don't fail. Could
|
| ;; presumably happen with optimizations off; no evidence.
|
| (define_insn "*divdi3_nonknuth"
|
| - [(set (match_operand:DI 0 "register_operand" "=&r,r")
|
| + [(set (match_operand:DI 0 "register_operand" "=&r,&r")
|
| (div:DI (match_operand:DI 1 "register_operand" "r,r")
|
| (match_operand:DI 2 "register_operand" "1,r")))
|
| (clobber (match_scratch:DI 3 "=1,1"))
|
| @@ -359,7 +359,7 @@ DIVU %0,%1,%2\;NEGU %1,0,%0\;CSN %0,$255,%1")
|
| ;; The %2-is-%1-case is there just to make sure things don't fail. Could
|
| ;; presumably happen with optimizations off; no evidence.
|
| (define_insn "*moddi3_nonknuth"
|
| - [(set (match_operand:DI 0 "register_operand" "=&r,r")
|
| + [(set (match_operand:DI 0 "register_operand" "=&r,&r")
|
| (mod:DI (match_operand:DI 1 "register_operand" "r,r")
|
| (match_operand:DI 2 "register_operand" "1,r")))
|
| (clobber (match_scratch:DI 3 "=1,1"))
|
| @@ -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.
|
|
|