diff options
author | Jan Hubicka <jh@suse.cz> | 2000-09-15 17:48:45 +0000 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2000-09-15 17:48:45 +0000 |
commit | 9076b9c1ac147fc876dc34f0077065e374fdaa09 (patch) | |
tree | 946db031b91b5cd29cc9f11f74f58711b01523f1 /gcc | |
parent | 5eca72d98021cb04fae2e5b02b3ad84e09ce046b (diff) | |
download | gcc-9076b9c1ac147fc876dc34f0077065e374fdaa09.zip gcc-9076b9c1ac147fc876dc34f0077065e374fdaa09.tar.gz gcc-9076b9c1ac147fc876dc34f0077065e374fdaa09.tar.bz2 |
i386-protos.h (no_comparison_operator, [...]): Remove.
* i386-protos.h (no_comparison_operator, uno_comparison_operator):
Remove.
(ix86_comparison_operator, ix86_cc_mode): Declare
* i386.h (CCGC, CCGCO): New modes.
(SELECT_CC_MODE): Move offline to ....
* i386.c (ix86_cc_mode): .... here; use new modes.
(ix86_comparison_operator): New.
(fcmov_comparison_operator): Ensure proper mode.
(put_condition_mode): More sanity checking.
(ix86_match_ccmode): Handle new modes.
(ix86_expand_fp_compare): GEU requires CCmode.
(ix86_expand_strlensi_unroll_1): Use emit_cmp_and_jump_insn instead of
doing it by hand.
* i386.md (cmp?i_ccz_1): Remove
(cmp?i_ccno_1): Use ix86_match_ccmode.
(cmp?i_minus_1): New.
(cmpsi_1): New expander.
(cmpqi_ext_1): Use match_ccmode
(cmpqi_ext_3): New expander.
(cmpqi_ext_3_insn): Rename from cmpqi_ext_3.
(cmpqi_ext_4): Use match_ccmode.
(add?i_?): Use match_ccmode.
(add?i_6): New.
(test?i_ccz_1): Remove
(test?i_1): New.
(testsi_ccno_1, testqi_ccz_1, testqi_ext_ccno_0): New expander.
(testqi_ext_0): Use ix86_match_ccmode.
(*xorqi_cc_ext_1): Use ix86_match_ccmode.
(xorqi_cc_ext_1): New expander.
(shift patterns): Use CCGOCmode for all shifts except for sar.
(setcc_?, jcc_?, miv?icc_nic): Use ix86_comparison_operator.
(setcc_3, jcc_3, miv?icc_c): Remove.
From-SVN: r36442
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 35 | ||||
-rw-r--r-- | gcc/config/i386/i386-protos.h | 4 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 204 | ||||
-rw-r--r-- | gcc/config/i386/i386.h | 27 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 535 |
5 files changed, 488 insertions, 317 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3a628e4..f57d5df 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,38 @@ +Fri Sep 15 19:45:55 MET DST 2000 Jan Hubicka <jh@suse.cz> + + * i386-protos.h (no_comparison_operator, uno_comparison_operator): + Remove. + (ix86_comparison_operator, ix86_cc_mode): Declare + * i386.h (CCGC, CCGCO): New modes. + (SELECT_CC_MODE): Move offline to .... + * i386.c (ix86_cc_mode): .... here; use new modes. + (ix86_comparison_operator): New. + (fcmov_comparison_operator): Ensure proper mode. + (put_condition_mode): More sanity checking. + (ix86_match_ccmode): Handle new modes. + (ix86_expand_fp_compare): GEU requires CCmode. + (ix86_expand_strlensi_unroll_1): Use emit_cmp_and_jump_insn instead of + doing it by hand. + * i386.md (cmp?i_ccz_1): Remove + (cmp?i_ccno_1): Use ix86_match_ccmode. + (cmp?i_minus_1): New. + (cmpsi_1): New expander. + (cmpqi_ext_1): Use match_ccmode + (cmpqi_ext_3): New expander. + (cmpqi_ext_3_insn): Rename from cmpqi_ext_3. + (cmpqi_ext_4): Use match_ccmode. + (add?i_?): Use match_ccmode. + (add?i_6): New. + (test?i_ccz_1): Remove + (test?i_1): New. + (testsi_ccno_1, testqi_ccz_1, testqi_ext_ccno_0): New expander. + (testqi_ext_0): Use ix86_match_ccmode. + (*xorqi_cc_ext_1): Use ix86_match_ccmode. + (xorqi_cc_ext_1): New expander. + (shift patterns): Use CCGOCmode for all shifts except for sar. + (setcc_?, jcc_?, miv?icc_nic): Use ix86_comparison_operator. + (setcc_3, jcc_3, miv?icc_c): Remove. + 2000-09-15 Will Cohen <wcohen@redhat.com> * dwarf2out.c (add_const_value_attribute): Changed array into a diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index 7ffb299..c7bd3d8 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -56,11 +56,10 @@ extern int general_no_elim_operand PARAMS ((rtx, enum machine_mode)); extern int nonmemory_no_elim_operand PARAMS ((rtx, enum machine_mode)); extern int q_regs_operand PARAMS ((rtx, enum machine_mode)); extern int non_q_regs_operand PARAMS ((rtx, enum machine_mode)); -extern int no_comparison_operator PARAMS ((rtx, enum machine_mode)); extern int sse_comparison_operator PARAMS ((rtx, enum machine_mode)); extern int fcmov_comparison_operator PARAMS ((rtx, enum machine_mode)); -extern int uno_comparison_operator PARAMS ((rtx, enum machine_mode)); extern int cmp_fp_expander_operand PARAMS ((rtx, enum machine_mode)); +extern int ix86_comparison_operator PARAMS ((rtx, enum machine_mode)); extern int ext_register_operand PARAMS ((rtx, enum machine_mode)); extern int binary_fp_operator PARAMS ((rtx, enum machine_mode)); extern int mult_operator PARAMS ((rtx, enum machine_mode)); @@ -71,6 +70,7 @@ extern int memory_displacement_operand PARAMS ((rtx, enum machine_mode)); extern int cmpsi_operand PARAMS ((rtx, enum machine_mode)); extern int long_memory_operand PARAMS ((rtx, enum machine_mode)); extern int aligned_operand PARAMS ((rtx, enum machine_mode)); +extern enum machine_mode ix86_cc_mode PARAMS ((enum rtx_code, rtx, rtx)); extern int legitimate_pic_address_disp_p PARAMS ((rtx)); diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 7485d19..f189e4b 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -1282,47 +1282,58 @@ sse_comparison_operator (op, mode) enum rtx_code code = GET_CODE (op); return code == EQ || code == LT || code == LE || code == UNORDERED; } - -/* Return 1 if OP is a comparison operator that can be issued by fcmov. */ - +/* Return 1 if OP is a valid comparison operator in valid mode. */ int -fcmov_comparison_operator (op, mode) - register rtx op; - enum machine_mode mode; +ix86_comparison_operator (op, mode) + register rtx op; + enum machine_mode mode; { + enum machine_mode inmode; if (mode != VOIDmode && GET_MODE (op) != mode) return 0; - switch (GET_CODE (op)) { case EQ: case NE: - case LEU: case LTU: case GEU: case GTU: - case UNORDERED: case ORDERED: return 1; - + case LT: case GE: + inmode = GET_MODE (XEXP (op, 0)); + if (inmode == CCmode || inmode == CCGCmode + || inmode == CCGOCmode || inmode == CCNOmode) + return 1; + return 0; + case LTU: case GTU: case LEU: case ORDERED: case UNORDERED: case GEU: + inmode = GET_MODE (XEXP (op, 0)); + if (inmode == CCmode) + return 1; + return 0; + case GT: case LE: + inmode = GET_MODE (XEXP (op, 0)); + if (inmode == CCmode || inmode == CCGCmode || inmode == CCNOmode) + return 1; + return 0; default: return 0; } } -/* Return 1 if OP is any normal comparison operator plus {UN}ORDERED. */ +/* Return 1 if OP is a comparison operator that can be issued by fcmov. */ -int -uno_comparison_operator (op, mode) +int +fcmov_comparison_operator (op, mode) register rtx op; enum machine_mode mode; { + enum machine_mode inmode = GET_MODE (XEXP (op, 0)); if (mode != VOIDmode && GET_MODE (op) != mode) return 0; - switch (GET_CODE (op)) { case EQ: case NE: - case LE: case LT: case GE: case GT: - case LEU: case LTU: case GEU: case GTU: - case UNORDERED: case ORDERED: return 1; - + case LTU: case GTU: case LEU: case ORDERED: case UNORDERED: case GEU: + if (inmode == CCmode) + return 1; + return 0; default: return 0; } @@ -3091,40 +3102,52 @@ put_condition_code (code, mode, reverse, fp, file) suffix = "ne"; break; case GT: - if (mode == CCNOmode) + if (mode != CCmode && mode != CCNOmode && mode != CCGCmode) abort (); suffix = "g"; break; case GTU: /* ??? Use "nbe" instead of "a" for fcmov losage on some assemblers. Those same assemblers have the same but opposite losage on cmov. */ + if (mode != CCmode) + abort(); suffix = fp ? "nbe" : "a"; break; case LT: - if (mode == CCNOmode) + if (mode == CCNOmode || mode == CCGOCmode) suffix = "s"; - else + else if (mode == CCmode || mode == CCGCmode) suffix = "l"; + else + abort(); break; case LTU: + if (mode != CCmode) + abort(); suffix = "b"; break; case GE: - if (mode == CCNOmode) + if (mode == CCNOmode || mode == CCGOCmode) suffix = "ns"; - else + else if (mode == CCmode || mode == CCGCmode) suffix = "ge"; + else + abort(); break; case GEU: /* ??? As above. */ + if (mode != CCmode) + abort(); suffix = fp ? "nb" : "ae"; break; case LE: - if (mode == CCNOmode) + if (mode != CCmode && mode != CCGCmode && mode != CCNOmode) abort (); suffix = "le"; break; case LEU: + if (mode != CCmode) + abort (); suffix = "be"; break; case UNORDERED: @@ -4510,15 +4533,27 @@ ix86_match_ccmode (insn, req_mode) set = XVECEXP (set, 0, 0); if (GET_CODE (set) != SET) abort (); + if (GET_CODE (SET_SRC (set)) != COMPARE) + abort (); set_mode = GET_MODE (SET_DEST (set)); switch (set_mode) { + case CCNOmode: + if (req_mode != CCNOmode + && (req_mode != CCmode + || XEXP (SET_SRC (set), 1) != const0_rtx)) + return 0; + break; case CCmode: - if (req_mode == CCNOmode) + if (req_mode == CCGCmode) return 0; /* FALLTHRU */ - case CCNOmode: + case CCGCmode: + if (req_mode == CCGOCmode || req_mode == CCNOmode) + return 0; + /* FALLTHRU */ + case CCGOCmode: if (req_mode == CCZmode) return 0; /* FALLTHRU */ @@ -4628,6 +4663,49 @@ ix86_fp_compare_mode (code) return unordered ? CCFPUmode : CCFPmode; } +enum machine_mode +ix86_cc_mode (code, op0, op1) + enum rtx_code code; + rtx op0, op1; +{ + if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_FLOAT) + return ix86_fp_compare_mode (code); + switch (code) + { + /* Only zero flag is needed. */ + case EQ: /* ZF=0 */ + case NE: /* ZF!=0 */ + return CCZmode; + /* Codes needing carry flag. */ + case GEU: /* CF=0 */ + case GTU: /* CF=0 & ZF=0 */ + case LTU: /* CF=1 */ + case LEU: /* CF=1 | ZF=1 */ + return CCmode; + /* Codes possibly doable only with sign flag when + comparing against zero. */ + case GE: /* SF=OF or SF=0 */ + case LT: /* SF<>OF or SF=0 */ + if (op1 == const0_rtx) + return CCGOCmode; + else + /* For other cases Carry flag is not required. */ + return CCGCmode; + /* Codes doable only with sign flag when comparing + against zero, but we miss jump instruction for it + so we need to use relational tests agains overflow + that thus needs to be zero. */ + case GT: /* ZF=0 & SF=OF */ + case LE: /* ZF=1 | SF<>OF */ + if (op1 == const0_rtx) + return CCNOmode; + else + return CCGCmode; + default: + abort(); + } +} + /* Return true if we should use an FCOMI instruction for this fp comparison. */ int @@ -4872,6 +4950,7 @@ ix86_expand_fp_compare (code, op0, op1, scratch) emit_insn (gen_andqi_ext_0 (scratch, scratch, GEN_INT (0x45))); emit_insn (gen_addqi_ext_1 (scratch, scratch, constm1_rtx)); emit_insn (gen_cmpqi_ext_3 (scratch, GEN_INT (0x44))); + intcmp_mode = CCmode; code = GEU; break; case UNLE: @@ -5921,8 +6000,6 @@ 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 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; @@ -5944,30 +6021,12 @@ 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_ccz_1 (align_rtx, 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_ccno_1 (align_rtx, GEN_INT (2))); - - 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, no_flags, const0_rtx); - tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, - gen_rtx_LABEL_REF (VOIDmode, - align_3_label), - pc_rtx); - emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp)); + emit_cmp_and_jump_insns (align_rtx, const0_rtx, EQ, NULL, + SImode, 1, 0, align_4_label); + emit_cmp_and_jump_insns (align_rtx, GEN_INT (2), EQ, NULL, + SImode, 1, 0, align_2_label); + emit_cmp_and_jump_insns (align_rtx, GEN_INT (2), GTU, NULL, + SImode, 1, 0, align_3_label); } else { @@ -5977,14 +6036,8 @@ 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_ccz_1 (align_rtx, 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_cmp_and_jump_insns (align_rtx, const0_rtx, EQ, NULL, + SImode, 1, 0, align_4_label); } mem = gen_rtx_MEM (QImode, out); @@ -5992,13 +6045,8 @@ 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_ccz_1 (mem, 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); - emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp)); + emit_cmp_and_jump_insns (mem, const0_rtx, EQ, NULL, + QImode, 1, 0, end_0_label); /* Increment the address. */ emit_insn (gen_addsi3 (out, out, const1_rtx)); @@ -6008,27 +6056,16 @@ ix86_expand_strlensi_unroll_1 (out, align_rtx, scratch) { emit_label (align_2_label); - emit_insn (gen_cmpqi_ccz_1 (mem, 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); - emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp)); + emit_cmp_and_jump_insns (mem, const0_rtx, EQ, NULL, + QImode, 1, 0, end_0_label); emit_insn (gen_addsi3 (out, out, const1_rtx)); emit_label (align_3_label); } - emit_insn (gen_cmpqi_ccz_1 (mem, 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); - emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp)); + emit_cmp_and_jump_insns (mem, const0_rtx, EQ, NULL, + QImode, 1, 0, end_0_label); emit_insn (gen_addsi3 (out, out, const1_rtx)); } @@ -6049,7 +6086,8 @@ ix86_expand_strlensi_unroll_1 (out, align_rtx, scratch) emit_insn (gen_one_cmplsi2 (scratch, scratch)); emit_insn (gen_andsi3 (tmpreg, tmpreg, scratch)); emit_insn (gen_andsi3 (tmpreg, tmpreg, GEN_INT (0x80808080))); - emit_cmp_and_jump_insns (tmpreg, const0_rtx, EQ, 0, SImode, 1, 0, align_4_label); + emit_cmp_and_jump_insns (tmpreg, const0_rtx, EQ, 0, + SImode, 1, 0, align_4_label); if (TARGET_CMOVE) { diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index ab0b536..c8b3c98 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -2257,14 +2257,25 @@ while (0) For the i386, we need separate modes when floating-point equality comparisons are being done. + + Add CCNO to indicate comparisons against zero that requires + No Overflow. Sign bit test is used instead and thus + can be used to form "a&b>0" type of tests. + + Add CCGC to indicate comparisons agains zero that allows + unspecified garbage in the Carry flag. This mode is used + by inc/dec instructions. - Add CCNO to indicate No Overflow, which is often also includes - No Carry. This is typically used on the output of logicals, - and is only valid in comparisons against zero. + Add CCGCO to indicate comparisons agains zero that allows + unspecified garbage in the Carry and Overflow flag. This + mode is used to simulate comparisons of (a-b) and (a+b) + against zero using sub/cmp/add operations. Add CCZ to indicate that only the Zero flag is valid. */ #define EXTRA_CC_MODES \ + CC(CCGCmode, "CCGC") \ + CC(CCGOCmode, "CCGOC") \ CC(CCNOmode, "CCNO") \ CC(CCZmode, "CCZ") \ CC(CCFPmode, "CCFP") \ @@ -2279,12 +2290,7 @@ while (0) For integer comparisons against zero, reduce to CCNOmode or CCZmode if possible, to allow for more combinations. */ -#define SELECT_CC_MODE(OP,X,Y) \ - (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \ - ? (OP) == EQ || (OP) == NE ? CCFPUmode : CCFPmode \ - : (OP) == LE || (OP) == GT ? CCmode \ - : (Y) != const0_rtx ? CCmode \ - : (OP) == EQ || (OP) == NE ? CCZmode : CCNOmode) +#define SELECT_CC_MODE(OP,X,Y) ix86_cc_mode (OP, X, Y) /* Control the assembler format that we output, to the extent this does not vary between assemblers. */ @@ -2591,10 +2597,9 @@ do { long l; \ {"nonmemory_no_elim_operand", {CONST_INT, REG, SUBREG}}, \ {"q_regs_operand", {SUBREG, REG}}, \ {"non_q_regs_operand", {SUBREG, REG}}, \ - {"no_comparison_operator", {EQ, NE, LT, GE, LTU, GTU, LEU, GEU}}, \ {"fcmov_comparison_operator", {EQ, NE, LTU, GTU, LEU, GEU}}, \ {"sse_comparison_operator", {EQ, LT, LE, UNORDERED }}, \ - {"uno_comparison_operator", {EQ, NE, LE, LT, GE, GT, LEU, LTU, GEU, \ + {"ix86_comparison_operator", {EQ, NE, LE, LT, GE, GT, LEU, LTU, GEU, \ GTU, UNORDERED, ORDERED}}, \ {"cmp_fp_expander_operand", {CONST_DOUBLE, SUBREG, REG, MEM}}, \ {"ext_register_operand", {SUBREG, REG}}, \ diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 91ae7b8..b825e0f 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -1061,11 +1061,11 @@ DONE; }") -(define_insn "cmpsi_ccz_1" - [(set (reg:CCZ 17) - (compare:CCZ (match_operand:SI 0 "nonimmediate_operand" "r,?mr") - (match_operand:SI 1 "const0_operand" "n,n")))] - "" +(define_insn "*cmpsi_ccno_1" + [(set (reg 17) + (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr") + (match_operand:SI 1 "const0_operand" "n,n")))] + "ix86_match_ccmode (insn, CCNOmode)" "@ test{l}\\t{%0, %0|%0, %0} cmp{l}\\t{%1, %0|%0, %1}" @@ -1073,28 +1073,34 @@ (set_attr "length_immediate" "0,1") (set_attr "mode" "SI")]) -(define_insn "cmpsi_ccno_1" - [(set (reg:CCNO 17) - (compare:CCNO (match_operand:SI 0 "nonimmediate_operand" "r,?mr") - (match_operand:SI 1 "const0_operand" "n,n")))] - "" - "@ - test{l}\\t{%0, %0|%0, %0} - cmp{l}\\t{%1, %0|%0, %1}" - [(set_attr "type" "test,icmp") - (set_attr "length_immediate" "0,1") +(define_insn "*cmpsi_minus_1" + [(set (reg 17) + (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r") + (match_operand:SI 1 "general_operand" "ri,mr")) + (const_int 0)))] + "ix86_match_ccmode (insn, CCGOCmode)" + "cmp{l}\\t{%1, %0|%0, %1}" + [(set_attr "type" "icmp") (set_attr "mode" "SI")]) -(define_insn "cmpsi_1" +(define_expand "cmpsi_1" [(set (reg:CC 17) (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r") (match_operand:SI 1 "general_operand" "ri,mr")))] - "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" + "" + "") + +(define_insn "*cmpsi_1_insn" + [(set (reg 17) + (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r") + (match_operand:SI 1 "general_operand" "ri,mr")))] + "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) + && ix86_match_ccmode (insn, CCmode)" "cmp{l}\\t{%1, %0|%0, %1}" [(set_attr "type" "icmp") (set_attr "mode" "SI")]) -(define_insn "*cmphi_0" +(define_insn "*cmphi_ccno_1" [(set (reg 17) (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr") (match_operand:HI 1 "const0_operand" "n,n")))] @@ -1106,32 +1112,31 @@ (set_attr "length_immediate" "0,1") (set_attr "mode" "HI")]) -(define_insn "*cmphi_1" - [(set (reg:CC 17) - (compare:CC (match_operand:HI 0 "nonimmediate_operand" "rm,r") - (match_operand:HI 1 "general_operand" "ri,mr")))] - "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" +(define_insn "*cmphi_minus_1" + [(set (reg 17) + (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r") + (match_operand:HI 1 "general_operand" "ri,mr")) + (const_int 0)))] + "ix86_match_ccmode (insn, CCGOCmode)" "cmp{w}\\t{%1, %0|%0, %1}" [(set_attr "type" "icmp") (set_attr "mode" "HI")]) -(define_insn "cmpqi_ccz_1" - [(set (reg:CCZ 17) - (compare:CCZ (match_operand:QI 0 "nonimmediate_operand" "q,?mq") - (match_operand:QI 1 "const0_operand" "n,n")))] - "" - "@ - test{b}\\t{%0, %0|%0, %0} - cmp{b}\\t{$0, %0|%0, 0}" - [(set_attr "type" "test,icmp") - (set_attr "length_immediate" "0,1") - (set_attr "mode" "QI")]) +(define_insn "*cmphi_1" + [(set (reg 17) + (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r") + (match_operand:HI 1 "general_operand" "ri,mr")))] + "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) + && ix86_match_ccmode (insn, CCmode)" + "cmp{w}\\t{%1, %0|%0, %1}" + [(set_attr "type" "icmp") + (set_attr "mode" "HI")]) (define_insn "*cmpqi_ccno_1" - [(set (reg:CCNO 17) - (compare:CCNO (match_operand:QI 0 "nonimmediate_operand" "q,?mq") - (match_operand:QI 1 "const0_operand" "n,n")))] - "" + [(set (reg 17) + (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq") + (match_operand:QI 1 "const0_operand" "n,n")))] + "ix86_match_ccmode (insn, CCNOmode)" "@ test{b}\\t{%0, %0|%0, %0} cmp{b}\\t{$0, %0|%0, 0}" @@ -1140,24 +1145,35 @@ (set_attr "mode" "QI")]) (define_insn "*cmpqi_1" - [(set (reg:CC 17) - (compare:CC (match_operand:QI 0 "nonimmediate_operand" "qm,q") - (match_operand:QI 1 "general_operand" "qi,mq")))] - "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" + [(set (reg 17) + (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q") + (match_operand:QI 1 "general_operand" "qi,mq")))] + "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) + && ix86_match_ccmode (insn, CCmode)" "cmp{b}\\t{%1, %0|%0, %1}" [(set_attr "type" "icmp") (set_attr "mode" "QI")]) +(define_insn "*cmpqi_minus_1" + [(set (reg 17) + (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "rm,r") + (match_operand:QI 1 "general_operand" "ri,mr")) + (const_int 0)))] + "ix86_match_ccmode (insn, CCGOCmode)" + "cmp{w}\\t{%1, %0|%0, %1}" + [(set_attr "type" "icmp") + (set_attr "mode" "QI")]) + (define_insn "*cmpqi_ext_1" - [(set (reg:CC 17) - (compare:CC + [(set (reg 17) + (compare (match_operand:QI 0 "general_operand" "qm") (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "q") (const_int 8) (const_int 8)) 0)))] - "" + "ix86_match_ccmode (insn, CCmode)" "cmp{b}\\t{%h1, %0|%0, %h1}" [(set_attr "type" "icmp") (set_attr "mode" "QI")]) @@ -1177,7 +1193,7 @@ (set_attr "length_immediate" "0") (set_attr "mode" "QI")]) -(define_insn "cmpqi_ext_3" +(define_expand "cmpqi_ext_3" [(set (reg:CC 17) (compare:CC (subreg:QI @@ -1187,13 +1203,25 @@ (const_int 8)) 0) (match_operand:QI 1 "general_operand" "qmn")))] "" + "") + +(define_insn "cmpqi_ext_3_insn" + [(set (reg 17) + (compare + (subreg:QI + (zero_extract:SI + (match_operand 0 "ext_register_operand" "q") + (const_int 8) + (const_int 8)) 0) + (match_operand:QI 1 "general_operand" "qmn")))] + "ix86_match_ccmode (insn, CCmode)" "cmp{b}\\t{%1, %h0|%h0, %1}" [(set_attr "type" "icmp") (set_attr "mode" "QI")]) (define_insn "*cmpqi_ext_4" - [(set (reg:CC 17) - (compare:CC + [(set (reg 17) + (compare (subreg:QI (zero_extract:SI (match_operand 0 "ext_register_operand" "q") @@ -1204,7 +1232,7 @@ (match_operand 1 "ext_register_operand" "q") (const_int 8) (const_int 8)) 0)))] - "" + "ix86_match_ccmode (insn, CCmode)" "cmp{b}\\t{%h1, %h0|%h0, %h1}" [(set_attr "type" "icmp") (set_attr "mode" "QI")]) @@ -3955,7 +3983,7 @@ (const_int 0))) (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm") (plus:SI (match_dup 1) (match_dup 2)))] - "ix86_match_ccmode (insn, CCNOmode) + "ix86_match_ccmode (insn, CCGOCmode) && ix86_binary_operator_ok (PLUS, SImode, operands) /* Current assemblers are broken and do not allow @GOTOFF in ought but a memory context. */ @@ -4001,7 +4029,7 @@ (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni")) (match_operand:SI 1 "nonimmediate_operand" "%0"))) (clobber (match_scratch:SI 0 "=r"))] - "ix86_match_ccmode (insn, CCNOmode) + "ix86_match_ccmode (insn, CCGCmode) && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM) /* Current assemblers are broken and do not allow @GOTOFF in ought but a memory context. */ @@ -4043,12 +4071,13 @@ (set_attr "mode" "SI")]) (define_insn "*addsi_4" - [(set (reg:CC 17) - (compare:CC (neg:SI (match_operand:SI 2 "general_operand" "rmni,rni")) - (match_operand:SI 1 "nonimmediate_operand" "%0,0"))) + [(set (reg 17) + (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni,rni")) + (match_operand:SI 1 "nonimmediate_operand" "%0,0"))) (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm") (plus:SI (match_dup 1) (match_dup 2)))] "ix86_binary_operator_ok (PLUS, SImode, operands) + && ix86_match_ccmode (insn, CCmode) /* Current assemblers are broken and do not allow @GOTOFF in ought but a memory context. */ && ! pic_symbolic_operand (operands[2], VOIDmode)" @@ -4057,11 +4086,12 @@ (set_attr "mode" "SI")]) (define_insn "*addsi_5" - [(set (reg:CC 17) - (compare:CC (neg:SI (match_operand:SI 2 "general_operand" "rmni")) - (match_operand:SI 1 "nonimmediate_operand" "%0"))) + [(set (reg 17) + (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni")) + (match_operand:SI 1 "nonimmediate_operand" "%0"))) (clobber (match_scratch:SI 0 "=r"))] "(GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM) + && ix86_match_ccmode (insn, CCmode) /* Current assemblers are broken and do not allow @GOTOFF in ought but a memory context. */ && ! pic_symbolic_operand (operands[2], VOIDmode)" @@ -4069,6 +4099,54 @@ [(set_attr "type" "alu") (set_attr "mode" "SI")]) +(define_insn "*addsi_6" + [(set (reg 17) + (compare + (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0") + (match_operand:SI 2 "general_operand" "rmni")) + (const_int 0))) + (clobber (match_scratch:SI 0 "=r"))] + "ix86_match_ccmode (insn, CCGOCmode) + && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM) + /* Current assemblers are broken and do not allow @GOTOFF in + ought but a memory context. */ + && ! pic_symbolic_operand (operands[2], VOIDmode)" + "* +{ + switch (get_attr_type (insn)) + { + case TYPE_INCDEC: + if (! rtx_equal_p (operands[0], operands[1])) + abort (); + if (operands[2] == const1_rtx) + return \"inc{l}\\t%0\"; + else if (operands[2] == constm1_rtx) + return \"dec{l}\\t%0\"; + else + abort(); + + default: + if (! rtx_equal_p (operands[0], operands[1])) + abort (); + /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. + Exceptions: -128 encodes smaller than 128, so swap sign and op. */ + if (GET_CODE (operands[2]) == CONST_INT + && (INTVAL (operands[2]) == 128 + || (INTVAL (operands[2]) < 0 + && INTVAL (operands[2]) != -128))) + { + operands[2] = GEN_INT (-INTVAL (operands[2])); + return \"sub{l}\\t{%2, %0|%0, %2}\"; + } + return \"add{l}\\t{%2, %0|%0, %2}\"; + } +}" + [(set (attr "type") + (if_then_else (match_operand:SI 2 "incdec_operand" "") + (const_string "incdec") + (const_string "alu"))) + (set_attr "mode" "SI")]) + (define_expand "addhi3" [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") (plus:HI (match_operand:HI 1 "nonimmediate_operand" "") @@ -4173,7 +4251,7 @@ (const_int 0))) (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") (plus:HI (match_dup 1) (match_dup 2)))] - "ix86_match_ccmode (insn, CCNOmode) + "ix86_match_ccmode (insn, CCGOCmode) && ix86_binary_operator_ok (PLUS, HImode, operands)" "* { @@ -4213,7 +4291,7 @@ (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni")) (match_operand:HI 1 "nonimmediate_operand" "%0"))) (clobber (match_scratch:HI 0 "=r"))] - "ix86_match_ccmode (insn, CCNOmode) + "ix86_match_ccmode (insn, CCGCmode) && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" "* { @@ -4249,26 +4327,70 @@ (set_attr "mode" "HI")]) (define_insn "*addhi_4" - [(set (reg:CC 17) - (compare:CC (neg:HI (match_operand:HI 2 "general_operand" "rmni,rni")) - (match_operand:HI 1 "nonimmediate_operand" "%0,0"))) + [(set (reg 17) + (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni,rni")) + (match_operand:HI 1 "nonimmediate_operand" "%0,0"))) (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") (plus:HI (match_dup 1) (match_dup 2)))] - "ix86_binary_operator_ok (PLUS, HImode, operands)" + "ix86_match_ccmode (insn, CCmode) + && ix86_binary_operator_ok (PLUS, HImode, operands)" "add{w}\\t{%2, %0|%0, %2}" [(set_attr "type" "alu") (set_attr "mode" "HI")]) (define_insn "*addhi_5" - [(set (reg:CC 17) - (compare:CC (neg:HI (match_operand:HI 2 "general_operand" "rmni")) - (match_operand:HI 1 "nonimmediate_operand" "%0"))) + [(set (reg 17) + (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni")) + (match_operand:HI 1 "nonimmediate_operand" "%0"))) (clobber (match_scratch:HI 0 "=r"))] - "(GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" + "ix86_match_ccmode (insn, CCmode) + && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" "add{w}\\t{%2, %0|%0, %2}" [(set_attr "type" "alu") (set_attr "mode" "HI")]) +(define_insn "*addhi_6" + [(set (reg 17) + (compare + (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0") + (match_operand:HI 2 "general_operand" "rmni")) + (const_int 0))) + (clobber (match_scratch:HI 0 "=r"))] + "ix86_match_ccmode (insn, CCGOCmode) + && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" + "* +{ + switch (get_attr_type (insn)) + { + case TYPE_INCDEC: + if (operands[2] == const1_rtx) + return \"inc{w}\\t%0\"; + else if (operands[2] == constm1_rtx + || (GET_CODE (operands[2]) == CONST_INT + && INTVAL (operands[2]) == 65535)) + return \"dec{w}\\t%0\"; + abort(); + + default: + /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. + Exceptions: -128 encodes smaller than 128, so swap sign and op. */ + if (GET_CODE (operands[2]) == CONST_INT + && (INTVAL (operands[2]) == 128 + || (INTVAL (operands[2]) < 0 + && INTVAL (operands[2]) != -128))) + { + operands[2] = GEN_INT (-INTVAL (operands[2])); + return \"sub{w}\\t{%2, %0|%0, %2}\"; + } + return \"add{w}\\t{%2, %0|%0, %2}\"; + } +}" + [(set (attr "type") + (if_then_else (match_operand:HI 2 "incdec_operand" "") + (const_string "incdec") + (const_string "alu"))) + (set_attr "mode" "HI")]) + (define_expand "addqi3" [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "") (plus:QI (match_operand:QI 1 "nonimmediate_operand" "") @@ -4384,7 +4506,7 @@ (const_int 0))) (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm") (plus:QI (match_dup 1) (match_dup 2)))] - "ix86_match_ccmode (insn, CCNOmode) + "ix86_match_ccmode (insn, CCGOCmode) && ix86_binary_operator_ok (PLUS, QImode, operands)" "* { @@ -4421,7 +4543,7 @@ (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni")) (match_operand:QI 1 "nonimmediate_operand" "%0"))) (clobber (match_scratch:QI 0 "=r"))] - "ix86_match_ccmode (insn, CCNOmode) + "ix86_match_ccmode (insn, CCGCmode) && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" "* { @@ -4454,26 +4576,67 @@ (set_attr "mode" "QI")]) (define_insn "*addqi_4" - [(set (reg:CC 17) - (compare:CC (neg:QI (match_operand:QI 2 "general_operand" "qmni,qni")) - (match_operand:QI 1 "nonimmediate_operand" "%0,0"))) + [(set (reg 17) + (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni,qni")) + (match_operand:QI 1 "nonimmediate_operand" "%0,0"))) (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm") (plus:QI (match_dup 1) (match_dup 2)))] - "ix86_binary_operator_ok (PLUS, QImode, operands)" + "ix86_match_ccmode (insn, CCmode) + && ix86_binary_operator_ok (PLUS, QImode, operands)" "add{b}\\t{%2, %0|%0, %2}" [(set_attr "type" "alu") (set_attr "mode" "QI")]) (define_insn "*addqi_5" - [(set (reg:CC 17) - (compare:CC (neg:QI (match_operand:QI 2 "general_operand" "qmni")) - (match_operand:QI 1 "nonimmediate_operand" "%0"))) + [(set (reg 17) + (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni")) + (match_operand:QI 1 "nonimmediate_operand" "%0"))) (clobber (match_scratch:QI 0 "=r"))] - "(GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" + "ix86_match_ccmode (insn, CCmode) + && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" "add{b}\\t{%2, %0|%0, %2}" [(set_attr "type" "alu") (set_attr "mode" "QI")]) +(define_insn "*addqi_6" + [(set (reg 17) + (compare + (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0") + (match_operand:QI 2 "general_operand" "qmni")) + (const_int 0))) + (clobber (match_scratch:QI 0 "=r"))] + "ix86_match_ccmode (insn, CCGOCmode) + && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" + "* +{ + switch (get_attr_type (insn)) + { + case TYPE_INCDEC: + if (operands[2] == const1_rtx) + return \"inc{b}\\t%0\"; + else if (operands[2] == constm1_rtx + || (GET_CODE (operands[2]) == CONST_INT + && INTVAL (operands[2]) == 255)) + return \"dec{b}\\t%0\"; + abort(); + + default: + /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */ + if (GET_CODE (operands[2]) == CONST_INT + && INTVAL (operands[2]) < 0) + { + operands[2] = GEN_INT (-INTVAL (operands[2])); + return \"sub{b}\\t{%2, %0|%0, %2}\"; + } + return \"add{b}\\t{%2, %0|%0, %2}\"; + } +}" + [(set (attr "type") + (if_then_else (match_operand:QI 2 "incdec_operand" "") + (const_string "incdec") + (const_string "alu"))) + (set_attr "mode" "QI")]) + (define_insn "addqi_ext_1" [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q") @@ -4631,7 +4794,7 @@ (const_int 0))) (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") (minus:SI (match_dup 1) (match_dup 2)))] - "ix86_match_ccmode (insn, CCNOmode) + "ix86_match_ccmode (insn, CCGOCmode) && ix86_binary_operator_ok (MINUS, SImode, operands)" "sub{l}\\t{%2, %0|%0, %2}" [(set_attr "type" "alu") @@ -4675,7 +4838,7 @@ (const_int 0))) (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") (minus:HI (match_dup 1) (match_dup 2)))] - "ix86_match_ccmode (insn, CCNOmode) + "ix86_match_ccmode (insn, CCGOCmode) && ix86_binary_operator_ok (MINUS, HImode, operands)" "sub{w}\\t{%2, %0|%0, %2}" [(set_attr "type" "alu") @@ -4719,7 +4882,7 @@ (const_int 0))) (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q") (minus:HI (match_dup 1) (match_dup 2)))] - "ix86_match_ccmode (insn, CCNOmode) + "ix86_match_ccmode (insn, CCGOCmode) && ix86_binary_operator_ok (MINUS, QImode, operands)" "sub{b}\\t{%2, %0|%0, %2}" [(set_attr "type" "alu") @@ -5175,31 +5338,28 @@ ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al. ;; Note that this excludes ah. -(define_insn "*testsi_ccz_1" - [(set (reg:CCZ 17) - (compare:CCZ + +(define_insn "testsi_1" + [(set (reg 17) + (compare (and:SI (match_operand:SI 0 "nonimmediate_operand" "%*a,r,rm") (match_operand:SI 1 "nonmemory_operand" "in,in,rin")) (const_int 0)))] - "" + "ix86_match_ccmode (insn, CCNOmode)" "test{l}\\t{%1, %0|%0, %1}" [(set_attr "type" "test") (set_attr "modrm" "0,1,1") (set_attr "mode" "SI") (set_attr "pent_pair" "uv,np,uv")]) -(define_insn "testsi_ccno_1" +(define_expand "testsi_ccno_1" [(set (reg:CCNO 17) (compare:CCNO - (and:SI (match_operand:SI 0 "nonimmediate_operand" "%*a,r,rm") - (match_operand:SI 1 "nonmemory_operand" "in,in,rin")) + (and:SI (match_operand:SI 0 "nonimmediate_operand" "") + (match_operand:SI 1 "nonmemory_operand" "")) (const_int 0)))] "" - "test{l}\\t{%1, %0|%0, %1}" - [(set_attr "type" "test") - (set_attr "modrm" "0,1,1") - (set_attr "mode" "SI") - (set_attr "pent_pair" "uv,np,uv")]) + "") (define_insn "*testhi_1" [(set (reg 17) @@ -5213,25 +5373,20 @@ (set_attr "mode" "HI") (set_attr "pent_pair" "uv,np,uv")]) -(define_insn "testqi_ccz_1" +(define_expand "testqi_ccz_1" [(set (reg:CCZ 17) - (compare:CCZ - (and:QI (match_operand:QI 0 "nonimmediate_operand" "%*a,q,qm") - (match_operand:QI 1 "nonmemory_operand" "n,n,qn")) - (const_int 0)))] + (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "") + (match_operand:QI 1 "nonmemory_operand" "")) + (const_int 0)))] "" - "test{b}\\t{%1, %0|%0, %1}" - [(set_attr "type" "test") - (set_attr "modrm" "0,1,1") - (set_attr "mode" "QI") - (set_attr "pent_pair" "uv,np,uv")]) + "") -(define_insn "*testqi_ccno_1" - [(set (reg:CCNO 17) - (compare:CCNO (and:QI (match_operand:QI 0 "nonimmediate_operand" "%*a,q,qm,r") - (match_operand:QI 1 "nonmemory_operand" "n,n,qn,n")) - (const_int 0)))] - "" +(define_insn "*testqi_1" + [(set (reg 17) + (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%*a,q,qm,r") + (match_operand:QI 1 "nonmemory_operand" "n,n,qn,n")) + (const_int 0)))] + "ix86_match_ccmode (insn, CCNOmode)" "@ test{b}\\t{%1, %0|%0, %1} test{b}\\t{%1, %0|%0, %1} @@ -5242,26 +5397,22 @@ (set_attr "mode" "QI,QI,QI,SI") (set_attr "pent_pair" "uv,np,uv,np")]) -(define_insn "*testqi_ext_ccz_0" - [(set (reg:CCZ 17) - (compare:CCZ +(define_expand "testqi_ext_ccno_0" + [(set (reg:CCNO 17) + (compare:CCNO (and:SI (zero_extract:SI - (match_operand 0 "ext_register_operand" "q") + (match_operand 0 "ext_register_operand" "") (const_int 8) (const_int 8)) - (match_operand 1 "const_int_operand" "n")) + (match_operand 1 "const_int_operand" "")) (const_int 0)))] - "(unsigned HOST_WIDE_INT) INTVAL (operands[1]) <= 0xff" - "test{b}\\t{%1, %h0|%h0, %1}" - [(set_attr "type" "test") - (set_attr "mode" "QI") - (set_attr "length_immediate" "1") - (set_attr "pent_pair" "np")]) + "" + "") -(define_insn "testqi_ext_ccno_0" - [(set (reg:CCNO 17) - (compare:CCNO +(define_insn "*testqi_ext_0" + [(set (reg 17) + (compare (and:SI (zero_extract:SI (match_operand 0 "ext_register_operand" "q") @@ -5269,7 +5420,8 @@ (const_int 8)) (match_operand 1 "const_int_operand" "n")) (const_int 0)))] - "(unsigned HOST_WIDE_INT) INTVAL (operands[1]) <= 0xff" + "(unsigned HOST_WIDE_INT) INTVAL (operands[1]) <= 0xff + && ix86_match_ccmode (insn, CCNOmode)" "test{b}\\t{%1, %h0|%h0, %1}" [(set_attr "type" "test") (set_attr "mode" "QI") @@ -5941,9 +6093,9 @@ [(set_attr "type" "alu") (set_attr "mode" "QI")]) -(define_insn "xorqi_cc_ext_1" - [(set (reg:CCNO 17) - (compare:CCNO +(define_insn "*xorqi_cc_ext_1" + [(set (reg 17) + (compare (xor:SI (zero_extract:SI (match_operand 1 "ext_register_operand" "0") @@ -5957,10 +6109,30 @@ (xor:SI (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8)) (match_dup 2)))] - "" + "ix86_match_ccmode (insn, CCNOmode)" "xor{b}\\t{%2, %h0|%h0, %2}" [(set_attr "type" "alu") (set_attr "mode" "QI")]) + +(define_expand "xorqi_cc_ext_1" + [(parallel [ + (set (reg:CCNO 17) + (compare:CCNO + (xor:SI + (zero_extract:SI + (match_operand 1 "ext_register_operand" "") + (const_int 8) + (const_int 8)) + (match_operand:QI 2 "general_operand" "")) + (const_int 0))) + (set (zero_extract:SI (match_operand 0 "ext_register_operand" "") + (const_int 8) + (const_int 8)) + (xor:SI + (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8)) + (match_dup 2)))])] + "" + "") ;; Negation instructions @@ -6810,7 +6982,7 @@ (const_int 0))) (set (match_operand:SI 0 "nonimmediate_operand" "=rm") (ashift:SI (match_dup 1) (match_dup 2)))] - "ix86_match_ccmode (insn, CCNOmode) + "ix86_match_ccmode (insn, CCGOCmode) && ix86_binary_operator_ok (ASHIFT, SImode, operands)" "* { @@ -6939,7 +7111,7 @@ (const_int 0))) (set (match_operand:HI 0 "nonimmediate_operand" "=rm") (ashift:HI (match_dup 1) (match_dup 2)))] - "ix86_match_ccmode (insn, CCNOmode) + "ix86_match_ccmode (insn, CCGOCmode) && ix86_binary_operator_ok (ASHIFT, HImode, operands)" "* { @@ -7106,7 +7278,7 @@ (const_int 0))) (set (match_operand:QI 0 "nonimmediate_operand" "=qm") (ashift:QI (match_dup 1) (match_dup 2)))] - "ix86_match_ccmode (insn, CCNOmode) + "ix86_match_ccmode (insn, CCGOCmode) && ix86_binary_operator_ok (ASHIFT, QImode, operands)" "* { @@ -7576,7 +7748,7 @@ (const_int 0))) (set (match_operand:SI 0 "nonimmediate_operand" "=rm") (lshiftrt:SI (match_dup 1) (match_dup 2)))] - "ix86_match_ccmode (insn, CCNOmode) + "ix86_match_ccmode (insn, CCGOCmode) && (TARGET_PENTIUM || TARGET_PENTIUMPRO) && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" "shr{l}\\t%0" @@ -7597,7 +7769,7 @@ (const_int 0))) (set (match_operand:SI 0 "nonimmediate_operand" "=rm") (lshiftrt:SI (match_dup 1) (match_dup 2)))] - "ix86_match_ccmode (insn, CCNOmode) + "ix86_match_ccmode (insn, CCGOCmode) && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" "@ shr{l}\\t{%2, %0|%0, %2}" @@ -7649,7 +7821,7 @@ (const_int 0))) (set (match_operand:HI 0 "nonimmediate_operand" "=rm") (lshiftrt:HI (match_dup 1) (match_dup 2)))] - "ix86_match_ccmode (insn, CCNOmode) + "ix86_match_ccmode (insn, CCGOCmode) && (TARGET_PENTIUM || TARGET_PENTIUMPRO) && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" "shr{w}\\t%0" @@ -7670,7 +7842,7 @@ (const_int 0))) (set (match_operand:HI 0 "nonimmediate_operand" "=rm") (lshiftrt:HI (match_dup 1) (match_dup 2)))] - "ix86_match_ccmode (insn, CCNOmode) + "ix86_match_ccmode (insn, CCGOCmode) && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" "@ shr{w}\\t{%2, %0|%0, %2}" @@ -7722,7 +7894,7 @@ (const_int 0))) (set (match_operand:QI 0 "nonimmediate_operand" "=qm") (lshiftrt:QI (match_dup 1) (match_dup 2)))] - "ix86_match_ccmode (insn, CCNOmode) + "ix86_match_ccmode (insn, CCGOCmode) && (TARGET_PENTIUM || TARGET_PENTIUMPRO) && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)" "shr{b}\\t%0" @@ -7743,7 +7915,7 @@ (const_int 0))) (set (match_operand:QI 0 "nonimmediate_operand" "=qm") (lshiftrt:QI (match_dup 1) (match_dup 2)))] - "ix86_match_ccmode (insn, CCNOmode) + "ix86_match_ccmode (insn, CCGOCmode) && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)" "shr{b}\\t{%2, %0|%0, %2}" [(set_attr "type" "ishift") @@ -8132,7 +8304,7 @@ (define_insn "*setcc_1" [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") - (match_operator:QI 1 "no_comparison_operator" + (match_operator:QI 1 "ix86_comparison_operator" [(reg 17) (const_int 0)]))] "" "set%C1\\t%0" @@ -8141,30 +8313,13 @@ (define_insn "*setcc_2" [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) - (match_operator:QI 1 "no_comparison_operator" + (match_operator:QI 1 "ix86_comparison_operator" [(reg 17) (const_int 0)]))] "" "set%C1\\t%0" [(set_attr "type" "setcc") (set_attr "mode" "QI")]) -(define_insn "*setcc_3" - [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") - (match_operator:QI 1 "uno_comparison_operator" - [(reg:CC 17) (const_int 0)]))] - "" - "set%C1\\t%0" - [(set_attr "type" "setcc") - (set_attr "mode" "QI")]) - -(define_insn "setcc_4" - [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) - (match_operator:QI 1 "uno_comparison_operator" - [(reg:CC 17) (const_int 0)]))] - "" - "set%C1\\t%0" - [(set_attr "type" "setcc") - (set_attr "mode" "QI")]) ;; Basic conditional jump instructions. ;; We ignore the overflow flag for signed branch instructions. @@ -8318,7 +8473,7 @@ (define_insn "*jcc_1" [(set (pc) - (if_then_else (match_operator 1 "no_comparison_operator" + (if_then_else (match_operator 1 "ix86_comparison_operator" [(reg 17) (const_int 0)]) (label_ref (match_operand 0 "" "")) (pc)))] @@ -8335,7 +8490,7 @@ (define_insn "*jcc_2" [(set (pc) - (if_then_else (match_operator 1 "no_comparison_operator" + (if_then_else (match_operator 1 "ix86_comparison_operator" [(reg 17) (const_int 0)]) (pc) (label_ref (match_operand 0 "" ""))))] @@ -8350,40 +8505,6 @@ (const_int 0) (const_int 1)))]) -(define_insn "*jcc_3" - [(set (pc) - (if_then_else (match_operator 1 "uno_comparison_operator" - [(reg:CC 17) (const_int 0)]) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "j%C1\\t%l0" - [(set_attr "type" "ibr") - (set (attr "prefix_0f") - (if_then_else (and (ge (minus (match_dup 0) (pc)) - (const_int -128)) - (lt (minus (match_dup 0) (pc)) - (const_int 124))) - (const_int 0) - (const_int 1)))]) - -(define_insn "*jcc_4" - [(set (pc) - (if_then_else (match_operator 1 "uno_comparison_operator" - [(reg:CC 17) (const_int 0)]) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "j%c1\\t%l0" - [(set_attr "type" "ibr") - (set (attr "prefix_0f") - (if_then_else (and (ge (minus (match_dup 0) (pc)) - (const_int -128)) - (lt (minus (match_dup 0) (pc)) - (const_int 124))) - (const_int 0) - (const_int 1)))]) - ;; Define combination compare-and-branch fp compare instructions to use ;; during early optimization. Splitting the operation apart early makes ;; for bad code when we want to reverse the operation. @@ -10484,7 +10605,7 @@ (define_insn "*movsicc_noc" [(set (match_operand:SI 0 "register_operand" "=r,r") - (if_then_else:SI (match_operator 1 "no_comparison_operator" + (if_then_else:SI (match_operator 1 "ix86_comparison_operator" [(reg 17) (const_int 0)]) (match_operand:SI 2 "nonimmediate_operand" "rm,0") (match_operand:SI 3 "nonimmediate_operand" "0,rm")))] @@ -10496,20 +10617,6 @@ [(set_attr "type" "icmov") (set_attr "mode" "SI")]) -(define_insn "*movsicc_c" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (if_then_else:SI (match_operator 1 "uno_comparison_operator" - [(reg:CC 17) (const_int 0)]) - (match_operand:SI 2 "nonimmediate_operand" "rm,0") - (match_operand:SI 3 "nonimmediate_operand" "0,rm")))] - "TARGET_CMOVE - && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" - "@ - cmov%C1\\t{%2, %0|%0, %2} - cmov%c1\\t{%3, %0|%0, %3}" - [(set_attr "type" "icmov") - (set_attr "mode" "SI")]) - (define_expand "movhicc" [(set (match_operand:HI 0 "register_operand" "") (if_then_else:HI (match_operand 1 "comparison_operator" "") @@ -10520,7 +10627,7 @@ (define_insn "*movhicc_noc" [(set (match_operand:HI 0 "register_operand" "=r,r") - (if_then_else:HI (match_operator 1 "no_comparison_operator" + (if_then_else:HI (match_operator 1 "ix86_comparison_operator" [(reg 17) (const_int 0)]) (match_operand:HI 2 "nonimmediate_operand" "rm,0") (match_operand:HI 3 "nonimmediate_operand" "0,rm")))] @@ -10532,20 +10639,6 @@ [(set_attr "type" "icmov") (set_attr "mode" "HI")]) -(define_insn "*movhicc_c" - [(set (match_operand:HI 0 "register_operand" "=r,r") - (if_then_else:HI (match_operator 1 "uno_comparison_operator" - [(reg:CC 17) (const_int 0)]) - (match_operand:HI 2 "nonimmediate_operand" "rm,0") - (match_operand:HI 3 "nonimmediate_operand" "0,rm")))] - "TARGET_CMOVE - && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" - "@ - cmov%C1\\t{%2, %0|%0, %2} - cmov%c1\\t{%3, %0|%0, %3}" - [(set_attr "type" "icmov") - (set_attr "mode" "HI")]) - (define_expand "movsfcc" [(set (match_operand:SF 0 "register_operand" "") (if_then_else:SF (match_operand 1 "comparison_operator" "") |