Загрузите 4 байта, используя инструкцию загрузки с одной дорожкой (vld1 <register>[<lane>], [<address]
), в q-регистр, а затем используйте две инструкции длины хода (vmovl
), чтобы повысить их сначала до 16, а затем до 32 бит.Результатом должно быть что-то вроде (в синтаксисе GNU)
vld1 d0[0], [<address>] @Now d0 = (*<addr>, *<addr+1>, *<addr+2>, *<addr+3>, <junk>, ... <junk> )
vmovl.u8 q0, d0 @Now q1 = (d0, d1) = ((uint16_t)*<addr>, ... (uint16_t)*<addr+3>, <junk>, ... <junk>)
vmovl.u16 q0, d2 @Now d0 = ((uint32_t)*<addr>, ... (uint32_t)*<addr+3>), d1 = (<junk>, ... <junk>)
Если вы можете гарантировать, что <address>
выровнено по 4 байта, вместо этого напишите [<address>: 32]
в инструкции загрузки, чтобы сохранить цикл илидва.Если вы сделаете это, а адрес не выровнен, вы получите ошибку, однако.
Хм, я просто понял, что вы хотите использовать встроенные функции, а не ассемблер, так что здесь то же самое с встроенными функциями.
uint32x4_t v8; // Will actually hold 4 uint8_t
v8 = vld1_lane_u32(ptr, v8, 0);
const uint16x4_t v16 = vget_low_u16(vmovl_u8(vreinterpret_u8_u32(v8)));
const uint32x4_t v32 = vmovl_u16(v16);