--- gcc/config/i386/sse.md.foo 2008-05-12 13:20:39.000000000 -0700 +++ gcc/config/i386/sse.md 2008-05-13 11:57:15.000000000 -0700 @@ -2250,6 +2250,17 @@ [(set_attr "type" "sselog1") (set_attr "mode" "V4SF")]) +(define_insn "*vec_concatv2sf_sse4_1" + [(set (match_operand:V2SF 0 "register_operand" "=x") + (vec_concat:V2SF + (match_operand:SF 1 "nonimmediate_operand" "0") + (match_operand:SF 2 "nonimmediate_operand" "xm")))] + "TARGET_SSE4_1" + "insertps\t{$0x10, %2, %0|%0, %2, 0x10}" + [(set_attr "type" "sselog") + (set_attr "mode" "V4SF")]) + +;; ??? In theory we can match memory for the MMX alternative, but allowing ;; ??? In theory we can match memory for the MMX alternative, but allowing ;; nonimmediate_operand for operand 2 and *not* allowing memory for the SSE ;; alternatives pretty much forces the MMX alternative to be chosen. @@ -4727,14 +4738,12 @@ (set_attr "mode" "TI,V4SF")]) (define_insn "*vec_concatv2si_sse4_1" - [(set (match_operand:V2SI 0 "register_operand" "=x,x") + [(set (match_operand:V2SI 0 "register_operand" "=x") (vec_concat:V2SI - (match_operand:SI 1 "nonimmediate_operand" "0,rm") - (match_operand:SI 2 "nonimmediate_operand" "rm,0")))] + (match_operand:SI 1 "nonimmediate_operand" "0") + (match_operand:SI 2 "nonimmediate_operand" "rm")))] "TARGET_SSE4_1" - "@ - pinsrd\t{$0x1, %2, %0|%0, %2, 0x1} - pinsrd\t{$0x0, %2, %0|%0, %2, 0x0}" + "pinsrd\t{$0x1, %2, %0|%0, %2, 0x1}" [(set_attr "type" "sselog") (set_attr "mode" "TI")]) @@ -4783,14 +4792,12 @@ (set_attr "mode" "TI,V4SF,V2SF")]) (define_insn "*vec_concatv2di_rex64_sse4_1" - [(set (match_operand:V2DI 0 "register_operand" "=x,x") + [(set (match_operand:V2DI 0 "register_operand" "=x") (vec_concat:V2DI - (match_operand:DI 1 "nonimmediate_operand" "0,rm") - (match_operand:DI 2 "nonimmediate_operand" "rm,0")))] + (match_operand:DI 1 "nonimmediate_operand" "0") + (match_operand:DI 2 "nonimmediate_operand" "rm")))] "TARGET_64BIT && TARGET_SSE4_1" - "@ - pinsrq\t{$0x1, %2, %0|%0, %2, 0x1} - pinsrq\t{$0x0, %2, %0|%0, %2, 0x0}" + "pinsrq\t{$0x1, %2, %0|%0, %2, 0x1}" [(set_attr "type" "sselog") (set_attr "mode" "TI")]) --- gcc/testsuite/gcc.target/i386/sse-set-ps-1.c.foo 2008-05-13 12:00:27.000000000 -0700 +++ gcc/testsuite/gcc.target/i386/sse-set-ps-1.c 2008-05-13 12:10:55.000000000 -0700 @@ -0,0 +1,40 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -msse" } */ + +#include "sse-check.h" + +#ifdef DEBUG +#include +#endif + +#include + +static void +__attribute__((noinline)) +test (float *v) +{ + union + { + __m128 x; + float f[4]; + } u; + unsigned int i; + + u.x = _mm_set_ps (v[3], v[2], v[1], v[0]); + + for (i = 0; i < sizeof (v) / sizeof (v[0]); i++) + if (v[i] != u.f[i]) + { +#ifdef DEBUG + printf ("%i: %f != %f\n", i, v[i], u.f[i]); +#endif + abort (); + } +} + +static void +sse_test (void) +{ + float v[4] = { -3, 2, 1, 9 }; + test (v); +} --- gcc/testsuite/gcc.target/i386/sse4_1-set-ps-1.c.foo 2008-05-13 12:00:31.000000000 -0700 +++ gcc/testsuite/gcc.target/i386/sse4_1-set-ps-1.c 2008-05-13 12:11:02.000000000 -0700 @@ -0,0 +1,41 @@ +/* { dg-do run } */ +/* { dg-require-effective-target sse4 } */ +/* { dg-options "-O2 -msse4.1" } */ + +#include "sse4_1-check.h" + +#ifdef DEBUG +#include +#endif + +#include + +static void +__attribute__((noinline)) +test (float *v) +{ + union + { + __m128 x; + float f[4]; + } u; + unsigned int i; + + u.x = _mm_set_ps (v[3], v[2], v[1], v[0]); + + for (i = 0; i < sizeof (v) / sizeof (v[0]); i++) + if (v[i] != u.f[i]) + { +#ifdef DEBUG + printf ("%i: %f != %f\n", i, v[i], u.f[i]); +#endif + abort (); + } +} + +static void +sse4_1_test (void) +{ + float v[4] = { -3, 2, 1, 9 }; + test (v); +}