diff options
author | H.J. Lu <hongjiu.lu@intel.com> | 2019-05-15 15:11:41 +0000 |
---|---|---|
committer | H.J. Lu <hjl@gcc.gnu.org> | 2019-05-15 08:11:41 -0700 |
commit | 3d34e8b0ea84b8f2c8db0c32272bc3d84c818b9e (patch) | |
tree | 962bd63a4daa324e2953d395aca1b31adc661386 /gcc | |
parent | 74e299b9299a03ddf44cfa7f0660c908c3257dfc (diff) | |
download | gcc-3d34e8b0ea84b8f2c8db0c32272bc3d84c818b9e.zip gcc-3d34e8b0ea84b8f2c8db0c32272bc3d84c818b9e.tar.gz gcc-3d34e8b0ea84b8f2c8db0c32272bc3d84c818b9e.tar.bz2 |
i386: Emulate MMX pshufw with SSE
Emulate MMX pshufw with SSE. Only SSE register source operand is allowed.
PR target/89021
* config/i386/mmx.md (mmx_pshufw): Also check TARGET_MMX and
TARGET_MMX_WITH_SSE.
(mmx_pshufw_1): Add SSE emulation.
(*vec_dupv4hi): Changed to define_insn_and_split and also allow
TARGET_MMX_WITH_SSE to support SSE emulation.
From-SVN: r271226
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/config/i386/mmx.md | 81 |
2 files changed, 74 insertions, 16 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4d2080f..97a0965 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,6 +1,15 @@ 2019-05-15 H.J. Lu <hongjiu.lu@intel.com> PR target/89021 + * config/i386/mmx.md (mmx_pshufw): Also check TARGET_MMX and + TARGET_MMX_WITH_SSE. + (mmx_pshufw_1): Add SSE emulation. + (*vec_dupv4hi): Changed to define_insn_and_split and also allow + TARGET_MMX_WITH_SSE to support SSE emulation. + +2019-05-15 H.J. Lu <hongjiu.lu@intel.com> + + PR target/89021 * config/i386/constraints.md (Yw): New constraint. * config/i386/mmx.md (*vec_dupv2si): Changed to define_insn_and_split and also allow TARGET_MMX_WITH_SSE to diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md index 80859d5..c19ee07 100644 --- a/gcc/config/i386/mmx.md +++ b/gcc/config/i386/mmx.md @@ -1348,9 +1348,10 @@ (define_expand "mmx_pshufw" [(match_operand:V4HI 0 "register_operand") - (match_operand:V4HI 1 "nonimmediate_operand") + (match_operand:V4HI 1 "register_mmxmem_operand") (match_operand:SI 2 "const_int_operand")] - "TARGET_SSE || TARGET_3DNOW_A" + "(TARGET_MMX || TARGET_MMX_WITH_SSE) + && (TARGET_SSE || TARGET_3DNOW_A)" { int mask = INTVAL (operands[2]); emit_insn (gen_mmx_pshufw_1 (operands[0], operands[1], @@ -1362,14 +1363,15 @@ }) (define_insn "mmx_pshufw_1" - [(set (match_operand:V4HI 0 "register_operand" "=y") + [(set (match_operand:V4HI 0 "register_operand" "=y,Yv") (vec_select:V4HI - (match_operand:V4HI 1 "nonimmediate_operand" "ym") + (match_operand:V4HI 1 "register_mmxmem_operand" "ym,Yv") (parallel [(match_operand 2 "const_0_to_3_operand") (match_operand 3 "const_0_to_3_operand") (match_operand 4 "const_0_to_3_operand") (match_operand 5 "const_0_to_3_operand")])))] - "TARGET_SSE || TARGET_3DNOW_A" + "(TARGET_MMX || TARGET_MMX_WITH_SSE) + && (TARGET_SSE || TARGET_3DNOW_A)" { int mask = 0; mask |= INTVAL (operands[2]) << 0; @@ -1378,11 +1380,20 @@ mask |= INTVAL (operands[5]) << 6; operands[2] = GEN_INT (mask); - return "pshufw\t{%2, %1, %0|%0, %1, %2}"; + switch (which_alternative) + { + case 0: + return "pshufw\t{%2, %1, %0|%0, %1, %2}"; + case 1: + return "%vpshuflw\t{%2, %1, %0|%0, %1, %2}"; + default: + gcc_unreachable (); + } } - [(set_attr "type" "mmxcvt") + [(set_attr "mmx_isa" "native,x64") + (set_attr "type" "mmxcvt,sselog") (set_attr "length_immediate" "1") - (set_attr "mode" "DI")]) + (set_attr "mode" "DI,TI")]) (define_insn "mmx_pswapdv2si2" [(set (match_operand:V2SI 0 "register_operand" "=y") @@ -1395,16 +1406,54 @@ (set_attr "prefix_extra" "1") (set_attr "mode" "DI")]) -(define_insn "*vec_dupv4hi" - [(set (match_operand:V4HI 0 "register_operand" "=y") +(define_insn_and_split "*vec_dupv4hi" + [(set (match_operand:V4HI 0 "register_operand" "=y,Yv,Yw") (vec_duplicate:V4HI (truncate:HI - (match_operand:SI 1 "register_operand" "0"))))] - "TARGET_SSE || TARGET_3DNOW_A" - "pshufw\t{$0, %0, %0|%0, %0, 0}" - [(set_attr "type" "mmxcvt") - (set_attr "length_immediate" "1") - (set_attr "mode" "DI")]) + (match_operand:SI 1 "register_operand" "0,Yv,r"))))] + "(TARGET_MMX || TARGET_MMX_WITH_SSE) + && (TARGET_SSE || TARGET_3DNOW_A)" + "@ + pshufw\t{$0, %0, %0|%0, %0, 0} + # + #" + "TARGET_MMX_WITH_SSE && reload_completed" + [(const_int 0)] +{ + rtx op; + operands[0] = lowpart_subreg (V8HImode, operands[0], + GET_MODE (operands[0])); + if (TARGET_AVX2) + { + operands[1] = lowpart_subreg (HImode, operands[1], + GET_MODE (operands[1])); + op = gen_rtx_VEC_DUPLICATE (V8HImode, operands[1]); + } + else + { + operands[1] = lowpart_subreg (V8HImode, operands[1], + GET_MODE (operands[1])); + rtx mask = gen_rtx_PARALLEL (VOIDmode, + gen_rtvec (8, + GEN_INT (0), + GEN_INT (0), + GEN_INT (0), + GEN_INT (0), + GEN_INT (4), + GEN_INT (5), + GEN_INT (6), + GEN_INT (7))); + + op = gen_rtx_VEC_SELECT (V8HImode, operands[1], mask); + } + rtx insn = gen_rtx_SET (operands[0], op); + emit_insn (insn); + DONE; +} + [(set_attr "mmx_isa" "native,x64,x64_avx") + (set_attr "type" "mmxcvt,sselog1,ssemov") + (set_attr "length_immediate" "1,1,0") + (set_attr "mode" "DI,TI,TI")]) (define_insn_and_split "*vec_dupv2si" [(set (match_operand:V2SI 0 "register_operand" "=y,x,Yv,Yw") |