Aarch64 NEON 中的 UADDL 与 UADDL2
UADDL vs UADDL2 in Aarch64 NEON
霓虹灯大会
我正在尝试了解 arm-v8 NEON。让我举例说明我正在尝试做什么。
我从数组 A 加载 16 字节(uchar 中的像素)。现在我想尝试 "lengthening ADD" 做空。从文档中,我看到 UADDL and UADDL 将分别对源寄存器的下半部分和上半部分进行加长。我可以编写以下代码来让它工作:
ld1 {V10.16B}, [x0]
uaddl V11.8H, V10.8B, V10.8B
uaddl2 V12.8H, V10.16B, V10.16B
st1 {V11.8H}, [x1], #16
st1 {V12.8H}, [x1], #16
NEON 内在函数
来到NEON Intrinsics,语法如下:(Refer Page 8)
uint16x8_t vaddl_u8 (uint8x8_t a, uint8x8_t b)
uint16x8_t vaddl_high_u8 (uint8x16_t a, uint8x16_t b)
这里,两个函数的输入是不同类型的。
所以一旦我加载了一个 uint8x16_t 变量,我应该如何将这个变量传递给 vaddl_u8?我可以做任何铸造吗?或者我是否必须将下半部分复制到另一个变量? (也就是说,这是额外的费用)
所以我的问题是,如何使用 NEON 内部函数实现这段汇编代码?
更新
- 我在 Ubuntu 16.04.
中使用 aarch64-linux-gnu-g++(gcc 版本 5.4.0)
你应该知道uint8x16_t
和uint8x8_t
是不同的数据类型。
下面是我会做的:
uint8x16_t a, b, c;
uint8x8_t low, high;
.
.
.
a = vld1q_u8(pSrc);
low = vget_low_u8(a);
high = vget_high_u8(a);
b = vaddl_u8(low, low);
c = vaddl_u8(high, high);
vst1q_u8(pDst++, b);
vst1q_u8(pDst++, c);
顺便说一句,请问您从哪里得到vaddl_high_u8
???
AndroidStudio 3.0.1 上的自动完成未将其显示为可行选项。
霓虹灯大会
我正在尝试了解 arm-v8 NEON。让我举例说明我正在尝试做什么。
我从数组 A 加载 16 字节(uchar 中的像素)。现在我想尝试 "lengthening ADD" 做空。从文档中,我看到 UADDL and UADDL 将分别对源寄存器的下半部分和上半部分进行加长。我可以编写以下代码来让它工作:
ld1 {V10.16B}, [x0]
uaddl V11.8H, V10.8B, V10.8B
uaddl2 V12.8H, V10.16B, V10.16B
st1 {V11.8H}, [x1], #16
st1 {V12.8H}, [x1], #16
NEON 内在函数
来到NEON Intrinsics,语法如下:(Refer Page 8)
uint16x8_t vaddl_u8 (uint8x8_t a, uint8x8_t b)
uint16x8_t vaddl_high_u8 (uint8x16_t a, uint8x16_t b)
这里,两个函数的输入是不同类型的。
所以一旦我加载了一个 uint8x16_t 变量,我应该如何将这个变量传递给 vaddl_u8?我可以做任何铸造吗?或者我是否必须将下半部分复制到另一个变量? (也就是说,这是额外的费用)
所以我的问题是,如何使用 NEON 内部函数实现这段汇编代码?
更新
- 我在 Ubuntu 16.04. 中使用 aarch64-linux-gnu-g++(gcc 版本 5.4.0)
你应该知道uint8x16_t
和uint8x8_t
是不同的数据类型。
下面是我会做的:
uint8x16_t a, b, c;
uint8x8_t low, high;
.
.
.
a = vld1q_u8(pSrc);
low = vget_low_u8(a);
high = vget_high_u8(a);
b = vaddl_u8(low, low);
c = vaddl_u8(high, high);
vst1q_u8(pDst++, b);
vst1q_u8(pDst++, c);
顺便说一句,请问您从哪里得到vaddl_high_u8
???
AndroidStudio 3.0.1 上的自动完成未将其显示为可行选项。