can't get the right code

Go To Last Post
9 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

#if WHATEVER
static inline void rd_data ( void ) {
return ( PIND & 2 );
}
#else
#define rd_data() ( PIND & 2 )
#endif
/************************/
char somefunc ( void ){
register char i;

i = rd_data();
PORTD &= ~1;
return !i;
}

ATMega128. Optimization level MUST be 2! Regular function call works, but I want inline or macro(speed is an issue).
I'm straggling to get right code. Any help appreciated.
Thanks.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Don't use inline, use a macro.

That's certainly a bug in avr-gcc (I hope your inquiry on the avr-gcc
list will prompt one of the compiler developers to eventually
respond), but if you need something right now, the macro approach
seems the best to me.

Both versions generate the correct code for me (OK, after fixing the
obvious error in your inline function that it must return `unsigned
char' instead of `void'), but the macro version is the optimal code,
because function return values are always expanded to 16 bits (that's
a documented feature).

Here's the code I'm getting for the macro version

    .text
.global somefunc
    .type somefunc, @function
somefunc:
    in r24,48-0x20
    cbi 50-0x20,0
    ldi r18,lo8(0)
    ldi r19,hi8(0)
    sbrs r24,1
    ldi r18,lo8(1) ; reg_was_0
.L2:
    movw r24,r18
    ret

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Joerg,
look at line return !i or try i = !rd_data();

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

return type clash
use prototypes !
it is erroneous to have a "return" statement in the body
if the declaration is ".... void ..."
(although a pointer to void as a return value is legit)

admin's test signature
 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mr. noname!

Let me in my turn give you an advice:
Try to read what has been written above and think about it!
void is just obvious mistype! I put this code as an example otherwise you could mention that I didn't describe somewhat() function or had I defined WHATEVER or not... The point of the question was how to fight with compiler because all my attempts to get the code I'd like to see have failed.
PS. I can make some errors in my broken English too but it really doesn't matter on compiled code, does it?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

brb (how do you pronounce that btw.? ;-),

what's wrong with the code?

If your PIND.2 bit was set, the SBRS instruction skips the next LDI,
so a 0 will be returned in r24. If PIND.2 was clear, the SBRS will be
executed, and a 1 will be returned.

The only silly thing is the assignment to r19. OTOH, it might be
considered a bug that r19 is not moved to r25, since functions
returning 8-bit entities are supposed to extend them to 16 bits.
However, since the caller wouldn't care, it's not really a bug (but
perhaps really worth discussing with Marek and Denis).

admin's test signature
 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorry for `noname', forgot to log in first.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Joerg,

brb is compound of first two consonant letters of my first and last name at the same time(br-rb or brb). I'm using this acronym as login for over 20 years and used to it :-)

Second question is much harder to answer. I tried tens of variants of code so I can't answer exactly what is wrong each time is different. The project I'm working on requires me to run very-very fast in other words to write on C and get assembly code (inline asm is strictly restricted but still allowed). From other hand code size is absolutely doesn't matter. That is a reason of using macro or even better inline functions. In some my tries compiler did produce simple wrong code at all. When I'll nave a break I can return to it and send you exact example.
As of it stands right now I have to use:
000001c2 :
asm volatile ("ldi r24, 1;");
1c2: 81 e0 ldi r24, 0x01 ; 1
asm volatile ("sbic 0x10,1;");
1c4: 81 99 sbic 0x10, 1 ; 16
asm volatile ("ldi r24, 0;");
1c6: 80 e0 ldi r24, 0x00 ; 0
}
1c8: 08 95 ret

000001ca :
static bool rd_data1 ( void ) {
asm volatile ("ldi r24, 0;");
1ca: 80 e0 ldi r24, 0x00 ; 0
asm volatile ("sbic 0x10,1;");
1cc: 81 99 sbic 0x10, 1 ; 16
asm volatile ("ldi r24, 1;");
1ce: 81 e0 ldi r24, 0x01 ; 1
}
1d0: 08 95 ret

because it is fastest code I could get even with expenses on call and ret.
I'd still like to implement this as inline functions.

PS. Does avr-gcc has bool (boolean) type?
My bool is
typedef enum { FALSE = 0, TRUE } bool;

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Eric,

What is type _Bool?
if it is #define Bool int that is not what I want.
I figured out that avr-gcc does not generate warnings when it sees custom type mismatch, but I'm positive some day it will. That is why I like my bool more.