7

I really can't get what "keyword" like __m128d is in C++.

I'm using MSVC, and it says: The __m128d data type, for use with the Streaming SIMD Extensions 2 instructions intrinsics, is defined in <emmintrin.h>.

So, is it a Data Type? typedef? If I do:

#include <emmintrin.h>

int main() {
    __m128d x;
}

I can't see the defination on <emmintrin.h>. It seems a keyword of compiler? Does it automatically convert that keyword to somethings like "move register xmm0" etc? Or which kind of operation does?

It doesn't seems a data type at all.

Can someone shine me?

gsamaras
  • 71,951
  • 46
  • 188
  • 305
markzzz
  • 47,390
  • 120
  • 299
  • 507
  • 1
    A 128 bit register? – gsamaras Dec 13 '18 at 08:21
  • It represents an XMM register of 128 bit width. – YiFei Dec 13 '18 at 08:22
  • Yes it _is_ a typedef. Look closely at the `` file. – Jabberwocky Dec 13 '18 at 08:24
  • 2
    https://clang.llvm.org/doxygen/emmintrin_8h_source.html line 29? – default Dec 13 '18 at 08:25
  • 3
    Think of `__m128d` in the same way that would a `double` - in your code it's just a type, but under the hood it could be a memory location, a register, some combination of both, or even optimised away completely. – Paul R Dec 13 '18 at 08:38
  • @PaulR: what do you mean with "or even optimised away completely."? – markzzz Dec 13 '18 at 09:01
  • @markzzz: just as with any other simple variable type it's perfectly possible for the compiler to obviate the need for a temporary value that is represented in your code as a variable (this is one of the things that makes using a debugger with optimised code quite tricky, as variables in the source code may not even exist in the generated binary). – Paul R Dec 13 '18 at 09:33
  • @PaulR but its still on register. Or do you mean as "const" that it simply written in the asm? – markzzz Dec 13 '18 at 09:53
  • 2
    @markzzz: there are a number of code generation optimisations that can cause a variable to "disappear", e.g. an explicit load and a subsequent arithmetic operation in your code could be elided into a single arithmetic instruction with a memory operand instead of a register operand. Here is [an example](https://gcc.godbolt.org/z/OXHwDJ) - note that `v1` "disappears". – Paul R Dec 13 '18 at 10:49

1 Answers1

9

Is it a typedef?

Yes!

__m128d is a data type that the compiler will hopefully store in a XMM 128 bit register when optimizing (if not optimizing it away as @PeterCordes commented). It's not inherently different from an int or long, which the compiler will hopefully store in integer registers when optimizing.

The actual definition is compiler-specific; code that intends to be portable between MSVC and the other major compilers that implement Intel's intrinsics should avoid depending on the details of the definition.

MSVC defines vector types as a union of arrays of different element sizes.

In compilers that implement GNU C extensions (gcc and clang), it is typedef'ed as a 16-byte GNU C native vector of doubles:

// From gcc 7.3's emmintrin.h  (SSE2 extensions).  SSE1 stuff in xmmintrin.h

/* The Intel API is flexible enough that we must allow aliasing with other
   vector types, and their scalar components.  */
typedef long long __m128i __attribute__ ((__vector_size__ (16), __may_alias__));
typedef double __m128d __attribute__ ((__vector_size__ (16), __may_alias__));

in <emmintrin.h>, as @Default commented.

The may_alias attribute tells the compiler that __m128d* can alias other types the same way that char* can, for the purposes of optimization based on C++ strict-aliasing rules.


Example of usage: (initialization is portable between MSVC and other compilers)

__m128d a2 = { -1.388539L, 0.0L };


For __m128, check the Intel forum and <xmmintrin.h>.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
gsamaras
  • 71,951
  • 46
  • 188
  • 305
  • 5
    It's not literally a register, just like `int foo;` isn't literally an integer register. It's a C variable that the compiler will hopefully keep in a register when optimizing, if it doesn't optimize away. It's a data type that can map to an XMM register. – Peter Cordes Dec 13 '18 at 08:29
  • 1
    @PeterCordes indeed, injected that to my answer, thanks! – gsamaras Dec 13 '18 at 08:31
  • 3
    You edited out the MSVC definition, and had an old or simplified version of the GNU C definition. I fixed that for you, and added a big warning that it *is* different between implementations. I'm not 100% sure how Intel's own compiler defines it. ICC implements GNU C extensions, so it does support GNU C native vectors. But IDK if they define `__m128` in terms of native vectors the way gcc does. – Peter Cordes Dec 13 '18 at 08:45