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

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

Re: [avr-gcc-list] Checking carry flag and Rotate operation in C.


From: Wouter van Gulik
Subject: Re: [avr-gcc-list] Checking carry flag and Rotate operation in C.
Date: Tue, 17 Jun 2008 08:50:39 +0200
User-agent: Thunderbird 2.0.0.14 (Windows/20080421)

Jonathan Blanchard schreef:
Funny enough I was just debugging some error in my inline assembly
code. I was pretty amazed that GCC can actually transform ADC R0 R0 to
ROL R0.


In binary it is the same instruction. "ROL rx" does not "exist" it is just a short form for "ADC Rx, Rx" and
"LSL Rx" is just "ADD, Rx, Rx"
"CLR Rx" equals "XOR, Rx, Rx"
"SET Rx" is "LDI Rx, 0xFF" and
"TST Rx" is "AND Rx, Rx".
I once found a website with (almost) all duplicates, but I can't find it anymore

HTH

Wouter

Jonathan Blanchard
address@hidden


On Mon, Jun 16, 2008 at 9:18 PM, Andy H <address@hidden> wrote:
Internally gcc understands rotate.

So I looked up how gcc might expect rotate to be expressed.

It is
  unsigned char a;
  return (a>>cx) | (a<<cy);

- where the two constant cx, cy add up to size of mode (1+7=8 bits)

However, since we have not defined AVR instruction patterns to gcc for
rotate, it will produce code using shifts. I think this is worthy of a bug
report or at least a place on the TODO list.

Andy


Andy H wrote:
The simple answer us that you cant. Thougg we could do with this in
library and/or gcc patterns (builtin rotate)

This is close:


unsigned char foo(unsigned char b)
{
if (b & 128)
{
  b  <<= 1;
  b ^= 0b00011101;
}
else
{
  b<<=1;
}
return b;
}


unsigned char bar(unsigned char b)
{
if (b & 128)
{
  b ^= 0b0001110;
  b <<= 1;
  b |= 1;
}
else
{
  b<<=1;
}
return b;
}

Jonathan Blanchard wrote:
Hi,

I got two question about programming with AVR-GCC. Both are related to
finding a way to generate a specific output in assembler.

First, how do you create the rotate operation in C. Specifically how
can the ROL and ROR can be generated.

Secondly I have this piece of code where b is a 16 bit unsigned integer :

       b = b << 1;
       if( b & 256 )
           b = b ^ 0b100011101;

To optimize that I only need to check if b overflow at the left shift
operation by checking the carry flag. I'm trying to find a way to do
that in C. Right now I'm using the following piece of inline assembly
to do the trick :

       asm volatile(

                   "LSL %0     \n\t"
                   "BRCC 1f    \n\t"
                   "EOR %0, %1 \n\t"
               "1:""           \n\t"
                   :"+d" (b)
                   :"r"  (PPoly)

                 );

In this last piece of code b is a 8 bit unsigned integer and PPoly is
a 8 bit unsigned integer with the value 0b00011101. I'm just curious
to know if it's possible to achieve the same result only by using C.

Jonathan Blanchard


_______________________________________________
AVR-GCC-list mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


_______________________________________________
AVR-GCC-list mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


_______________________________________________
AVR-GCC-list mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list





reply via email to

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