[wellylug] asm stylings?

Rob Giltrap rob at kiwihq.com
Sun Feb 18 22:36:07 NZDT 2007


Daniel Pittman wrote:
> Rob Giltrap <rob at kiwihq.com> writes:
>   
>> Daniel Pittman wrote:
>>     
>>> #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.
>   
>
If this piece of code is multiplying a 64bit number * 32bit number then 
does one of the registers have to be 64 bit e.g movl %eax becomes movq %rax?




More information about the wellylug mailing list