ARM Thumb-2 (NEON), 6 bytes
Eat my Thumb, pclmullqlqdqdqdqdq
. ARM has boring builtins, too!
ef80 0e01 4770
Assembly code:
.syntax unified
.arch armv7-a
.fpu neon
.thumb
.globl xormul_boring_neon
.thumb_func
xormul_boring_neon:
// q0[0-8] = d0[0-8] @ d1[0-8]
vmull.p8 q0, d0, d1
bx lr
Multiplies the packed 8-bit values in d0
and d1
with each other and returns each 16-bit product in q0
.
ARM Thumb-2, manual, 14 bytes
Ok, to make up for it, here is a fully scalar version which does a 32x32 multiply with a 32-bit result.
2300 0849 bf28 4043 0040 d1fa 4770
.syntax unified
.arch armv6t2
.thumb
.globl xormul_scalar
.thumb_func
// r3 <- r0 @ r1
xormul_scalar:
// acc <- 0
movs r3, #0
.Lloop:
// test each bit in y by using lsrs carry-out
lsrs r1, r1, #1
// was the bit set?
it cs
// if so, acc ^= x
eorcs r3, r0
// shift x left
lsls r0, r0, #1
// loop while x is non zero
bne .Lloop
.Lend:
// return in r3
bx lr
Equivalent C code:
uint32_t xormul_scalar(uint32_t x, uint32_t y)
{
uint32_t acc = 0;
do {
if (y & 1)
acc ^= x;
y >>= 1;
} while ((x <<= 1));
return acc;
}
Yet another case of lsls
and lsrs
being far too useful than they deserve to be.
I will try to upload it to Travis later tonight.