All pastes #14201 Raw Edit

Unnamed

public text v1 · immutable
#14201 ·published 2005-06-13 00:31 UTC
rendered paste body
uint16 gcd(uint16 a, uint16 b)
{
	uint16 res;
	asm volatile (
		// Count trailing zeros of a
		"addi	r3,%1,-1\n"
		"andc	r3,r3,%1\n"
		"cntlzw	r3,r3\n"
		"subfic	r3,r3,32\n"
		// Count trailing zeros of b
		"addi	r4,%2,-1\n"
		"andc	r4,r4,%2\n"
		"cntlzw	r4,r4\n"
		"subfic	r4,r4,32\n"
		// Compute min(ctz(a),ctz(b))
		"subfc	%0,r4,r3\n"
		"subfe	%0,%0,%0\n"
		"andc	r4,r4,%0\n"
		"and	%0,r3,%0\n"
		"or		%0,r4,%0\n"
		// Remove trailing zeros from a and b
		"srw	%1,%1,%0\n"
		"srw	%2,%2,%0\n"
		// Main loop
		"loop%=:\n"
		"cmplw	%1,%2\n"
		"beq	end%=\n"
		// (a,b) = (min(a,b),|a-b|)
		"subfc	r3,%2,%1\n"
		"subfe	r4,r4,r4\n"
		"and	%1,%1,r4\n"
		"andc	%2,%2,r4\n"
		"or		%1,%1,%2\n"
		"xor	%2,r3,r4\n"
		"sub	%2,%2,r4\n"
		// Remove trailing zeros from b
		"addi	r4,%2,-1\n"
		"andc	r4,r4,%2\n"
		"cntlzw	r4,r4\n"
		"subfic	r4,r4,32\n"
		"srw	%2,%2,r4\n"
		"b		loop%=\n"
		// Done. Add factors of two removed at the beginning
		"end%=:\n"
		"slw	%0,%1,%0\n"
	: "=&r"(res), "+r"(a), "+r"(b)
	:
	: "r3", "r4"
	);

	return res;
}