ARM Neon: store the nth position (s) of non-zero byte (s) in an 8-byte vector strip

I want to convert a neon 64-bit vector strip to get the nth position (s) of non-zero (aka. 0xFF) 8-bit value (s), and then fill in the rest of the vector zeros. Here are some examples:

    0  1  2  3  4  5  6  7

d0: 00 FF 00 FF 00 00 00 FF
d1: 1  3  7  0  0  0  0  0

d0: 00 FF FF FF 00 00 FF 00
d1: 1  2  3  6  0  0  0  0

d0: FF FF FF FF FF FF FF FF
d1: 0  1  2  3  4  5  6  7

d0: FF 00 00 00 00 00 00 00
d1: 0  0  0  0  0  0  0  0

d0: 00 00 00 00 00 00 00 00
d1: 0  0  0  0  0  0  0  0

I have the feeling that this is probably one or two Neon bit-shifted instructions with another “good” vector. How can i do this?

+1
source share
2 answers

It turns out to be far from simple.

( 0 1 2 3 4 5 6 7 vand ). , - , , - - . , , vtbl ( vtbx, ). vtbl , , . , , , ; .

, , , , SIMD. NEON - SIMD, , - , //, .

, NEON, - , ; " - NEON-", , - . , , , ():

// d0 contains input vector
vmov.u8 d1, #0
vmov.u8 d2, #0
vmvn.u8 d3, #0
vdup.u8 d4, d0[0]
vext.u8 d5, d2, d3, #7
vbit.u8 d3, d5, d4
vsub.u8 d1, d1, d3
vdup.u8 d4, d0[1]
vext.u8 d5, d2, d3, #7
vbit.u8 d3, d5, d4
vsub.u8 d1, d1, d3
vdup.u8 d4, d0[2]
vext.u8 d5, d2, d3, #7
vbit.u8 d3, d5, d4
vsub.u8 d1, d1, d3
vdup.u8 d4, d0[3]
vext.u8 d5, d2, d3, #7
vbit.u8 d3, d5, d4
vsub.u8 d1, d1, d3
vdup.u8 d4, d0[4]
vext.u8 d5, d2, d3, #7
vbit.u8 d3, d5, d4
vsub.u8 d1, d1, d3
vdup.u8 d4, d0[5]
vext.u8 d5, d2, d3, #7
vbit.u8 d3, d5, d4
vsub.u8 d1, d1, d3
vdup.u8 d4, d0[6]
vext.u8 d5, d2, d3, #7
vbit.u8 d3, d5, d4
vsub.u8 d1, d1, d3
vdup.u8 d4, d0[7]
vext.u8 d5, d2, d3, #7
vbit.u8 d3, d5, d4
vbic.u8 d1, d1, d3
// d1 contains output vector

( d0 , d0[0]), , :

vmov.u8 d1, #0
vmov.u8 d2, #0
vmvn.u8 d3, #0
mov r0, #8
1:
vdup.u8 d4, d0[0]
vext.u8 d5, d2, d3, #7
vbit.u8 d3, d5, d4
subs r0, r0, #1
vext.u8 d0, d0, d0, #1
vsub.u8 d1, d1, d3
bne 1b
vbic.u8 d1, d1, d3

, , , .

+1

, . , , .

00/ff d0 0, 1, 2, ..., 7 d1, vorn.

vorn.u8 d0, d1, d0

d0 0xff, . , .

16 :

vmov.u8 d1, #255

/ :

vuzp.u8 d0, d1

vmin/vmax , , vmin/vmax , . :

vmin.u8 d2, d0, d1
vmax.u8 d3, d0, d1
vsri.u64 d2, d2, #8   ; stagger the even lanes (discards d0[0])
vmax.u8 d4, d2, d3    ; dst reg would be d0, but we want d0[0] back...
vmin.u8 d1, d2, d3
vsli.u64 d0, d4, #8   ; revert the stagger, and restore d0[0]

, ( ), - d0[7] d0[0] , , d0[0], d0[7], .

, :

vzip.u8 d0, d1

:

vmov.u8 d1, #0
vmax.s8 d0, d1

d0 .

Wikipedia , , - ( vmin/vmax), ( vsli vsri), , //vbubble, . NEON, , , , .

, 16 , , , q , 32 ... .

, , . .

+1

Source: https://habr.com/ru/post/1657690/


All Articles