> Ya, the example looks good to me.  In fact, I didn't know you could use
> useful labels for the asm vars, I have a few that all use A1 B2, etc.
> In my code, I just used straight C to convert from BCD to Bin (and vice
> versa), although, you're looks to be far more efficient.
> On the assembly for the dadd, seems like you are going to a bit of extra
> work, this too would work:
>    __asm__( "DADD.W  %A1, %A0  \n\t" : "=r" (bcd_a) : "r" (bcd_b) );

Actually, that won't work; you neglected to tell gcc that bcd_a is a
necessary *input* to the asm, so it might optimize away previous
instructions that set the value.  You need either

        asm("CLRC\n\tDADD.W %1,%0" : "+r" (bcd_a) : "r" (bcd_b) );
or
        asm("CLRC\n\tDADD.W %1,%0" : "=r" (bcd_a) : "r" (bcd_b), "0" (bcd_a));

(Earlier versions of gcc didn't support the "+" abbreviation and needed
the second form.)

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

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

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

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

Some gcc platforms require a final `: "cc"' clobber at the end, to
indicate that the condition codes are modified; other platforms assume
it.  I don't know which applies to mspgcc.

Reply via email to