>> 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