Here's the scoop: C uses R0 as a "scratch" register and never assumes a value for it unless it is under its explicit control. It certainly will not use it to save something across an asm statemnt. Messing with R0 is probably a don't-care.
R1 is different -- C assumes that R1 is *always* 0. If you mess with r1 in an asm statement, you must *always* return it back to 0 before exiting the asm. AFAIK, the "clobber" section of the asm statement does not cause C to emit a push/pop pair, but instead warns the code generator not to use those registers for storage across the asm statement. While R0 is not a problem, R1 will cause issues because of C's "R1 is always 0" assumption. That's my quick answer -- I'm sure that those with far more experience than I will correct me. Best regards, Stu Bell DataPlay (DPHI, Inc.) -----Original Message----- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Craig D Stewart Sent: Thursday, February 07, 2008 5:20 PM To: [email protected] Subject: AVR GCC R0 and asm Hi, Im trying to use FMUL to give an approximation of floating point multiply for gain control for a lo-fi DSP. So if value = 120 and amplitude/gain = 0.5 ( or 64 if treated as a uchar) then result would be the predictable 60. Unfortunately the FMUL instruction dumps the result in r0 and r1. My understanding was that as long as i include R0 and R1 in my used registers at the end of my inline assembler thent he complier would deal with pushing the values of the registers on to the stack before the asm and returning the values after the asm. However the r0 is not getting reset. The following code demonstrates the problem with ampcounter and valuecounter being set to what ever is left in ro.. and not 0... #include <avr/io.h> #include <avr/interrupt.h> unsigned char tasm(unsigned char value, unsigned char amp) { unsigned char result=0; asm volatile ( "fmul %1,%2" "\n\t" "mov %0,r1" :"=&r" (result) :"a" (value),"a" (amp) :"r0", "r1" ); return result; } volatile unsigned char address[4] = {1,2,3,4}; volatile unsigned char values[10] = {10,20,30,40,80,120,140,160,180,200}; volatile unsigned char amplitude[4] = {32,64,96,128}; unsigned char temp = 0; unsigned char tamp = 0; unsigned char tvalue = 0; unsigned char result = 0; unsigned char ampcounter = 0; unsigned char valuecounter = 0; int main(void) { for(;;) { tvalue = values[valuecounter]; tamp = amplitude[ampcounter]; temp = tasm(tvalue,tamp); valuecounter++; ampcounter++; if (valuecounter >9) { valuecounter = 0; } if (ampcounter >3) { ampcounter = 0; } } } Of course i can just set R0 to be zero after my asm instructions, but surely this is a minor issue that should be 'fixed' ?? or im i misunderstanding something here? Thanks Craig _______________________________________________ AVR-GCC-list mailing list [email protected] http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
