PR target/89021 * config/i386/i386.c (ix86_expand_vector_init_duplicate): Set mmx_ok to true if TARGET_MMX_WITH_SSE is true. (ix86_expand_vector_init_one_nonzero): Likewise. (ix86_expand_vector_init_one_var): Likewise. (ix86_expand_vector_init_general): Likewise. (ix86_expand_vector_init): Likewise. (ix86_expand_vector_set): Likewise. (ix86_expand_vector_extract): Likewise. * config/i386/mmx.md (*vec_dupv2sf): Changed to define_insn_and_split to support SSE emulation. (vec_setv2sf): Also allow TARGET_MMX_WITH_SSE. (vec_extractv2sf_1 splitter): Likewise. (vec_extractv2sfsf): Likewise. (vec_setv2si): Likewise. (vec_extractv2si_1 splitter): Likewise. (vec_extractv2sisi): Likewise. (vec_setv4hi): Likewise. (vec_extractv4hihi): Likewise. (vec_setv8qi): Likewise. (vec_extractv8qiqi): Likewise. (*vec_extractv2sf_0): Don't allow TARGET_MMX_WITH_SSE. (*vec_extractv2sf_1): Likewise. (*vec_extractv2si_0): Likewise. (*vec_extractv2si_1): Likewise. (*vec_extractv2sf_0_sse): New. (*vec_extractv2sf_1_sse): Likewise. (*vec_extractv2si_0_sse): Likewise. (*vec_extractv2si_1_sse): Likewise. --- gcc/config/i386/i386.c | 8 +++ gcc/config/i386/mmx.md | 133 +++++++++++++++++++++++++++++++++-------- 2 files changed, 117 insertions(+), 24 deletions(-)
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index cf7a71bcc02..cf2c59f7b6a 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -42365,6 +42365,7 @@ ix86_expand_vector_init_duplicate (bool mmx_ok, machine_mode mode, { bool ok; + mmx_ok |= TARGET_MMX_WITH_SSE; switch (mode) { case E_V2SImode: @@ -42524,6 +42525,7 @@ ix86_expand_vector_init_one_nonzero (bool mmx_ok, machine_mode mode, bool use_vector_set = false; rtx (*gen_vec_set_0) (rtx, rtx, rtx) = NULL; + mmx_ok |= TARGET_MMX_WITH_SSE; switch (mode) { case E_V2DImode: @@ -42717,6 +42719,7 @@ ix86_expand_vector_init_one_var (bool mmx_ok, machine_mode mode, XVECEXP (const_vec, 0, one_var) = CONST0_RTX (GET_MODE_INNER (mode)); const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (const_vec, 0)); + mmx_ok |= TARGET_MMX_WITH_SSE; switch (mode) { case E_V2DFmode: @@ -43102,6 +43105,7 @@ ix86_expand_vector_init_general (bool mmx_ok, machine_mode mode, machine_mode quarter_mode = VOIDmode; int n, i; + mmx_ok |= TARGET_MMX_WITH_SSE; switch (mode) { case E_V2SFmode: @@ -43301,6 +43305,8 @@ ix86_expand_vector_init (bool mmx_ok, rtx target, rtx vals) int i; rtx x; + mmx_ok |= TARGET_MMX_WITH_SSE; + /* Handle first initialization from vector elts. */ if (n_elts != XVECLEN (vals, 0)) { @@ -43400,6 +43406,7 @@ ix86_expand_vector_set (bool mmx_ok, rtx target, rtx val, int elt) machine_mode mmode = VOIDmode; rtx (*gen_blendm) (rtx, rtx, rtx, rtx); + mmx_ok |= TARGET_MMX_WITH_SSE; switch (mode) { case E_V2SFmode: @@ -43755,6 +43762,7 @@ ix86_expand_vector_extract (bool mmx_ok, rtx target, rtx vec, int elt) bool use_vec_extr = false; rtx tmp; + mmx_ok |= TARGET_MMX_WITH_SSE; switch (mode) { case E_V2SImode: diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md index 25954891b11..e56d2e71168 100644 --- a/gcc/config/i386/mmx.md +++ b/gcc/config/i386/mmx.md @@ -597,14 +597,27 @@ (set_attr "prefix_extra" "1") (set_attr "mode" "V2SF")]) -(define_insn "*vec_dupv2sf" - [(set (match_operand:V2SF 0 "register_operand" "=y") +(define_insn_and_split "*vec_dupv2sf" + [(set (match_operand:V2SF 0 "register_operand" "=y,x,Yv") (vec_duplicate:V2SF - (match_operand:SF 1 "register_operand" "0")))] - "TARGET_MMX" - "punpckldq\t%0, %0" - [(set_attr "type" "mmxcvt") - (set_attr "mode" "DI")]) + (match_operand:SF 1 "register_operand" "0,0,Yv")))] + "TARGET_MMX || TARGET_MMX_WITH_SSE" + "@ + punpckldq\t%0, %0 + # + #" + "&& reload_completed && TARGET_MMX_WITH_SSE" + [(const_int 0)] +{ + /* Emulate MMX vec_dupv2sf with SSE vec_dupv4sf. */ + rtx op0 = gen_rtx_REG (V4SFmode, REGNO (operands[0])); + rtx insn = gen_vec_dupv4sf (op0, operands[1]); + emit_insn (insn); + DONE; +} + [(set_attr "mmx_isa" "native,x64_noavx,x64_avx") + (set_attr "type" "mmxcvt,ssemov,ssemov") + (set_attr "mode" "DI,TI,TI")]) (define_insn "*mmx_concatv2sf" [(set (match_operand:V2SF 0 "register_operand" "=y,y") @@ -622,7 +635,7 @@ [(match_operand:V2SF 0 "register_operand") (match_operand:SF 1 "register_operand") (match_operand 2 "const_int_operand")] - "TARGET_MMX" + "TARGET_MMX || TARGET_MMX_WITH_SSE" { ix86_expand_vector_set (false, operands[0], operands[1], INTVAL (operands[2])); @@ -636,7 +649,20 @@ (vec_select:SF (match_operand:V2SF 1 "nonimmediate_operand" " xm,x,ym,y,m,m") (parallel [(const_int 0)])))] - "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))" + "TARGET_MMX + && !TARGET_MMX_WITH_SSE + && !(MEM_P (operands[0]) && MEM_P (operands[1]))" + "#" + "&& reload_completed" + [(set (match_dup 0) (match_dup 1))] + "operands[1] = gen_lowpart (SFmode, operands[1]);") + +(define_insn_and_split "*vec_extractv2sf_0_sse" + [(set (match_operand:SF 0 "nonimmediate_operand" "=x, m,f,r") + (vec_select:SF + (match_operand:V2SF 1 "nonimmediate_operand" " xm,x,m,m") + (parallel [(const_int 0)])))] + "TARGET_MMX_WITH_SSE && !(MEM_P (operands[0]) && MEM_P (operands[1]))" "#" "&& reload_completed" [(set (match_dup 0) (match_dup 1))] @@ -649,7 +675,9 @@ (vec_select:SF (match_operand:V2SF 1 "nonimmediate_operand" " 0,x,x,o,o,o,o") (parallel [(const_int 1)])))] - "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))" + "TARGET_MMX + && !TARGET_MMX_WITH_SSE + && !(MEM_P (operands[0]) && MEM_P (operands[1]))" "@ punpckhdq\t%0, %0 %vmovshdup\t{%1, %0|%0, %1} @@ -671,12 +699,33 @@ (set_attr "prefix" "orig,maybe_vex,orig,orig,orig,orig,orig") (set_attr "mode" "DI,V4SF,V4SF,SF,SF,SF,SF")]) +(define_insn "*vec_extractv2sf_1_sse" + [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,x,f,r") + (vec_select:SF + (match_operand:V2SF 1 "nonimmediate_operand" " x,x,o,o,o") + (parallel [(const_int 1)])))] + "TARGET_MMX_WITH_SSE && !(MEM_P (operands[0]) && MEM_P (operands[1]))" + "@ + %vmovshdup\t{%1, %0|%0, %1} + shufps\t{$0xe5, %1, %0|%0, %1, 0xe5} + # + # + #" + [(set_attr "isa" "sse3,noavx,*,*,*") + (set_attr "type" "sse,sseshuf1,ssemov,fmov,imov") + (set (attr "length_immediate") + (if_then_else (eq_attr "alternative" "1") + (const_string "1") + (const_string "*"))) + (set_attr "prefix" "maybe_vex,orig,orig,orig,orig") + (set_attr "mode" "V4SF,V4SF,SF,SF,SF")]) + (define_split [(set (match_operand:SF 0 "register_operand") (vec_select:SF (match_operand:V2SF 1 "memory_operand") (parallel [(const_int 1)])))] - "TARGET_MMX && reload_completed" + "(TARGET_MMX || TARGET_MMX_WITH_SSE) && reload_completed" [(set (match_dup 0) (match_dup 1))] "operands[1] = adjust_address (operands[1], SFmode, 4);") @@ -684,7 +733,7 @@ [(match_operand:SF 0 "register_operand") (match_operand:V2SF 1 "register_operand") (match_operand 2 "const_int_operand")] - "TARGET_MMX" + "TARGET_MMX || TARGET_MMX_WITH_SSE" { ix86_expand_vector_extract (false, operands[0], operands[1], INTVAL (operands[2])); @@ -1536,7 +1585,7 @@ [(match_operand:V2SI 0 "register_operand") (match_operand:SI 1 "register_operand") (match_operand 2 "const_int_operand")] - "TARGET_MMX" + "TARGET_MMX || TARGET_MMX_WITH_SSE" { ix86_expand_vector_set (false, operands[0], operands[1], INTVAL (operands[2])); @@ -1550,7 +1599,20 @@ (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "xm,x,ym,y,m") (parallel [(const_int 0)])))] - "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))" + "TARGET_MMX + && !TARGET_MMX_WITH_SSE + && !(MEM_P (operands[0]) && MEM_P (operands[1]))" + "#" + "&& reload_completed" + [(set (match_dup 0) (match_dup 1))] + "operands[1] = gen_lowpart (SImode, operands[1]);") + +(define_insn_and_split "*vec_extractv2si_0_sse" + [(set (match_operand:SI 0 "nonimmediate_operand" "=x,m,r") + (vec_select:SI + (match_operand:V2SI 1 "nonimmediate_operand" "xm,x,m") + (parallel [(const_int 0)])))] + "TARGET_MMX_WITH_SSE && !(MEM_P (operands[0]) && MEM_P (operands[1]))" "#" "&& reload_completed" [(set (match_dup 0) (match_dup 1))] @@ -1563,7 +1625,9 @@ (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" " 0,x,x,o,o,o") (parallel [(const_int 1)])))] - "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))" + "TARGET_MMX + && !TARGET_MMX_WITH_SSE + && !(MEM_P (operands[0]) && MEM_P (operands[1]))" "@ punpckhdq\t%0, %0 %vpshufd\t{$0xe5, %1, %0|%0, %1, 0xe5} @@ -1580,22 +1644,43 @@ (set_attr "prefix" "orig,maybe_vex,orig,orig,orig,orig") (set_attr "mode" "DI,TI,V4SF,SI,SI,SI")]) +(define_insn "*vec_extractv2si_1_sse" + [(set (match_operand:SI 0 "nonimmediate_operand" "=x,x,x,r") + (vec_select:SI + (match_operand:V2SI 1 "nonimmediate_operand" " x,x,o,o") + (parallel [(const_int 1)])))] + "TARGET_MMX_WITH_SSE + && !(MEM_P (operands[0]) && MEM_P (operands[1]))" + "@ + %vpshufd\t{$0xe5, %1, %0|%0, %1, 0xe5} + shufps\t{$0xe5, %1, %0|%0, %1, 0xe5} + # + #" + [(set_attr "isa" "sse2,noavx,*,*") + (set_attr "type" "sseshuf1,sseshuf1,ssemov,imov") + (set (attr "length_immediate") + (if_then_else (eq_attr "alternative" "0,1") + (const_string "1") + (const_string "*"))) + (set_attr "prefix" "maybe_vex,orig,orig,orig") + (set_attr "mode" "TI,V4SF,SI,SI")]) + (define_split [(set (match_operand:SI 0 "register_operand") (vec_select:SI (match_operand:V2SI 1 "memory_operand") (parallel [(const_int 1)])))] - "TARGET_MMX && reload_completed" + "(TARGET_MMX || TARGET_MMX_WITH_SSE) && reload_completed" [(set (match_dup 0) (match_dup 1))] "operands[1] = adjust_address (operands[1], SImode, 4);") (define_insn_and_split "*vec_extractv2si_zext_mem" - [(set (match_operand:DI 0 "register_operand" "=y,x,r") + [(set (match_operand:DI 0 "register_operand" "=x,r") (zero_extend:DI (vec_select:SI - (match_operand:V2SI 1 "memory_operand" "o,o,o") + (match_operand:V2SI 1 "memory_operand" "o,o") (parallel [(match_operand:SI 2 "const_0_to_1_operand")]))))] - "TARGET_64BIT && TARGET_MMX" + "TARGET_64BIT" "#" "&& reload_completed" [(set (match_dup 0) (zero_extend:DI (match_dup 1)))] @@ -1607,7 +1692,7 @@ [(match_operand:SI 0 "register_operand") (match_operand:V2SI 1 "register_operand") (match_operand 2 "const_int_operand")] - "TARGET_MMX" + "TARGET_MMX || TARGET_MMX_WITH_SSE" { ix86_expand_vector_extract (false, operands[0], operands[1], INTVAL (operands[2])); @@ -1627,7 +1712,7 @@ [(match_operand:V4HI 0 "register_operand") (match_operand:HI 1 "register_operand") (match_operand 2 "const_int_operand")] - "TARGET_MMX" + "TARGET_MMX || TARGET_MMX_WITH_SSE" { ix86_expand_vector_set (false, operands[0], operands[1], INTVAL (operands[2])); @@ -1638,7 +1723,7 @@ [(match_operand:HI 0 "register_operand") (match_operand:V4HI 1 "register_operand") (match_operand 2 "const_int_operand")] - "TARGET_MMX" + "TARGET_MMX || TARGET_MMX_WITH_SSE" { ix86_expand_vector_extract (false, operands[0], operands[1], INTVAL (operands[2])); @@ -1658,7 +1743,7 @@ [(match_operand:V8QI 0 "register_operand") (match_operand:QI 1 "register_operand") (match_operand 2 "const_int_operand")] - "TARGET_MMX" + "TARGET_MMX || TARGET_MMX_WITH_SSE" { ix86_expand_vector_set (false, operands[0], operands[1], INTVAL (operands[2])); @@ -1669,7 +1754,7 @@ [(match_operand:QI 0 "register_operand") (match_operand:V8QI 1 "register_operand") (match_operand 2 "const_int_operand")] - "TARGET_MMX" + "TARGET_MMX || TARGET_MMX_WITH_SSE" { ix86_expand_vector_extract (false, operands[0], operands[1], INTVAL (operands[2])); -- 2.20.1