From 93330ea10a357abf2055c883935abf71102cbbec Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sun, 12 Sep 2004 11:00:49 -0700 Subject: [PATCH] i386.c (ix86_split_ashldi): Special case op1 as one or minus one. * config/i386/i386.c (ix86_split_ashldi): Special case op1 as one or minus one. (ix86_split_ashrdi, ix86_split_lshrdi): Clean up conditions for post-reload, and scratch NULL. * config/i386/i386.md (testqi_1): Use FLAGS_REG name. (x86_shift_adj_2): Use ix86_expand_clear. (ashldi3): Remove CMOVE expansion difference. (ashldi3_1): Remove. (*ashldi3_1): Rename from *ashldi3_2. Use reg_or_pm1_operand and add constraints for immediates. New peephole for split-with-temp. Run splitter after peep2 pass. (ashrdi3, ashrdi3_1, ashrdi3_2): Similarly. (lshrdi3, lshrdi3_1, lshrdi3_2): Similarly. (setcc_2): Rename with *. * config/i386/predicates.md (reg_or_pm1_operand): New. (ashldi_input_operand): New. From-SVN: r87398 --- gcc/ChangeLog | 19 ++++ gcc/config/i386/i386.c | 109 +++++++++++++++------- gcc/config/i386/i386.md | 171 +++++++++++++--------------------- gcc/config/i386/predicates.md | 11 +++ 4 files changed, 170 insertions(+), 140 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index df4dd94b39e..578495b5492 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,22 @@ +2004-09-12 Richard Henderson + + * config/i386/i386.c (ix86_split_ashldi): Special case op1 as one + or minus one. + (ix86_split_ashrdi, ix86_split_lshrdi): Clean up conditions for + post-reload, and scratch NULL. + * config/i386/i386.md (testqi_1): Use FLAGS_REG name. + (x86_shift_adj_2): Use ix86_expand_clear. + (ashldi3): Remove CMOVE expansion difference. + (ashldi3_1): Remove. + (*ashldi3_1): Rename from *ashldi3_2. Use reg_or_pm1_operand and + add constraints for immediates. New peephole for split-with-temp. + Run splitter after peep2 pass. + (ashrdi3, ashrdi3_1, ashrdi3_2): Similarly. + (lshrdi3, lshrdi3_1, lshrdi3_2): Similarly. + (setcc_2): Rename with *. + * config/i386/predicates.md (reg_or_pm1_operand): New. + (ashldi_input_operand): New. + 2004-09-12 Richard Henderson = 32) { emit_move_insn (low[0], high[1]); - - if (! reload_completed) - emit_insn (gen_ashrsi3 (high[0], low[0], GEN_INT (31))); - else - { - emit_move_insn (high[0], low[0]); - emit_insn (gen_ashrsi3 (high[0], high[0], GEN_INT (31))); - } - + emit_move_insn (high[0], low[0]); + emit_insn (gen_ashrsi3 (high[0], high[0], GEN_INT (31))); if (count > 32) emit_insn (gen_ashrsi3 (low[0], low[0], GEN_INT (count - 32))); } @@ -10096,10 +10147,8 @@ ix86_split_ashrdi (rtx *operands, rtx scratch) emit_insn (gen_x86_shrd_1 (low[0], high[0], operands[2])); emit_insn (gen_ashrsi3 (high[0], high[0], operands[2])); - if (TARGET_CMOVE && (! no_new_pseudos || scratch)) + if (TARGET_CMOVE && scratch) { - if (! no_new_pseudos) - scratch = gen_reg_rtx (SImode); emit_move_insn (scratch, high[0]); emit_insn (gen_ashrsi3 (scratch, scratch, GEN_INT (31))); emit_insn (gen_x86_shift_adj_1 (low[0], high[0], operands[2], @@ -10124,7 +10173,7 @@ ix86_split_lshrdi (rtx *operands, rtx scratch) if (count >= 32) { emit_move_insn (low[0], high[1]); - emit_move_insn (high[0], const0_rtx); + ix86_expand_clear (high[0]); if (count > 32) emit_insn (gen_lshrsi3 (low[0], low[0], GEN_INT (count - 32))); @@ -10148,13 +10197,9 @@ ix86_split_lshrdi (rtx *operands, rtx scratch) emit_insn (gen_lshrsi3 (high[0], high[0], operands[2])); /* Heh. By reversing the arguments, we can reuse this pattern. */ - if (TARGET_CMOVE && (! no_new_pseudos || scratch)) + if (TARGET_CMOVE && scratch) { - if (! no_new_pseudos) - scratch = force_reg (SImode, const0_rtx); - else - emit_move_insn (scratch, const0_rtx); - + ix86_expand_clear (scratch); emit_insn (gen_x86_shift_adj_1 (low[0], high[0], operands[2], scratch)); } diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 8ec7719b660..f2f3fbedbdf 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -1906,7 +1906,7 @@ (define_split [(set (match_operand:DI 0 "push_operand" "") (match_operand:DI 1 "immediate_operand" ""))] - "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2)) + "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed) && !symbolic_operand (operands[1], DImode) && !x86_64_immediate_operand (operands[1], DImode)" [(set (match_dup 0) (match_dup 1)) @@ -2168,7 +2168,7 @@ (define_split [(set (match_operand:DI 0 "memory_operand" "") (match_operand:DI 1 "immediate_operand" ""))] - "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2)) + "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed) && !symbolic_operand (operands[1], DImode) && !x86_64_immediate_operand (operands[1], DImode)" [(set (match_dup 2) (match_dup 3)) @@ -7924,7 +7924,7 @@ "") (define_insn "*testqi_1" - [(set (reg 17) + [(set (reg FLAGS_REG) (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r") (match_operand:QI 1 "general_operand" "n,n,qn,n")) (const_int 0)))] @@ -10623,20 +10623,11 @@ ;; than 31. (define_expand "ashldi3" - [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "") - (ashift:DI (match_operand:DI 1 "shiftdi_operand" "") - (match_operand:QI 2 "nonmemory_operand" ""))) - (clobber (reg:CC FLAGS_REG))])] + [(set (match_operand:DI 0 "shiftdi_operand" "") + (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "") + (match_operand:QI 2 "nonmemory_operand" "")))] "" -{ - if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode)) - { - emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2])); - DONE; - } - ix86_expand_binary_operator (ASHIFT, DImode, operands); - DONE; -}) + "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;") (define_insn "*ashldi3_1_rex64" [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") @@ -10738,41 +10729,35 @@ (const_string "ishift"))) (set_attr "mode" "DI")]) -(define_insn "ashldi3_1" - [(set (match_operand:DI 0 "register_operand" "=r") - (ashift:DI (match_operand:DI 1 "register_operand" "0") - (match_operand:QI 2 "nonmemory_operand" "Jc"))) - (clobber (match_scratch:SI 3 "=&r")) - (clobber (reg:CC FLAGS_REG))] - "!TARGET_64BIT && TARGET_CMOVE" - "#" - [(set_attr "type" "multi")]) - -(define_insn "*ashldi3_2" - [(set (match_operand:DI 0 "register_operand" "=r") - (ashift:DI (match_operand:DI 1 "register_operand" "0") - (match_operand:QI 2 "nonmemory_operand" "Jc"))) +(define_insn "*ashldi3_1" + [(set (match_operand:DI 0 "register_operand" "=&r,r") + (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0") + (match_operand:QI 2 "nonmemory_operand" "Jc,Jc"))) (clobber (reg:CC FLAGS_REG))] "!TARGET_64BIT" "#" [(set_attr "type" "multi")]) -(define_split - [(set (match_operand:DI 0 "register_operand" "") - (ashift:DI (match_operand:DI 1 "register_operand" "") - (match_operand:QI 2 "nonmemory_operand" ""))) - (clobber (match_scratch:SI 3 "")) - (clobber (reg:CC FLAGS_REG))] - "!TARGET_64BIT && TARGET_CMOVE && reload_completed" +;; By default we don't ask for a scratch register, because when DImode +;; values are manipulated, registers are already at a premium. But if +;; we have one handy, we won't turn it away. +(define_peephole2 + [(match_scratch:SI 3 "r") + (parallel [(set (match_operand:DI 0 "register_operand" "") + (ashift:DI (match_operand:DI 1 "nonmemory_operand" "") + (match_operand:QI 2 "nonmemory_operand" ""))) + (clobber (reg:CC FLAGS_REG))]) + (match_dup 3)] + "!TARGET_64BIT && TARGET_CMOVE" [(const_int 0)] "ix86_split_ashldi (operands, operands[3]); DONE;") (define_split [(set (match_operand:DI 0 "register_operand" "") - (ashift:DI (match_operand:DI 1 "register_operand" "") + (ashift:DI (match_operand:DI 1 "nonmemory_operand" "") (match_operand:QI 2 "nonmemory_operand" ""))) (clobber (reg:CC FLAGS_REG))] - "!TARGET_64BIT && reload_completed" + "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)" [(const_int 0)] "ix86_split_ashldi (operands, NULL_RTX); DONE;") @@ -10829,7 +10814,7 @@ JUMP_LABEL (tmp) = label; emit_move_insn (operands[0], operands[1]); - emit_move_insn (operands[1], const0_rtx); + ix86_expand_clear (operands[1]); emit_label (label); LABEL_NUSES (label) = 1; @@ -11346,27 +11331,19 @@ ;; See comment above `ashldi3' about how this works. (define_expand "ashrdi3" - [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "") - (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "") - (match_operand:QI 2 "nonmemory_operand" ""))) - (clobber (reg:CC FLAGS_REG))])] + [(set (match_operand:DI 0 "shiftdi_operand" "") + (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "") + (match_operand:QI 2 "nonmemory_operand" "")))] "" -{ - if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode)) - { - emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2])); - DONE; - } - ix86_expand_binary_operator (ASHIFTRT, DImode, operands); - DONE; -}) + "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;") -(define_insn "ashrdi3_63_rex64" +(define_insn "*ashrdi3_63_rex64" [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm") (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0") (match_operand:DI 2 "const_int_operand" "i,i"))) (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size) + "TARGET_64BIT && INTVAL (operands[2]) == 63 + && (TARGET_USE_CLTD || optimize_size) && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" "@ {cqto|cqo} @@ -11441,18 +11418,7 @@ [(set_attr "type" "ishift") (set_attr "mode" "DI")]) - -(define_insn "ashrdi3_1" - [(set (match_operand:DI 0 "register_operand" "=r") - (ashiftrt:DI (match_operand:DI 1 "register_operand" "0") - (match_operand:QI 2 "nonmemory_operand" "Jc"))) - (clobber (match_scratch:SI 3 "=&r")) - (clobber (reg:CC FLAGS_REG))] - "!TARGET_64BIT && TARGET_CMOVE" - "#" - [(set_attr "type" "multi")]) - -(define_insn "*ashrdi3_2" +(define_insn "*ashrdi3_1" [(set (match_operand:DI 0 "register_operand" "=r") (ashiftrt:DI (match_operand:DI 1 "register_operand" "0") (match_operand:QI 2 "nonmemory_operand" "Jc"))) @@ -11461,13 +11427,17 @@ "#" [(set_attr "type" "multi")]) -(define_split - [(set (match_operand:DI 0 "register_operand" "") - (ashiftrt:DI (match_operand:DI 1 "register_operand" "") - (match_operand:QI 2 "nonmemory_operand" ""))) - (clobber (match_scratch:SI 3 "")) - (clobber (reg:CC FLAGS_REG))] - "!TARGET_64BIT && TARGET_CMOVE && reload_completed" +;; By default we don't ask for a scratch register, because when DImode +;; values are manipulated, registers are already at a premium. But if +;; we have one handy, we won't turn it away. +(define_peephole2 + [(match_scratch:SI 3 "r") + (parallel [(set (match_operand:DI 0 "register_operand" "") + (ashiftrt:DI (match_operand:DI 1 "register_operand" "") + (match_operand:QI 2 "nonmemory_operand" ""))) + (clobber (reg:CC FLAGS_REG))]) + (match_dup 3)] + "!TARGET_64BIT && TARGET_CMOVE" [(const_int 0)] "ix86_split_ashrdi (operands, operands[3]); DONE;") @@ -11476,7 +11446,7 @@ (ashiftrt:DI (match_operand:DI 1 "register_operand" "") (match_operand:QI 2 "nonmemory_operand" ""))) (clobber (reg:CC FLAGS_REG))] - "!TARGET_64BIT && reload_completed" + "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)" [(const_int 0)] "ix86_split_ashrdi (operands, NULL_RTX); DONE;") @@ -11858,20 +11828,11 @@ ;; See comment above `ashldi3' about how this works. (define_expand "lshrdi3" - [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "") - (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "") - (match_operand:QI 2 "nonmemory_operand" ""))) - (clobber (reg:CC FLAGS_REG))])] + [(set (match_operand:DI 0 "shiftdi_operand" "") + (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "") + (match_operand:QI 2 "nonmemory_operand" "")))] "" -{ - if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode)) - { - emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2])); - DONE; - } - ix86_expand_binary_operator (LSHIFTRT, DImode, operands); - DONE; -}) + "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;") (define_insn "*lshrdi3_1_one_bit_rex64" [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") @@ -11937,17 +11898,7 @@ [(set_attr "type" "ishift") (set_attr "mode" "DI")]) -(define_insn "lshrdi3_1" - [(set (match_operand:DI 0 "register_operand" "=r") - (lshiftrt:DI (match_operand:DI 1 "register_operand" "0") - (match_operand:QI 2 "nonmemory_operand" "Jc"))) - (clobber (match_scratch:SI 3 "=&r")) - (clobber (reg:CC FLAGS_REG))] - "!TARGET_64BIT && TARGET_CMOVE" - "#" - [(set_attr "type" "multi")]) - -(define_insn "*lshrdi3_2" +(define_insn "*lshrdi3_1" [(set (match_operand:DI 0 "register_operand" "=r") (lshiftrt:DI (match_operand:DI 1 "register_operand" "0") (match_operand:QI 2 "nonmemory_operand" "Jc"))) @@ -11956,13 +11907,17 @@ "#" [(set_attr "type" "multi")]) -(define_split - [(set (match_operand:DI 0 "register_operand" "") - (lshiftrt:DI (match_operand:DI 1 "register_operand" "") - (match_operand:QI 2 "nonmemory_operand" ""))) - (clobber (match_scratch:SI 3 "")) - (clobber (reg:CC FLAGS_REG))] - "!TARGET_64BIT && TARGET_CMOVE && reload_completed" +;; By default we don't ask for a scratch register, because when DImode +;; values are manipulated, registers are already at a premium. But if +;; we have one handy, we won't turn it away. +(define_peephole2 + [(match_scratch:SI 3 "r") + (parallel [(set (match_operand:DI 0 "register_operand" "") + (lshiftrt:DI (match_operand:DI 1 "register_operand" "") + (match_operand:QI 2 "nonmemory_operand" ""))) + (clobber (reg:CC FLAGS_REG))]) + (match_dup 3)] + "!TARGET_64BIT && TARGET_CMOVE" [(const_int 0)] "ix86_split_lshrdi (operands, operands[3]); DONE;") @@ -11971,7 +11926,7 @@ (lshiftrt:DI (match_operand:DI 1 "register_operand" "") (match_operand:QI 2 "nonmemory_operand" ""))) (clobber (reg:CC FLAGS_REG))] - "!TARGET_64BIT && reload_completed" + "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)" [(const_int 0)] "ix86_split_lshrdi (operands, NULL_RTX); DONE;") @@ -12840,7 +12795,7 @@ [(set_attr "type" "setcc") (set_attr "mode" "QI")]) -(define_insn "setcc_2" +(define_insn "*setcc_2" [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) (match_operator:QI 1 "ix86_comparison_operator" [(reg 17) (const_int 0)]))] diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index 220b01c81cc..96be8b9bc67 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -553,12 +553,23 @@ return op == const1_rtx || op == constm1_rtx; }) +;; True for registers, or 1 or -1. Used to optimize double-word shifts. +(define_predicate "reg_or_pm1_operand" + (ior (match_operand 0 "register_operand") + (and (match_code "const_int") + (match_test "op == const1_rtx || op == constm1_rtx")))) + ;; True if OP is acceptable as operand of DImode shift expander. (define_predicate "shiftdi_operand" (if_then_else (match_test "TARGET_64BIT") (match_operand 0 "nonimmediate_operand") (match_operand 0 "register_operand"))) +(define_predicate "ashldi_input_operand" + (if_then_else (match_test "TARGET_64BIT") + (match_operand 0 "nonimmediate_operand") + (match_operand 0 "reg_or_pm1_operand"))) + ;; Return true if OP is a vector load from the constant pool with just ;; the first element non-zero. (define_predicate "zero_extended_scalar_load_operand" -- 2.30.2