Subject: question on inline assembly and long long values

From: Chris Friesen <[email-masked]>
Date: Wed, 06 Apr 2005 12:26:07 -0600

I want to retrieve the msr (which is 64-bits) on a 970 when running in 
32-bit mode.  I have the following bit of code that seems to work, but 
when looking at the code it always seems to use a suboptimal register 
for the low word, and then it ends up having to copy it to the right 
register to create a long long register pair.

static inline unsigned long long get_msr()
{
	union {
		struct {
			unsigned long low;
			unsigned long high;
		} words;
		unsigned long long val;
	} val;
         asm volatile( \
                 "mfmsr  %0               \n\t" \
                 "rldicl %1,%0,32,32       \n\t" \
                 "rldicl %0,%0,0,32        \n\t" \
                 : "=r" (val.words.low), "=r" (val.words.high));
	return val.val;
}

Using this code, the optimised assembly output of

	unsigned long long a = asdf();
	unsigned long long b = asdf();

is

	mfmsr  5
	rldicl 0,5,32,32
	rldicl 5,5,0,32
	mr 6,0
	mfmsr  7
	rldicl 9,7,32,32
	rldicl 7,7,0,32
	mr 8,9

I figure it should have been able to use registers 6/8 in the first 
place, and save the extra moves.

Is there any way to help gcc optimise this?

Chris