aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/mips/mips.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/mips/mips.c')
-rw-r--r--gcc/config/mips/mips.c61
1 files changed, 47 insertions, 14 deletions
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 600d512..a12e82a 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -3116,6 +3116,27 @@ mips_zero_if_equal (rtx cmp0, rtx cmp1)
cmp0, cmp1, 0, 0, OPTAB_DIRECT);
}
+/* Convert *CODE into a code that can be used in a floating-point
+ scc instruction (c.<cond>.<fmt>). Return true if the values of
+ the condition code registers will be inverted, with 0 indicating
+ that the condition holds. */
+
+static bool
+mips_reverse_fp_cond_p (enum rtx_code *code)
+{
+ switch (*code)
+ {
+ case NE:
+ case LTGT:
+ case ORDERED:
+ *code = reverse_condition_maybe_unordered (*code);
+ return true;
+
+ default:
+ return false;
+ }
+}
+
/* Convert a comparison into something that can be used in a branch or
conditional move. cmp_operands[0] and cmp_operands[1] are the values
being compared and *CODE is the code used to compare them.
@@ -3173,20 +3194,8 @@ mips_emit_compare (enum rtx_code *code, rtx *op0, rtx *op1, bool need_eq_ne_p)
Set CMP_CODE to the code of the comparison instruction and
*CODE to the code that the branch or move should use. */
- switch (*code)
- {
- case NE:
- case LTGT:
- case ORDERED:
- cmp_code = reverse_condition_maybe_unordered (*code);
- *code = EQ;
- break;
-
- default:
- cmp_code = *code;
- *code = NE;
- break;
- }
+ cmp_code = *code;
+ *code = mips_reverse_fp_cond_p (&cmp_code) ? EQ : NE;
*op0 = (ISA_HAS_8CC
? gen_reg_rtx (CCmode)
: gen_rtx_REG (CCmode, FPSW_REGNUM));
@@ -3232,6 +3241,30 @@ gen_conditional_branch (rtx *operands, enum rtx_code code)
emit_jump_insn (gen_condjump (condition, operands[0]));
}
+/* Implement:
+
+ (set temp (COND:CCV2 CMP_OP0 CMP_OP1))
+ (set DEST (unspec [TRUE_SRC FALSE_SRC temp] UNSPEC_MOVE_TF_PS)) */
+
+void
+mips_expand_vcondv2sf (rtx dest, rtx true_src, rtx false_src,
+ enum rtx_code cond, rtx cmp_op0, rtx cmp_op1)
+{
+ rtx cmp_result;
+ bool reversed_p;
+
+ reversed_p = mips_reverse_fp_cond_p (&cond);
+ cmp_result = gen_reg_rtx (CCV2mode);
+ emit_insn (gen_scc_ps (cmp_result,
+ gen_rtx_fmt_ee (cond, VOIDmode, cmp_op0, cmp_op1)));
+ if (reversed_p)
+ emit_insn (gen_mips_cond_move_tf_ps (dest, false_src, true_src,
+ cmp_result));
+ else
+ emit_insn (gen_mips_cond_move_tf_ps (dest, true_src, false_src,
+ cmp_result));
+}
+
/* Emit the common code for conditional moves. OPERANDS is the array
of operands passed to the conditional move define_expand. */