summaryrefslogtreecommitdiff
path: root/gcc/config/i386/i386.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/i386/i386.md')
-rw-r--r--gcc/config/i386/i386.md21
1 files changed, 20 insertions, 1 deletions
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index f16b42ab884..79c5f1a740c 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -3874,10 +3874,29 @@
[(set_attr "type" "imovx")
(set_attr "mode" "SI")])
+(define_insn_and_split "*zext<mode>_doubleword_and"
+ [(set (match_operand:DI 0 "register_operand" "=&<r>")
+ (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
+ "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
+ && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
+ "#"
+ "&& reload_completed && GENERAL_REG_P (operands[0])"
+ [(set (match_dup 2) (const_int 0))]
+{
+ split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);
+
+ emit_move_insn (operands[0], const0_rtx);
+
+ gcc_assert (!TARGET_PARTIAL_REG_STALL);
+ emit_insn (gen_movstrict<mode>
+ (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
+})
+
(define_insn_and_split "*zext<mode>_doubleword"
[(set (match_operand:DI 0 "register_operand" "=r")
(zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
- "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
+ "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
+ && !(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
"#"
"&& reload_completed && GENERAL_REG_P (operands[0])"
[(set (match_dup 0) (zero_extend:SI (match_dup 1)))