Как альтернативный ответ на мой другой ответ, вот как это сделать с помощью встроенной сборки, а не встроенной. (Как Томас Порнин отмечает в моем другом ответе, встроенные функции, как правило, лучше, потому что они более переносимы, но иногда вы тоже хотите что-то подобное.)
Сначала я обманул - я взял версию со встроенной функцией, скомпилировал ее с помощью -S
и посмотрел на получившийся код сборки, который выглядит так:
movsd -64(%rbp), %xmm0
movhpd -56(%rbp), %xmm0
movsd -48(%rbp), %xmm1
movhpd -40(%rbp), %xmm1
blendpd $3, %xmm1, %xmm0
movlpd %xmm0, -64(%rbp)
movhpd %xmm0, -56(%rbp)
Здесь вы можете увидеть несколько вещей, отличных от вашего исходного кода. Во-первых, обратите внимание, что два 128-битных аргумента являются , а не немедленными - это регистры xmm0 и xmm1. Кроме того, у вас есть операнды в неправильном порядке - маска идет первой, а регистр, содержащий выходные данные, идет последним. Исправьте это, и код скомпилируется.
Вторая проблема заключается в том, что вы сохраняете результат из общего регистра в y
, а инструкция blendpd не затрагивает общие регистры, так что это просто хранение мусора. Вам нужен регистр xmm0
, который вы получаете вместе с =Yz
(см. Документацию GCC здесь ). И вы не можете сохранить это в long long
, который составляет 64 бита; вам нужна 128-битная векторная переменная. Решая все эти проблемы, исправляем код:
#include<iostream>
#include<smmintrin.h>
using namespace std;
int main()
{
__m128d y;
__asm("blendpd $0x3,%%xmm1,%%xmm0":
"=Yz" (y):
);
// cout<<y;
return 0;
}
Вы заметите, что мне пришлось закомментировать строку cout
, так как в ней не предусмотрено обработки векторов SSE; вам нужно будет использовать встроенную _mm_store_pd
, чтобы сначала получить отдельные двойные значения из y
. (Или вы можете добавить больше встроенной сборки для вызова инструкций movhpd
и movhld
, чтобы получить двойные значения непосредственно из регистра, вместо использования ограничения для присвоения им y
.)
И вот, он у вас есть - он компилируется и работает нормально. Конечно, входные значения не определены (что бы то ни было в этих регистрах случайным образом), поэтому в любом случае выходные данные являются мусором - вам нужно сначала что-то добавить для загрузки значений в регистры, если вы хотите получить значимый результат.