>> Note that you don't need the "A" modifier unless you're accessing part
>> of a multi-word operand.  You would use it for a 32-bit add:
>> 
>>      asm("CLRC\n\tDADD.W %A1,%A0\n\tDADD.W %B1,%B0" : "=r" (bcd_a) : "r" 
>> (bcd_b), "0" (bcd_a));
>> 
> True, but harmless.

Agreed, but it is clutter that someone has to parse and understand
before realizing it's harmless.

>> You can also let it use the full range of possible addressing modes:
>>      asm("CLRC\n\tDADD.W %1,%0" : "+ro" (bcd_a) : "g" (bcd_b) );
>> 
> Yeah, but I'm not sure that makes any difference in this case. Does it?
> 
>> Amd, further, let it know that the operation is commutative:
>> 
>>      asm("CLRC\n\tDADD.W %1,%0" : "=ro" (bcd_a) : "%g" (bcd_b), "0" (bcd_a));
>> 
> Now I don't follow you. The dadd instruction is certainly not 
> commutative. Since that is all you have here, how would the overall 
> operation be commutative when the final answer is still constrained to 
> be in bcd_a?

The two *inputs* are commutative, which is why I need to use the
3-operand form.  x = y + z is the same as x = z + y.  Which can be
expressed to gcc as:

        asm("CLRC\n\tDADD %1,%0" : "=ro" (x) : "%g" (y), "0" (z));

> Now if I defined a third variable, say bcd_c, and made that the output 
> of the assembly code, and then returned that from the original full bcd 
> addition static inline function, I see how that would become 
> communtative. Right now, I don't follow you.

I think I see the confusion... You're saying that "dadd x,y" is
obviously not the same as "dadd y,x", since they differ in which
operand gets written to.

What I meant, however, and what GCC understands, is that the *inputs*
are commutative.  By telling it that, it can choose which to copy to the
output.  So GCC might compile

        asm("CLRC\n\tDADD %1,%0" : "=ro" (x) : "%g" (y), "0" (z));

as either:

        mov z,x
        CLRC
        DADD y,x

or:

        mov y,x
        CLRC
        DADD z,x

>> And, I suppose, for completeness' sake, tell gcc that a memory
>> destination is slow and to be avoided if possible:
>> 
>>      asm("CLRC\n\tDADD.W %1,%0" : "=r,o?" (bcd_a) : "%g,g" (bcd_b), "0,0" 
>> (bcd_a));
>> 
> Does this actually do anything?  The compiler is free to choose 
> addressing modes, so surely it just grabs from and stuffs to whereever 
> fits best.

Well, the ? just says that a memory destination is "discouraged", and
is about as bad as adding a single extra instruction.

This is really a minor optimization point, but without it, gcc might
generate something stupid like:

        dadd r15,memory
        mov memory,r14

rather than

        mov memory,r14
        dadd r15,r14

Reply via email to