Difference between revisions of "Z80 Routines:Optimized:PopCountA"

From WikiTI
Jump to: navigation, search
Line 7: Line 7:
 
;output: a
 
;output: a
 
;destroys: f, c
 
;destroys: f, c
;27 bytes, 108 clock cycles
+
;26 bytes, 104 clock cycles
 
TypicalPopCountA:
 
TypicalPopCountA:
 
xor a
 
xor a

Revision as of 19:37, 15 September 2020

This is a faster/smaller (and also obfuscated) replacement for the normal popcount a, which returns the number of set bits in a.

Typical routine:

;input: b
;output: a
;destroys: f, c
;26 bytes, 104 clock cycles
TypicalPopCountA:
	xor	a
	ld	c, a
	rrc	b
	adc	a, c
	rrc	b
	adc	a, c
	rrc	b
	adc	a, c
	rrc	b
	adc	a, c
	rrc	b
	adc	a, c
	rrc	b
	adc	a, c
	rrc	b
	adc	a, c
	rrc	b
	adc	a, c

Better routine:

;- Pop Count A
;input:	byte in a
;output: number of set bits in a
;destroys f, bc
;22 bytes and 85 clock cycles
;author: jacobly
PopCountA:
	ld	c, a			; c=(A|B|C|D|E|F|G|H)
	and	10101010b		; a=(A|0|C|0|E|0|G|0)
	cpl				; a=(~A|1|~C|1|~E|1|~G|1)
	rrca				; a=(1|~A|1|~C|1|~E|1|~G), cf=1
	adc	a, c			; a=(A+B|C+D|E+F|G+H)
	ld	b, a			; b=(A+B|C+D|E+F|G+H)
	and	00110011b		; a=(00|C+D|00|G+H)
	ld	c, a			; c=(00|C+D|00|G+H)
	xor	b			; a=(A+B|00|E+F|00)
	rrca \ rrca			; a=(0|A+B|00|E+F|0)
	add	a, c			; a=(A+B+C+D|E+F+G+H)
	ld	c, a			; c=(A+B+C+D|E+F+G+H)
	rrca \ rrca \ rrca \ rrca	; a=(E+F+G+H|A+B+C+D)
	add	a, c			; a=(A+B+C+D+E+F+G+H|A+B+C+D+E+F+G+H)
	and	00001111b		; a=A+B+C+D+E+F+G+H