aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/i386/i386.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/i386/i386.c')
-rw-r--r--gcc/config/i386/i386.c80
1 files changed, 60 insertions, 20 deletions
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 9fc4425..9c755a5 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -1373,7 +1373,7 @@ memory_displacement_operand (op, mode)
return parts.disp != NULL_RTX;
}
-/* To avoid problems when jump re-emits comparisons like testqi_ext_0,
+/* To avoid problems when jump re-emits comparisons like testqi_ext_ccno_0,
re-recognize the operand to avoid a copy_to_mode_reg that will fail.
??? It seems likely that this will only work because cmpsi is an
@@ -4252,6 +4252,45 @@ ix86_unary_operator_ok (code, mode, operands)
return TRUE;
}
+/* Return TRUE or FALSE depending on whether the first SET in INSN
+ has source and destination with matching CC modes, and that the
+ CC mode is at least as constrained as REQ_MODE. */
+
+int
+ix86_match_ccmode (insn, req_mode)
+ rtx insn;
+ enum machine_mode req_mode;
+{
+ rtx set;
+ enum machine_mode set_mode;
+
+ set = PATTERN (insn);
+ if (GET_CODE (set) == PARALLEL)
+ set = XVECEXP (set, 0, 0);
+ if (GET_CODE (set) != SET)
+ abort ();
+
+ set_mode = GET_MODE (SET_DEST (set));
+ switch (set_mode)
+ {
+ case CCmode:
+ if (req_mode == CCNOmode)
+ return 0;
+ /* FALLTHRU */
+ case CCNOmode:
+ if (req_mode == CCZmode)
+ return 0;
+ /* FALLTHRU */
+ case CCZmode:
+ break;
+
+ default:
+ abort ();
+ }
+
+ return (GET_MODE (SET_SRC (set)) == set_mode);
+}
+
/* Produce an unsigned comparison for a given signed comparison. */
static enum rtx_code
@@ -4455,7 +4494,7 @@ ix86_expand_fp_compare (code, op0, op1, unordered)
abort ();
}
- emit_insn (gen_testqi_ext_0 (tmp, GEN_INT (mask)));
+ emit_insn (gen_testqi_ext_ccno_0 (tmp, GEN_INT (mask)));
intcmp_mode = CCNOmode;
}
}
@@ -4470,7 +4509,7 @@ ix86_expand_fp_compare (code, op0, op1, unordered)
switch (code)
{
case GT:
- emit_insn (gen_testqi_ext_0 (tmp, GEN_INT (0x45)));
+ emit_insn (gen_testqi_ext_ccno_0 (tmp, GEN_INT (0x45)));
code = EQ;
break;
case LT:
@@ -4480,7 +4519,7 @@ ix86_expand_fp_compare (code, op0, op1, unordered)
code = EQ;
break;
case GE:
- emit_insn (gen_testqi_ext_0 (tmp, GEN_INT (0x05)));
+ emit_insn (gen_testqi_ext_ccno_0 (tmp, GEN_INT (0x05)));
code = EQ;
break;
case LE:
@@ -5490,7 +5529,8 @@ ix86_expand_strlensi_unroll_1 (out, align_rtx, scratch)
rtx align_4_label = gen_label_rtx ();
rtx end_0_label = gen_label_rtx ();
rtx mem;
- rtx flags = gen_rtx_REG (CCNOmode, FLAGS_REG);
+ rtx no_flags = gen_rtx_REG (CCNOmode, FLAGS_REG);
+ rtx z_flags = gen_rtx_REG (CCNOmode, FLAGS_REG);
rtx tmpreg = gen_reg_rtx (SImode);
align = 0;
@@ -5512,25 +5552,25 @@ ix86_expand_strlensi_unroll_1 (out, align_rtx, scratch)
align_rtx = expand_binop (SImode, and_optab, scratch, GEN_INT (3),
NULL_RTX, 0, OPTAB_WIDEN);
- emit_insn (gen_cmpsi_0 (align_rtx, const0_rtx));
+ emit_insn (gen_cmpsi_ccz_1 (align_rtx, const0_rtx));
- tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
+ tmp = gen_rtx_EQ (VOIDmode, z_flags, const0_rtx);
tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
gen_rtx_LABEL_REF (VOIDmode,
align_4_label),
pc_rtx);
emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
- emit_insn (gen_cmpsi_1 (align_rtx, GEN_INT (2)));
+ emit_insn (gen_cmpsi_ccno_1 (align_rtx, GEN_INT (2)));
- tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
+ tmp = gen_rtx_EQ (VOIDmode, no_flags, const0_rtx);
tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
gen_rtx_LABEL_REF (VOIDmode,
align_2_label),
pc_rtx);
emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
- tmp = gen_rtx_GTU (VOIDmode, flags, const0_rtx);
+ tmp = gen_rtx_GTU (VOIDmode, no_flags, const0_rtx);
tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
gen_rtx_LABEL_REF (VOIDmode,
align_3_label),
@@ -5545,9 +5585,9 @@ ix86_expand_strlensi_unroll_1 (out, align_rtx, scratch)
align_rtx = expand_binop (SImode, and_optab, scratch, GEN_INT (2),
NULL_RTX, 0, OPTAB_WIDEN);
- emit_insn (gen_cmpsi_0 (align_rtx, const0_rtx));
+ emit_insn (gen_cmpsi_ccz_1 (align_rtx, const0_rtx));
- tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
+ tmp = gen_rtx_EQ (VOIDmode, z_flags, const0_rtx);
tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
gen_rtx_LABEL_REF (VOIDmode,
align_4_label),
@@ -5560,9 +5600,9 @@ ix86_expand_strlensi_unroll_1 (out, align_rtx, scratch)
/* Now compare the bytes. */
/* Compare the first n unaligned byte on a byte per byte basis. */
- emit_insn (gen_cmpqi_0 (mem, const0_rtx));
+ emit_insn (gen_cmpqi_ccz_1 (mem, const0_rtx));
- tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
+ tmp = gen_rtx_EQ (VOIDmode, z_flags, const0_rtx);
tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
gen_rtx_LABEL_REF (VOIDmode, end_0_label),
pc_rtx);
@@ -5576,9 +5616,9 @@ ix86_expand_strlensi_unroll_1 (out, align_rtx, scratch)
{
emit_label (align_2_label);
- emit_insn (gen_cmpqi_0 (mem, const0_rtx));
+ emit_insn (gen_cmpqi_ccz_1 (mem, const0_rtx));
- tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
+ tmp = gen_rtx_EQ (VOIDmode, z_flags, const0_rtx);
tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
gen_rtx_LABEL_REF (VOIDmode,
end_0_label),
@@ -5590,9 +5630,9 @@ ix86_expand_strlensi_unroll_1 (out, align_rtx, scratch)
emit_label (align_3_label);
}
- emit_insn (gen_cmpqi_0 (mem, const0_rtx));
+ emit_insn (gen_cmpqi_ccz_1 (mem, const0_rtx));
- tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
+ tmp = gen_rtx_EQ (VOIDmode, z_flags, const0_rtx);
tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
gen_rtx_LABEL_REF (VOIDmode, end_0_label),
pc_rtx);
@@ -5626,7 +5666,7 @@ ix86_expand_strlensi_unroll_1 (out, align_rtx, scratch)
emit_insn (gen_lshrsi3 (reg, reg, GEN_INT (16)));
/* If zero is not in the first two bytes, move two bytes forward. */
- emit_insn (gen_testsi_1 (tmpreg, GEN_INT (0x8080)));
+ emit_insn (gen_testsi_ccno_1 (tmpreg, GEN_INT (0x8080)));
tmp = gen_rtx_REG (CCNOmode, FLAGS_REG);
tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
emit_insn (gen_rtx_SET (VOIDmode, tmpreg,
@@ -5650,7 +5690,7 @@ ix86_expand_strlensi_unroll_1 (out, align_rtx, scratch)
rtx end_2_label = gen_label_rtx ();
/* Is zero in the first two bytes? */
- emit_insn (gen_testsi_1 (tmpreg, GEN_INT (0x8080)));
+ emit_insn (gen_testsi_ccno_1 (tmpreg, GEN_INT (0x8080)));
tmp = gen_rtx_REG (CCNOmode, FLAGS_REG);
tmp = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,