Замена PowerPC vec_xl_be с использованием встроенной сборки
Я все еще преследую свою недостающую работу. Я хочу выполнить загрузку, которая избегает автоматического обмена с обратным порядком байтов, который происходит с прямым порядком байтов. Это должно сохранить две дополнительные инструкции по загрузке (ненужные xxswapd
а также xxlnand
).
Если я правильно разбираю выпуск 84753, мне нужно lxvd2x
который vec_xl_be
, Проблема в, vec_xl_be
не показывался в GCC до января 2018 года (или он все еще продолжается).
Я пытаюсь включить замену vec_xl_be
, Когда я компилирую Toy Test, показанный ниже, он компилируется нормально. У него нет регистровых давлений:
$ g++ -g3 -O3 -mcpu=power8 test.cxx -c
$ objdump --disassemble test.o | c++filt
test.o: file format elf64-powerpcle
Disassembly of section .text:
0000000000000000 <VEC_XL_BE(unsigned char const*, int)>:
0: 99 26 43 7c lxvd2x vs34,r3,r4
4: 20 00 80 4e blr
8: 00 00 00 00 .long 0x0
c: 00 09 00 00 .long 0x900
10: 00 00 00 00 .long 0x0
...
Тем не менее, когда я копирую / вставляю VEC_XL_BE
в реальную тестовую программу, то я получаю следующие ошибки. В реальной тестовой программе GCC используются 40-50 регистров Altivec и VSX:
$ g++ -DTEST_MAIN -g3 -O3 -mcpu=power8 sha256-p8.cxx -o sha256-p8.exe
/tmp/ccbDnfFr.s: Assembler messages:
/tmp/ccbDnfFr.s:758: Error: operand out of range (32 is not between 0 and 31)
/tmp/ccbDnfFr.s:983: Error: operand out of range (48 is not between 0 and 31)
Тест на игрушку может быть неверным. Она собрана из отчета о проблемах GCC, справочных страниц по простым машинам и машинам для конкретных машин. Я знаю, что флаги, используемые для компиляции и компоновки, верны, потому что они рекомендованы IBM в разделе Рекомендуемые параметры отладки, компилятора и компоновщика для настройки процессора мощности.
Добавление параметров, таких как -mpower8-vector
, -Wa,-mpower8
а также -Wa,-mvsx
не помогают
У меня два вопроса. Во-первых, это код для VEC_XL_BE
правильный? Если нет, то что это должно быть?
Во-вторых, если VEC_XL_BE
правильно, тогда как я могу обойти проблему "операнд вне диапазона"?
Игрушечный тест
$ cat test.cxx
#include <stdint.h>
#if defined(__ALTIVEC__)
# include <altivec.h>
# undef vector
# undef pixel
# undef bool
#endif
typedef __vector unsigned int uint32x4_p8;
uint32x4_p8 VEC_XL_BE(const uint8_t* data, int offset)
{
#if defined(__xlc__) || defined(__xlC__)
return (uint32x4_p8)vec_xl_be(offset, (uint8_t*)data);
#else
uint32x4_p8 res;
__asm(" lxvd2x %x0, %1, %2 \n\t"
: "=wa" (res)
: "g" (data), "g" (offset));
return res;
#endif
}
int main(int argc, char* argv[])
{
uint32x4_p8 t = VEC_XL_BE((const uint8_t*)argv, argc);
return 0;
}
1 ответ
Во-первых, правильный ли код для VEC_XL_BE? Если нет, то что это должно быть?
Похоже, проблемы с машиной были проблемой.
Во-вторых, если VEC_XL_BE правильно, то как я могу обойти проблему "операнд вне диапазона"?
По словам Питера Бергнера, строфа должна быть:
uint32x4_p8 VEC_XL_BE(const uint8_t* data, int offset)
{
#if defined(__xlc__) || defined(__xlC__)
return (uint32x4_p8)vec_xl_be(offset, (uint8_t*)data);
#else
uint32x4_p8 res;
__asm(" lxvd2x %x0, %1, %2 \n\t"
: "=wa" (res)
: "b" (data), "r" (offset));
return res;
#endif
}
Однажды я изменил ограничение указателя на "b"
и ограничение смещения "r"
проблема ушла