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

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

Re: [avr-gcc-list] Efficient I/O handling w. bitfields codegen problem


From: E. Weddington
Subject: Re: [avr-gcc-list] Efficient I/O handling w. bitfields codegen problem
Date: Thu, 02 Dec 2004 17:29:01 -0700
User-agent: Mozilla Thunderbird 0.7.3 (Windows/20040803)

Albert Seward wrote:

On Thu, 2 Dec 2004, E. Weddington wrote:

Albert Seward wrote:

I have some problems with code generation from GCC 3.3. Read my question
in the main block.

/*
* bitfields.c
*
* GCC bitfields optimization test
*/
typedef union {
      unsigned char byte;
      struct {
              unsigned char pin0 : 1;
              unsigned char pin1 : 1;
              unsigned char pin2 : 1;
              unsigned char pin3 : 1;
              unsigned char pin4 : 1;
              unsigned char pin5 : 1;
              unsigned char pin6 : 1;
              unsigned char pin7 : 1;
      };
} volatile * const port_t;

port_t port[] = {(port_t)0x3d, (port_t)0x38, (port_t)0x35, (port_t)0x32};

// Another way...
struct  {
      port_t portA;
      port_t portB;
      port_t portC;
      port_t portD;
} ports = {(port_t)0x3d, (port_t)0x38, (port_t)0x35, (port_t)0x32};


int main(void) {
      /*  This works!
       *  It will give asm:
       *  cbi     0x18, 7
       */ sbi     0x18, 7
      port[1]->pin7 = 0;
      port[1]->pin7 = 1;

      /*  Why dont I get the same asm as above?
       *  Now I do get this:
       *
       *  lds     r30, 0x0068
       *  lds     r31, 0x0069
       *  ld      r24, Z
       *  andi    r24, 0x7F       ; 127
       *  st      Z, r24
       *
       *  lds     r30, 0x0068
       *  lds     r31, 0x0069
       *  ld      r24, Z
       *  ori     r24, 0x80       ; 128
       *  st      Z, r24
       *
       *  This is not as efficient, and it does not do the job
       *  if I for example want to change GIMSK this way.
       */
      ports.portA->pin7 = 0;
      ports.portA->pin7 = 1;

      for(;;)

      return 0;
}


Hope anyone has the time to help me. I am really stuck.



The canonical way to change bits in ports in C language is not through
the use of bitfields. You need to learn to use the C language's bitwise
operators, in conjunction with a simple macro include in avr-libc:

#include <avr/io.h>
PORTA |= _BV(1);   // Set bit 1
PORTA &= ~_BV(1);    // Clear bit 1

See this thread on the AVR Freaks website on how to use these operators:
<http://www.avrfreaks.net/phpBB2/viewtopic.php?t=8764&highlight=programming+101>
Go to the post that starts with "Programming 101", which should be
highlighted.


If I wanted to do it the "canonical way" would I have ask for it. But I
didn't, did I?

I do wonder how your brain work. I wish I would have taken a degree in
philosophy instead of my master degree in computer science.

But hey, thanks for the link. Here is a link so you can learn some
"Reading 101"
http://www.fisher-price.com/us/ms5/learn-to-read.asp

Enjoy.

Albert Seward
Uppsala University Sweden




Albert Seward also wrote earlier:

Hope anyone has the time to help me. I am really stuck.


Awww. Isn't it nice that you were so polite when asking for help. And now look how rude you are. How were we to know your educational level, when you didn't mention it before? ;-) For that matter you didn't mention how overly sensitive you were to (incorrectly) assumed condescension.

Since you have a Master's in CompSci, you should be able to figure it out from looking at the compiler sources.

And next time, keep your personal rants off the list.






reply via email to

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