avr-gcc ABI: return 8-bit value from function

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

avr-gcc ABI: return 8-bit value from function

Benoit Steinmetz
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.

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

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



_______________________________________________
AVR-GCC-list mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Reply | Threaded
Open this post in threaded view
|

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

Erik Christiansen-2
Reply-To: [hidden email]

On 04.06.18 19:19, Benoit Steinmetz wrote:
>
> p.s:  I have recently started a topic on avrfreaks about this issue [2].

Your link has caused me to visit avrfreaks for the second time in a
decade, leading me to wonder if answers would appear here. Normally I'd
point to the useful software admonition "Be conservative in what you
output, and liberal in tolerance of input.", but I see that your target
is an ATtiny2313. With only 1K instructions available, I'm surprised
to see any 'C' used at all, and understand the desire to trim every
superfluous instruction.

One question: Does the omission of sign extension by avr-gcc remain
without optimisation for size?

My current project, also on an ATtiny2313, is 100% assembler -
simplified event scheduler, state machines, HAL, the lot. But at least
you could fall back to an ATtiny4313 if the 'C' blows out, I guess.

Erik


_______________________________________________
AVR-GCC-list mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Reply | Threaded
Open this post in threaded view
|

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

Bruce D. Lightner
Benoit,

See "C WITHOUT RAM" section of this 2006 article named "Tiny AVR Serial Port Programmer".

   http://www.lightner.net/avr/2605018Lightner.pdf

...and this Webpage...

   http://www.lightner.net/avr/ATtinyAvrGcc.html

Compiling C-code for an AVR like the ATtiny2313 with few resources---and zero SRAM---is indeed practical.

But today STMicro sells tiny 32-bit STM32 ARM microcontroller chips (e.g., STM32L021D4P7, 5mm x 6mm TSSOP-14) with plenty of program flash and SRAM for under $1 US.  STM even claims "32-bits for 32-cents" in large volumes for their ARM Cortex chips.

   https://www.electronicspecifier.com/micros/stm32f030-stm32-stmicroelectronics-value-line-microcontrollers-32-bits-for-32-cents

Best regards,

Bruce


On 6/4/2018 7:35 PM, Erik Christiansen wrote:
Reply-To: [hidden email]

On 04.06.18 19:19, Benoit Steinmetz wrote:
p.s:  I have recently started a topic on avrfreaks about this issue [2].
Your link has caused me to visit avrfreaks for the second time in a
decade, leading me to wonder if answers would appear here. Normally I'd
point to the useful software admonition "Be conservative in what you
output, and liberal in tolerance of input.", but I see that your target
is an ATtiny2313. With only 1K instructions available, I'm surprised
to see any 'C' used at all, and understand the desire to trim every
superfluous instruction.

One question: Does the omission of sign extension by avr-gcc remain
without optimisation for size?

My current project, also on an ATtiny2313, is 100% assembler -
simplified event scheduler, state machines, HAL, the lot. But at least
you could fall back to an ATtiny4313 if the 'C' blows out, I guess.

Erik


_______________________________________________
AVR-GCC-list mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list



--
Bruce D. Lightner
Lightner Engineering
8551 La Jolla Shores Drive
La Jolla, California 92037-3044
Mobile/SMS: +1-858-228-7579
Voice: +1-858-551-0770 ext. 2
Email: [hidden email]
URL: http://www.lightner.net/lightner/bruce/

CONFIDENTIALITY NOTICE: This e-mail and any attachments may contain confidential information intended solely for the use of the addressee. If the reader of this message is not the intended recipient, any distribution, copying, or use of this e-mail or its attachments is prohibited. If you received this message in error, please notify the sender immediately by e-mail and delete this message and any copies. Thank you.

_______________________________________________
AVR-GCC-list mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Reply | Threaded
Open this post in threaded view
|

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

Benoit Steinmetz
In reply to this post by Erik Christiansen-2
> One question: Does the omission of sign extension by avr-gcc remain
> without optimisation for size?

Thank you for your suggestion, I did not think of that.

When I compile without any optimization at all, the sign extension
by the called function is also missing, like with optimizations
enabled.

A user on avrfreaks suggested that the paragraph in the AVR-Libc FAQ
that causes the confusion might simply be mixing up "called function"
and "calling function".


is:  Return values: 8-bit in r24 (not r25!), ... 8-bit return values
are zero/sign-extended to 16 bits by the  *called*  function

(which is actually contradicting itself, as mentioned by another user)


should be:  Return values: 8-bit in r24 (not r25!), ... 8-bit return
values are zero/sign-extended to 16 bits by the  *calling*  function


Also, the avr-gcc ABI page states that 8-bit values are returned in
r24 and does not say anything about 8-bit return values being extended
to 16 bits by the called function.  [1]

So I think that the "called" vs "calling" mixup might actually be the
answer to my question.


Benoit

[1]  https://gcc.gnu.org/wiki/avr-gcc#Calling_Convention



_______________________________________________
AVR-GCC-list mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Reply | Threaded
Open this post in threaded view
|

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

Georg-Johann Lay-2
In reply to this post by Benoit Steinmetz
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


_______________________________________________
AVR-GCC-list mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list