[PATCH 31/40] i386: Emulate MMX pshufb with SSE version
H.J. Lu
hjl.tools@gmail.com
Mon Feb 11 22:56:00 GMT 2019
Emulate MMX version of pshufb with SSE version by masking out the bit 3
of the shuffle control byte. Only SSE register source operand is allowed.
PR target/89021
* config/i386/sse.md (ssse3_pshufbv8qi3): Renamed to ...
(ssse3_pshufbv8qi3_mmx): This.
(ssse3_pshufbv8qi3): New.
(ssse3_pshufbv8qi3_sse): Likewise.
---
gcc/config/i386/sse.md | 63 ++++++++++++++++++++++++++++++++++++++++--
1 file changed, 61 insertions(+), 2 deletions(-)
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index dc35fcfd34a..6e748d0543c 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -15819,18 +15819,77 @@
(set_attr "btver2_decode" "vector")
(set_attr "mode" "<sseinsnmode>")])
-(define_insn "ssse3_pshufbv8qi3"
+(define_expand "ssse3_pshufbv8qi3"
+ [(set (match_operand:V8QI 0 "register_operand")
+ (unspec:V8QI [(match_operand:V8QI 1 "register_operand")
+ (match_operand:V8QI 2 "nonimmediate_operand")]
+ UNSPEC_PSHUFB))]
+ "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSSE3"
+{
+ if (TARGET_MMX_WITH_SSE)
+ {
+ /* Emulate MMX version of pshufb with SSE version by masking
+ out the bit 3 of the shuffle control byte. */
+ rtvec par = gen_rtvec (4, GEN_INT (0xf7f7f7f7),
+ GEN_INT (0xf7f7f7f7),
+ GEN_INT (0xf7f7f7f7),
+ GEN_INT (0xf7f7f7f7));
+ rtx vec_const = gen_rtx_CONST_VECTOR (V4SImode, par);
+ vec_const = force_const_mem (V4SImode, vec_const);
+ rtx op3 = gen_reg_rtx (V4SImode);
+ rtx op4 = gen_reg_rtx (V4SImode);
+ rtx insn = gen_rtx_SET (op4, vec_const);
+ emit_insn (insn);
+ rtx op2 = force_reg (V8QImode, operands[2]);
+ insn = gen_ssse3_pshufbv8qi3_sse (operands[0], operands[1],
+ op2, op3, op4);
+ emit_insn (insn);
+ DONE;
+ }
+})
+
+(define_insn "ssse3_pshufbv8qi3_mmx"
[(set (match_operand:V8QI 0 "register_operand" "=y")
(unspec:V8QI [(match_operand:V8QI 1 "register_operand" "0")
(match_operand:V8QI 2 "nonimmediate_operand" "ym")]
UNSPEC_PSHUFB))]
- "TARGET_SSSE3"
+ "TARGET_SSSE3 && !TARGET_MMX_WITH_SSE"
"pshufb\t{%2, %0|%0, %2}";
[(set_attr "type" "sselog1")
(set_attr "prefix_extra" "1")
(set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
(set_attr "mode" "DI")])
+(define_insn_and_split "ssse3_pshufbv8qi3_sse"
+ [(set (match_operand:V8QI 0 "register_operand" "=x,Yv")
+ (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "0,Yv")
+ (match_operand:V8QI 2 "register_operand" "x,Yv")]
+ UNSPEC_PSHUFB))
+ (set (match_operand:V4SI 3 "register_operand" "=x,Yv")
+ (unspec:V4SI [(match_operand:V4SI 4 "register_operand" "3,3")]
+ UNSPEC_PSHUFB))]
+ "TARGET_SSSE3 && TARGET_MMX_WITH_SSE"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+{
+ /* Mask out the bit 3 of the shuffle control byte. */
+ rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
+ rtx op3 = operands[3];
+ rtx insn = gen_andv4si3 (op3, op3, op2);
+ emit_insn (insn);
+ /* Generate SSE version of pshufb. */
+ rtx op0 = gen_rtx_REG (V16QImode, REGNO (operands[0]));
+ rtx op1 = gen_rtx_REG (V16QImode, REGNO (operands[1]));
+ op3 = gen_rtx_REG (V16QImode, REGNO (op3));
+ insn = gen_ssse3_pshufbv16qi3 (op0, op1, op3);
+ emit_insn (insn);
+ DONE;
+}
+ [(set_attr "mmx_isa" "x64_noavx,x64_avx")
+ (set_attr "type" "sselog1")
+ (set_attr "mode" "TI,TI")])
+
(define_insn "<ssse3_avx2>_psign<mode>3"
[(set (match_operand:VI124_AVX2 0 "register_operand" "=x,x")
(unspec:VI124_AVX2
--
2.20.1
More information about the Gcc-patches
mailing list