x264中的avg_w8函数汇编实现

函数参数说明:

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

其它代码看注释

你可能感兴趣的:(汇编,算法)