我正在使用内联汇编移植一些我写给NEON的代码。
我需要的一件事是将范围[0..128]的字节值转换为表格中的其他字节值,这些字节值占据整个范围[0..255]
表格很简短,但这背后的数学并不容易,所以我认为每次运动都不值得计算#34;所以我想试试Look Up表。
我已经将VTBL用于32字节的情况,并按预期工作
对于整个范围,一个想法是首先比较源的范围并进行不同的查找(即,具有4个32位查找表)。
我的问题是:有没有更有效的方法呢?
修改的
经过一些试验,我已经完成了四次查找并且(仍未安排)我对结果感到满意。我在这里留下了内联汇编中的一段代码行,以防有人发现它有用或者认为它可以改进。
// Have the original data in d0
// d1 holds #32 value
// d6,d7,d8,d9 has the images for the values [0..31]
//First we look for the 0..31 images. The values out of range will be 0
"vtbl.u8 d2,{d6,d7,d8,d9},d0 \n\t"
// Now we sub #32 to d1 and find the images for [32...63], which have been previously loaded in d10,d11,d12,d13
"vsub.u8 d0,d0,d1\n\t"
"vtbl.u8 d3,{d10,d11,d12,d13},d1 \n\t"
// Do the same and calculating images for [64..95]
"vsub.u8 d0,d0,d1\n\t"
"vtbl.u8 d4,{d14,d15,d16,d17},d0 \n\t"
// Last step: images for [96..127]
"vsub.u8 d0,d0,d1\n\t"
"vtbl.u8 d5,{d18,d19,d20,d21},d0 \n\t"
// Now we add all. No need to saturate, since only one will be different than zero each time
"vadd.u8 d2,d2,d3\n\t"
"vadd.u8 d4,d4,d5\n\t"
"vadd.u8 d2,d2,d4\n\t" // Leave the result in d2
答案 0 :(得分:1)
正确的顺序是通过
vtbl d0, { d2,d3,d4,d5 }, d1 // first value
vsub d1, d1, d31 // decrement index
vtbx d0, { d6,d7,d8,d9 }, d1 // all the subsequent values
vsub d1, d1, d31 // decrement index
vtbx d0, { q5,q6 }, d1 // q5 = d10,d11
vsub d1, d1, d31
vtbx d0, { q7,q8 }, d1
vtbl 和 vtbx 之间的区别在于 vtbl
将元素 d0 归零,当 d1 >= 32 时,vtbx 将 d0 中的原始值保持不变。因此不需要像我的评论中那样的诡计,也不需要合并部分值。