使用单通道加载指令 ( vld1 <register>[<lane>], [<address]
) 将 4 个字节加载到 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);