Вопрос

How can I access only a specific part (byte) of a 128bit xmm register? I have to loop (bytewise) over the whole space, compare byte after byte and copy it on well defined conditions*.

Therefore I have to compare every byte of this 16-byte register with \0 and (maybe) overwrite it.

xor %ecx, %ecx #var i

copy:
    cmp $0, <i-th byte of xmm1>
    je end
    mov <byte i of xmm1>, <byte i of xmm2>
    inc %ecx
    jmp copy
end:
# ...

How to access the i-th byte of xmm registers?

My solution has to use as less operations as possible (only the number of ops count, not the number of their clock cycles!), so I will not use sub-functions like strlen etc.

*) I have to move all bytes, unit the the first \0 occurrence within b, from register a to register b.

Это было полезно?

Решение

Technically you can access bytes using PEXTRB but that's not recommended for this task. I would do a SIMD compare using PCMPEQB then PMOVMSKB to get the result mask, then look up the first set bit using BSF then create a blend mask from that. Avoid looping, use parallelism.


Update: based on rwong's comment here is a possible implementation using pcmpistrm:

3       movdqu input, %xmm1
(gdb) si
4       movdqu replace, %xmm2
(gdb)
5       movdqa %xmm1, %xmm0
(gdb)
6       pcmpistrm $0x78, %xmm1, %xmm1
(gdb) p/s $xmm1.v16_int8
$1 = "input\000----------"
(gdb) p/s $xmm2.v16_int8
$2 = "replacereplacere"
(gdb) si
7       pblendvb %xmm1, %xmm2
(gdb) si
8       ret
(gdb) p/s $xmm2.v16_int8
$3 = "repla\000----------"
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top