Замена 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" проблема ушла

Другие вопросы по тегам