[wellylug] asm stylings?

Daniel Pittman daniel at rimspace.net
Sun Feb 18 18:28:08 NZDT 2007


Rob Giltrap <rob at kiwihq.com> writes:
> Daniel Pittman wrote:
>> Rob Giltrap <rob at kiwihq.com> writes:
>>
>>
>>> Anyone on the list familiar with C code including GCC asm code?
>>>
>>> I got a small bit of asm code I don't understand and need to convert
>>> over to something readable by SunStudio C compiler.
>>>
>>> If anyone can lend their knowledge I would greatly appreciate it.
>>>
>>
>> I am far from expert at GCC inline assembler and know zero about the
>> SunStudio version, but I can probably help you understand what the
>> snippet is doing -- which means you only need write the Sun part.
>>
>> Post it here and we will see what we can do.
>>
>>      Daniel
>>
> Okay here goes. First the example...
>
>> #define __MULH64(__x, __y)    \
>>       	({ uint64 __lo, __hi;        \
>> 	__asm__("mulq %3"
>> 		: "=a" (__lo), "=d" (__hi) 	/* output */
>> 		: "%0" (__x), "rm" (__y)	/* input */)
>> 		; __hi; /* return value*/
>> 		})
>>
>> So what we want is a function that multiplies two 64
>> bit values together and returns the upper 64 bit value.
>>
>> The asm becomes an inline for SunStudio as follows:
>>
>>         .inline __MULH64, 8
>>         movq %rdi,%rax
>>         mulq %rsi
>>         movl %edx,%eax
>>         .end
> So now what I need is to decipher the next three lines...
>
> #define MUL64x32(  __x,__y,__lo,__hi)    asm("mulq %3" : "=a" (__lo),
> "=d" (__hi) : "%0" (__x), "rm" (__y) );

I presume you know what mulq means.

The outputs are:

  __lo, stored from the eax register.
  __hi, stored from the edx register.

The inputs are:

  __x, loaded into the eax register.
  __y, as the argument to the mulq operation, which in a "register or
       memory" value and appropriately referenced by gcc.

The '%3' in the instruction part is the fourth input or output argument;
they are:

  %0 -> __lo,  %1 -> __hi,  %2 -> __x,  %3 -> __y

The generated code, by the way, will look something like this:
        
	movl	-20(%ebp), %eax ; __x -> eax
#APP
	mulq -16(%ebp)          ; __y -> mulq arg
#NO_APP
	movl	%eax, -12(%ebp) ; eax -> __lo
	movl	%edx, -8(%ebp)  ; edx -> __hi


Anyway, the key parts are: the outputs specify a constraint on where
they can be placed.  =a is "write eax", =d "write edx".

The %0 is a reference; you can omit the '%' happily -- and the document
you linked to does.

The 'rm' is a fairly liberal constraint: it must be a value in a
register or in memory.  Not really much constrained. ;)

The general 'r' constraint is "any register", not that it is used alone
here.  


Anyway, no additional clobbers are required here because only the
referenced registers are touched by the process.  As I understand.

> #define MUL_LOHI64(__x,__y,__lo,__hi)    asm("mulq %3" : "=a" (__lo),
> "=d" (__hi) : "%0" (__x), "rm" (__y) );

That is exactly the same as the previous macro. :)

> #define SQR_LOHI64(__x,    __lo,__hi)    asm("mulq %0" : "=a" (__lo),
> "=d" (__hi) : "0"  (__x) );

That is basically the same, save it multiplies __x by __x.  So, less
references to arguments but essentially the same effect. as if it called
one of the previous macros with '__x, __x, __lo, __hi' as arguments.


Does that clear up what is happening there?

Regards,
        Daniel
-- 
Digital Infrastructure Solutions -- making IT simple, stable and secure
Phone: 0401 155 707        email: contact at digital-infrastructure.com.au
                 http://digital-infrastructure.com.au/




More information about the wellylug mailing list