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

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

Re: [avr-gcc-list] avr-gcc ABI: return 8-bit value from function


From: Georg-Johann Lay
Subject: Re: [avr-gcc-list] avr-gcc ABI: return 8-bit value from function
Date: Sat, 23 Jun 2018 10:23:34 +0200
User-agent: Thunderbird 2.0.0.24 (Windows/20100228)

Benoit Steinmetz schrieb:
hi all

I have written a function in AVR assembler that returns an 8-bit result. The
function is called from C, so it should respect the avr-gcc ABI.

I am a bit confused as to whether the function is required to zero/sign-extend the 8-bit result to 16 bits or not.

Yes.

The AVR-Libc FAQ mentions that "8-bit return values are zero/sign-extended to
16 bits by the called function" [1]

Older versions of avr-gcc extended to 16 bits even though the ABI didn't impost that. For example avr-gcc v3.4.6 (e.g. WinAVR-20060421) emits code that extends to 16 bits. As this is sub-optimal and the compiler itself didn't exploit this, newer versions of the compiler no more extend to 16 bits.

In any case, assuming that [u]int8_t will be returned as [unsigned] 8-bit value will work, both with the old versions and the new ones, both for assembly and C or any mixture thereof.

Johann

But on the other hand the code generated by avr-gcc (4.9.2) on my machine does
not extend 8-bit results to 16 bits.

example:
~~~
int8_t signed8(void)
{
    return -1;
}
~~~

generated:
~~~
00000034 <signed8>:
  34:   8f ef           ldi     r24, 0xFF       ; 255
  36:   08 95           ret
~~~


I would have expected:
~~~
00000034 <signed8>:
  34:   8f ef           ldi     r24, 0xFF       ; 255
  36:   9f ef           ldi     r25, 0xFF       ; 255
  38:   08 95           ret
~~~


Also a function using the returned result (cast to int16_t) does not rely on
the called function to already have sign-extended its result; it rather
performs the sign extension itself:

~~~
#include <stdint.h>

int8_t signed8(void);
void write16(int16_t val);

int main(void)
{
    write16(signed8());
    return 0;
}
~~~


generated:
~~~
0000003c <main>:
  3c:   fb df           rcall   .-10            ; 0x34 <signed8>
  3e:   08 2e           mov     r0, r24
  40:   00 0c           add     r0, r0
  42:   99 0b           sbc     r25, r25
  44:   f9 df           rcall   .-14            ; 0x38 <write16>
  46:   80 e0           ldi     r24, 0x00       ; 0
  48:   90 e0           ldi     r25, 0x00       ; 0
  4a:   08 95           ret
~~~


I am using avr-gcc 4.9.2 (shipped with Debian 9.4). Has the ABI changed since the last update of the AVR-Libc FAQ (Tue Aug 12 2014), and called functions no
longer need to extend 8-bit results to 16 bits?

best regards

Benoit.

p.s:  I have recently started a topic on avrfreaks about this issue [2].

[1] https://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_reg_usage
[2] https://www.avrfreaks.net/forum/avr-gcc-abi-return-8-bit-value-function




reply via email to

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