avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[avr-gcc-list] RE: AVR GCC R0 and asm


From: Stu Bell
Subject: [avr-gcc-list] RE: AVR GCC R0 and asm
Date: Fri, 8 Feb 2008 08:53:47 -0700

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: address@hidden
[mailto:address@hidden On Behalf Of
Craig D Stewart
Sent: Thursday, February 07, 2008 5:20 PM
To: address@hidden
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   





reply via email to

[Prev in Thread] Current Thread [Next in Thread]