Arm Neon VST1.datatype指令

流水賬:

過年在家閒的發慌,年前被通知彙編代碼出了點bug。原來是寬度爲6的色度插值彙編沒寫。走寬度爲8的分支鐵定會崩。

如果僅僅發現這些問題,就可以直接解決,不用折騰好兩個下午了。

回想9月份的時候,發現寬爲2的色度塊漏寫彙編,修過一次。那時候給自己埋了坑。

一般插值輸入src: uint_8

            輸出dst: uint_8

所以對於寬度爲2的塊,最後每行需要輸出的是2個8bit的數據。

/*d0裏爲8個8bit的插值結果。width=2的插值結果,存在前2個8bit裏,所以先取32bit,再用strh指令代表存一半(store half)*/
vmov.u16      r6, d0[0]
strh          r6, [r0], r1


但是在插值中間結果的一步,輸出dst: int_16,當初的代碼寫法仍和前面一樣。很顯然最後結果只拿到了一個16bit。

所以這時候想當然的用了指令:

VST1.16 D[0], [r0], [r1]   

希望將D[0]的32bit數據存出去。

可是結果是瞎了狗眼咯。把C代碼移過來,一點一點的對比C代碼和彙編代碼插值的結果;發現第二列的位置插值結果是錯誤的;

把指令改成:

VST1.32 D[0], [r0], [r1]   

就可以完美的取出2個16bit數據了。

揉揉瞎了的狗眼,做了一波實驗,主要是想知道VST1後面的datatype對最終的結果有沒有影響。很久以前的實驗和經驗告訴我,

VSTn{cond}.datatype list, [Rn{@align}], Rm 

存入數據的位數(幾bit)直接與list列表相關的。

實驗的代碼以及運行結果如下:

傳入的數組uint_8類型 {1,2,3,4,5,6,7,8,9,10} 輸出爲int_16的類型。

neon_D_reg_test:
    vld1.8  {d0}, [r0]    //將數組load進來,進來8個8bit 1,2,3,4,5,6,7,8,0,0
    vaddl.u8   q2, d0, d0 //變成8個16bit 2,4,6,8,10,12,14,16,0,0
    vmov.s16   q3, #3
    vsub.s16   q2, q3
    //vst1.32 {q2}, [r1]    // -1, 1, 3, 5, 7, 9, 11, 13, 0, 0
    //vst1.32 {d4}, [r1]    // -1, 1, 3, 5, 0, 0, 0, 0, 0, 0
    //vst1.16 {d4}, [r1]    // -1, 1, 3, 5, 0, 0, 0, 0, 0, 0
    //vst1.8 {d4}, [r1]    // -1, 1, 3, 5, 0, 0, 0, 0, 0, 0
    //以上,均可以將d寄存器裏的所有數據存出去。與具體的數據類型無關。
    
    //以下,希望將d[0]或d[1]的32bit數據存出,但是實際y
    //vst1.16 {d4[0]}, [r1]    // -1, 0, 0, 0, 0, 0, 0, 0, 0, 0
    //vst1.16 {d4[1]}, [r1]    // 1, 0, 0, 0, 0, 0, 0, 0, 0, 0
    //vst1.32 {d4[0]}, [r1]    // -1, 1, 0, 0, 0, 0, 0, 0, 0, 0
    //vst1.32 {d4[1]}, [r1]    // 3, 5, 0, 0, 0, 0, 0, 0, 0, 0
    //vst1.8 {d4[0]}, [r1]    // 255, 0, 0, 0, 0, 0, 0, 0, 0, 0
    //vst1.8 {d4[1]}, [r1]    // 255, 0, 0, 0, 0, 0, 0, 0, 0, 0
    //vst1.32 {d6[0]}, [r1] // 3, 3, 0, 0, 0, 0, 0, 0, 0, 0
    vst1.16 {d6[0]}, [r1] // 3, 0, 0, 0, 0, 0, 0, 0, 0, 0
    bx lr
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章