Intel VCVTTPD2QQ загружает 4 номера, а не 8 - PullRequest
0 голосов
/ 05 февраля 2020

Руководство по разработке программного обеспечения Intel описывает VCVTTPD2QQ как:

Convert eight packed double-precision floating-point values
from zmm2/m512 to eight packed quadword integers in zmm1
using truncation with writemask k1.

Я использую VCVTTPD2QQ для загрузки восьми 64-битных операций с двойной точностью в zmm1, закодированных следующим образом:

mov rax,18446744073709551615
KMOVQ k1,rax
EVEX.512.66.0F.W1 VCVTTPD2QQ zmm1 {k1}{z},[r11+r15]

Я заполняю k1 всеми 1, чтобы указать, чтобы переместить все 8 чисел.

Если я кодирую его таким образом, я все равно получаю тот же результат:

VCVTTPD2QQ zmm1 {k1}{z},[r11+r15]

Руководство Intel различает три возможных кодировки по именам регистров; если имя является регистром zmm, то оно должно переместиться на 8.

Почему в zmm1 загружается только 4, а не 8 точек данных?

РЕДАКТИРОВАТЬ:

Я исключил маску записи, которая, как сказал Питер Кордес ниже, здесь не имеет значения. Я также создал массив памяти и получил к нему доступ:

test_array:  dq 24.0, 93.0, 43.0, 28.0, 86.0, 143.0, 17.0, 129.0, 33.0, 67.0, 55.0

mov rdi,test_array
EVEX.512.66.0F.W1 VCVTTPD2QQ zmm1,[rdi]

Отладчик показывает то же самое, что и доступ к массиву, который читается из внешнего файла (4 элемента, а не 8). Вот вывод gdb:

(gdb) i r zmm1
zmm1 {v16_float = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v8_double = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0}, v64_int8 = {0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5d, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x1c, 0x0 <repeats 39 times>}, v32_int16 = {0x18, 0x0, 0x0, 0x0, 0x5d,
0x0, 0x0, 0x0, 0x2b, 0x0, 0x0, 0x0, 0x1c, 0x0 <repeats 19 times>},    v16_int32 = {0x18, 0x0, 0x5d, 0x0, 0x2b, 0x0, 0x1c, 0x0, 0x0, 0x0, 0x0, 0x0,     0x0, 0x0, 0x0, 0x0}, v8_int64 = {0x18, 0x5d, 0x2b, 0x1c, 0x0, 0x0, 0x0,
0x0}, v4_int128 = {0x5d0000000000000018, 0x1c000000000000002b, 0x0, 0x0}}

В разделе v8_int64 мы видим первые четыре значения (правильные), но последние четыре равны нулю, а входные данные не равны нулю.

1 Ответ

2 голосов
/ 05 февраля 2020

Как Питер Кордес и Майкл Петч оба подозревали в своих последних комментариях, эта проблема была вызвана ошибкой в ​​gdb. По-видимому, GDB не может отображать верхние 256 бит регистра Zmm.

Простой тест, как сказал Питер Кордес, состоит в объявлении тестового массива в памяти:

section .data
test_array2: times 8 dq 0

section .text
VCVTTPD2QQ zmm1,[r11+r15]

mov rdi,test_array2
vmovdqu64 [rdi],zmm1

mov rax,[rdi+0]
mov rax,[rdi+8]
mov rax,[rdi+16]
mov rax,[rdi+24]
mov rax,[rdi+32]
mov rax,[rdi+40]
mov rax,[rdi+48]
mov rax,[rdi+56]

Используйте gdb для перехода по каждой из строк rax, [rdi + xxx] и увидеть значение в rax. В моем случае все 8 значений соответствуют входным данным, хотя GDB показывает верхние 256 битов zmm1 как ноль.

Если бы я опубликовал пример MCR с исходным вопросом, другие, возможно, заметили это раньше.

Спасибо за все комментарии.

...