How to convert SSEish _mm_set1_ps() into AltiVec correctly?

Justin Hibbits jrh29 at alumni.cwru.edu
Mon Jul 14 16:20:56 UTC 2014


On Mon, Jul 14, 2014 at 8:42 AM, Alexey Dokuchaev <danfe at nsu.ru> wrote:
> Hi there,
>
> I'm a bit confused about how to convert _mm_set1_ps() [1] SSE function into
> its AltiVec equivalent.  To start with, I need to set all four floats of a
> vector to the same value.  So far, I've come up with two versions that work
> with GCC or Clang, but I want to have a code that works with any compiler,
> and is technically correct (works not just by accident).
>
> On PowerPC, there are two altivec.h files provided by GCC 4.2 and Clang:
>
>     /usr/include/clang/3.4.1/altivec.h
>     /usr/include/gcc/4.2/altivec.h
>
> The problem is that they are substantially different (read: offer different
> APIs).  For Clang, I can simply write something like this:
>
>     union {
>         float f1, f2, f3, f4;
>         vector float f;
>     } foo;
>
>     foo.f = vec_splats(42.f);
>     // all f1, f2, f3, f4 are 42.f now
>
> But this does not work with GCC: it simply does not offer vec_splats(float);
> however, I can do this:
>
>     float init = 42.f;
>     foo.f = vec_ld(0, &init);
>
> And it will set all four components to 42.f.  Yet this is technically wrong,
> as apparently I'm supposed to pass an entire array of floats, e.g. if built
> with Clang all floats are "nan".  Lets change the code to this:
>
>     float init[4] = { 42.f };
>     foo.f = vec_ld(0, init);
>
> This works with both compilers, but I'm not sure if it is correct.  Can any
> of our AltiVec experts give me some hint here?  Thanks.
>
> ./danfe
>
> [1] http://msdn.microsoft.com/en-us/library/vstudio/2x1se8ha%28v=vs.100%29.aspx

I just tried the following:

vector float a = (vector float){42.0f};
vector float b = vec_splat(a, 0);

Haven't done anything more than compile test it, but it builds with
both gcc and clang.  GCC uses vspltw, while clang uses vperm.

- Justin


More information about the freebsd-ppc mailing list