Я соединил неоновый эквивалент встроенного в SSE2 _mm_shuffle_epi8.
Код, который у меня сейчас есть для этой цели:
static __forceinline __n128 shuffle8(
const __n128& a,
__n128 b) throw()
{
__n64x2 in =
{
a.DUMMYNEONSTRUCT.low64,
a.DUMMYNEONSTRUCT.high64
};
b.DUMMYNEONSTRUCT.low64 = vtbl2_u8(in, b.DUMMYNEONSTRUCT.low64);
b.DUMMYNEONSTRUCT.high64 = vtbl2_u8(in, b.DUMMYNEONSTRUCT.high64);
return b;
}
Теперь я не обязательно настроен на то, чтобы быть конечной формой вещей; но это еще не вопрос. Я тестировал свой код и обнаружил, что то, что я дал, работает точно так, как я намеревался при сборке / запуске в режиме отладки, но НЕ при сборке / запуске в режиме выпуска. В качестве примера:
#define simd_shuffle8(a, b) shuffle8(a, b)
...
simd test = keyschedule[1];
test = simd_shuffle8(test, test);
keychedule [1] имеет начальное значение
{0x858efc16, 0x8801f2e2, 0x1f0fb923, 0x11ecb78e}
В режиме отладки тест завершается со значением
{0x00000000, 0x00fc0000, 0x00110000, 0x00000000}
что так и должно быть. В режиме выпуска тест завершается со значением
{0x16161616, 0x16001616, 0x16161616, 0x16001616}
что не так, как должно быть. Что может быть причиной этой проблемы / как я могу ее исправить?
Так получилось, что после небольшого тестирования я обнаружил, что назначение значений DUMMYNEONSTRUCT low64 и high64 по отдельности, кажется, является той частью, которая вызывает проблемы — интересно, что выходные данные меняются в зависимости от порядка, в котором я их назначаю. Насколько я могу судить, похоже на ошибку в MSVS. В любом случае, всем, кому это интересно, я обошел это, вернув vcombine. Это произвело правильный вывод.