popcount: move $v0, $zero move $t0, $zero b test bod: andiu $t1, $a0, 1 bnez $t1, nope addiu $v0, $v0, 1 nope: addiu $t0, $t0, 1 blt $t0, 32, bod jr $ra
popcount: move $v0, $zero move $t0, $zero b test bod: andiu $t1, $a0, 1 addiu $v0, $v0, $t1 nope: addiu $t0, $t0, 1 blt $t0, 32, bod jr $ra
popcount: move $v0, $zero and $t1, $a0, 1 # block repeated 32 times srl $a0, $a0, 1 # this omitted in last rep add $v0, $v0, $t1 jr $ra
.data tbl: .word 0x55555555 .word 0x33333333 .word 0x0f0f0f0f .word 0x00ff00ff .word 0x0000ffff .text popcount: la $t0, tbl lw $t1, 0($t0) srl $v0, $a0, 1 and $v0, $v0, $t1 and $a0, $a0, $t1 add $v0, $v0, $a0 lw $t1, 4($t0) srl $v1, $v0, 2 and $v1, $v1, $t1 and $v0, $v0, $t1 add $v0, $v0, $v1 lw $t1, 8($t0) srl $v1, $v0, 4 and $v1, $v1, $t1 and $v0, $v0, $t1 add $v0, $v0, $v1 lw $t1, 12($t0) srl $v1, $v0, 8 and $v1, $v1, $t1 and $v0, $v0, $t1 add $v0, $v0, $v1 lw $t1, 16($t0) srl $v1, $v0, 16 and $v1, $v1, $t1 and $v0, $v0, $t1 add $v0, $v0, $v1 jr $ra
/* does not distinguish between x = 2^31 and x = 0 */ return tbl[(x ^ (x-1)) % 37]; /* mod 37 is a perfect hash */
/* 12345678901 12345678901 */ n = n - ((n >> 1) & 033333333333) - ((n >> 2) & 011111111111); /* 4a+2b+c - 2a+b - a = a+b+c, groups of 3 bits */ return ((n + (n >> 3)) & 030707070707) % 63;This mathematical trick makes use of the fact that 64 mod 63 is 1. Can you see what's going on?
Like many of the mathematical hacks that use integer division or remaindering, the expression is actually rather expensive to evaluatione on most of the early MIPS processors. On other processors that have faster hardware integer units, this operation might be competitive with the others shown above.
bsy+www@cs.ucsd.edu, last updated