函数参数说明:
dst 结果存储地址, i_dst 存储结果的linesize
src1 计算源数据地址1,i_src1 计算源数据linesize
src2 计算源数据地址2, i_src2 计算源数据linesize
一 对应的c语言实现
static inline void pixel_avg2_w8_altivec( uint8_t *dst, intptr_t i_dst,
uint8_t *src1, intptr_t i_src1,
uint8_t *src2, int i_height )
{//r0 dst r1 i_dst
//r2 src1, r3 i_src1
//r4 src2 r5 height
vec_u8_t src1v, src2v;
for( int y = 0; y < i_height; y++ )
{
#if 0
src1v = vec_vsx_ld( 0, src1 );
src2v = vec_vsx_ld( 0, src2 );
src1v = vec_avg( src1v, src2v );
VEC_STORE8(src1v, dst);
#endif
for (int i = 0; i < 8; i++) { //每一行计算8个值的平均值
dst[i] = (src1[i] + src2[i]) >> 1;
}
dst += i_dst;
src1 += i_src1;
src2 += i_src1;
}
}
二 汇编函数实现
function pixel_avg2_w8_neon
ldr ip, [sp, #4] //保存 ip = *(sp + 4) height
push {lr} //要压栈的寄存器列表
ldr lr, [sp, #4] //lr = *(sp + 4) src2
avg2_w8_loop: //process 128 bits per time
subs ip, ip, #2 // ip = ip - 2
vld1.64 {d0}, [r2], r3 //从r2 + r3 位置加载64bit 到 d0
vld1.64 {d2}, [lr], r3 //从lr + r3 位置加载64 bits到 d2
vrhadd.u8 d0, d0, d2 //d0 = d0(uint8) + d2(uint8)
vld1.64 {d1}, [r2], r3 //从 r2 + r3 位置加载64bits到 d1
vld1.64 {d3}, [lr], r3 //从 lr + r3 位置加载64bits到 d3
vrhadd.u8 d1, d1, d3 //d1 = d1(uint8) + d3(uint8)
vst1.64 {d0}, [r0,:64], r1 // r1 + r0 = *d0
vst1.64 {d1}, [r0,:64], r1 // r1 + r0 + 64 = *d1
bgt avg2_w8_loop
pop {pc}
endfunc
arm环境下,寄存器传递参数有4个,寄存器r0,r1,r2,r3 。一共可以到r11。
其它的都是入栈。
入栈都是反向入栈的,最后的参数最先入栈
ldr ip, [sp, #4]. 最后一个参数height
ldr lr, [sp, #4] 倒数第二个参数src2
其它代码看注释