Forum: Compiler & IDEs === GCC v15 ===


von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Die diesjährige GCC Release v15 ist raus: 
https://gcc.gnu.org/gcc-15/changes.html

Per Default wird C als C23 übersetzt. Ein paar Neuerungen:

* constexpr für Objekte.  Kann z.B. für Array-Größe verwendet werden.

* Direktive #embed, mit der man Binärdateien ins Programm einfügen kann. 
Das ging bislang schon, war aber z.T. umständliches Binutils Gebastel. 
Beispiel mit #embed:
1
#include <stdio.h>
2
#include <avr/pgmspace.h>
3
 
4
static const char foo_c[] PROGMEM =
5
{
6
#embed "foo.c"
7
    // Append \0 so that foo_c becomes a proper C string
8
    // (assuming foo.c is a text file).
9
    , '\0'
10
};
11
 
12
int main ()
13
{
14
    printf ("== foo.c has %d bytes ==\n%S\n",
15
            (int) sizeof (foo_c) - 1, foo_c);
16
}

* bool, true und false sind Schlüsselworte.  stdbool.h wird nicht mehr 
gebraucht, funktioniert aber weiterhin.

* Globale asm Statements können Argumente haben.

* In Prototypen wie "int func()" ist "()" gleichbedeutend mit "(void)".

* Case Ranges (-std=c2y)

* if Deklarationen so wie in for (-std=c2y)

* Implizite Oktal-Literals sind abgeschafft. Wer wirklich 12 oktal will 
schreibt also nicht mehr 012 sondern 0o12.

Auch für AVR gibt es ein paar Neuerungen:

https://gcc.gnu.org/gcc-15/changes.html#avr

* Attribute signal(num) wo num die IRQ-Nummer ist.  Damit kann man 
static Funktionen als ISR verwenden und auch Funktionen aus einem C++ 
Namespace.  AVR-LibC v2.3 uterstützt das als ISR_N(num). Beispiel:
1
#include <avr/io.h>
2
3
__attribute__((signal(ADC_vect_num)))
4
static void adc_isr (void)
5
{
6
   // Code
7
}
8
9
#include <avr/interrupt.h>
10
11
ISR_N (INT0_vect_num) // ab AVR-LibC v2.3
12
static void int0_isr (void)
13
{
14
   // Code
15
}

* Unterstützung von Compact Vector Table (CVT).  Auch dies erfordert 
AVR-LibC v2.3.

AVR-LibC v2.3 ist noch nicht released.
News: https://github.com/avrdudes/avr-libc/blob/main/NEWS.md
(Links auf neue Header sind 404 weil die aktuelle Doku noch für v2.2 
ist.)

: Bearbeitet durch User
von Falk B. (falk)


Lesenswert?

Johann L. schrieb:
> #embed "foo.c"
>     // Append \0 so that foo_c becomes a proper C string
>     // (assuming foo.c is a text file).
>     , '\0'
> };

Und was mache ich, wenn ich keine extra \0 haben will, was bei 
Binärdateien der Normalfall ist? Denn dadurch ändert sich ja die 
Objektgröße.

von Hmmm (hmmm)


Lesenswert?

Falk B. schrieb:
> Und was mache ich, wenn ich keine extra \0 haben will, was bei
> Binärdateien der Normalfall ist?

Meinst Du die Frage ernst?

Johann L. schrieb:
> , '\0'

von Dergute W. (derguteweka)


Lesenswert?

Falk B. schrieb:
> Und was mache ich, wenn ich keine extra \0 haben will, was bei
> Binärdateien der Normalfall ist?

Ich haette dann einfach die Zeile 9 weggelassen. Aber ich hab's nicht 
ausprobiert.

Gruss
WK

von Bauform B. (bauformb)


Lesenswert?

Johann L. schrieb:
> * Implizite Oktal-Literals sind abgeschafft. Wer wirklich 12 oktal will
> schreibt also nicht mehr 012 sondern 0o12.

Vielen Dank für die Warnung. Wer war das? 0.2% meiner Quelltextzeilen 
müssen geändert werden, muss das sein? Brauchen die alle kein chmod(), 
open(), creat()... oder ANSI-Escapes? Funktioniert denn jetzt zum 
Ausgleich wenigstens '\e' statt '033'?

Kennt der gcc 13 oder 14 diese Konstruktion schon?

1
$ gcc --version
2
gcc (Debian 12.2.0-14) 12.2.0
3
$ make
4
mkpdfs.c: In function 'mktmpdir':
5
mkpdfs.c:192:23: error: invalid suffix "o755" on integer constant
6
  192 |    if (mkdir (tmpdir, 0o755)) {
7
      |                       ^~~~~

von Oliver S. (oliverso)


Lesenswert?

Bauform B. schrieb:
> Vielen Dank für die Warnung. Wer war das? 0.2% meiner Quelltextzeilen
> müssen geändert werden, muss das

Du musst ja alte Quelltexte nicht mit C23 übersetzen. Wenn doch, muss es 
halt C23 sein. Für den Sprachstandard kann der Compiler nichts.

Oliver

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Bauform B. schrieb:
> Brauchen die alle kein chmod(), open(), creat()

Vielleicht nehmen sie ja einfach
1
S_IRUSR | S_IWUSR

statt 0o666?

von Dergute W. (derguteweka)


Lesenswert?

Moin,

Bauform B. schrieb:
> Kennt der gcc 13 oder 14 diese Konstruktion schon?
Ich glaube nicht. Hier mit einem 14.2.0:
1
gcc -std=c23 bla.c 
2
bla.c: In function ‘main’:
3
bla.c:4:19: error: invalid suffix "o123" on integer constant
4
    4 |     printf("%d\n",0o123);
5
      |                   ^~~~~

ohne -std genauso.

Gruss
WK

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Bauform B. schrieb:
> Johann L. schrieb:
>> * Implizite Oktal-Literals sind abgeschafft. Wer wirklich 12 oktal will
>> schreibt also nicht mehr 012 sondern 0o12.
>
> Vielen Dank für die Warnung. Wer war das?

WG14 Vorschlag N3193 "Obsolete implicitly octal literals" ist zum 
Beispiel hier zu finden:
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3193.htm

>> The use of base-8 instead of base-10 by integer literals that begin
>> with a zero digit is the source of frequent confusion. We propose
>> marking the use of such literals as obsolete in order to encourage
>> a warning that will prompt rewrites, and the introduction of a new
>> prefix to explicitly mark literals that are genuinely intended to
>> be in base-8.

und:

>> We propose that a new syntax is added for explicit octal constants,
>> with a new prefix 0o or an alternative spelling to mark the beginning
>> of a base-8 literal. The old syntax should be retained and marked as
>> obsolescent to avoid breaking the meaning of existing code.

Wie es aussieht wird es eine neue Diagnostic geben, die auch deaktiviert 
werden kann wenn man die alte Syntax wirklich haben will (ähnlich zu 
Trigraphen).

> Kennt der gcc 13 oder 14 diese Konstruktion schon?

Das hängt weniger am Compiler als an der C-Version, welche noch nicht 
released ist. C2y wird wohl C26 oder C27 werden.  In C23 ist es als 
Erweiterung drin, aber erst ab GCC v15:
1
$ echo 'int i = 0o12;' | gcc-14 -xc - -fsyntax-only -std=c23
2
<stdin>:1:9: error: invalid suffix "o12" on integer constant
3
$ echo 'int i = 0o12;' | gcc-15 -xc - -fsyntax-only -std=c23 # ok
4
$ echo 'int i = 0o12;' | gcc-15 -xc - -fsyntax-only -Wpedantic
5
<stdin>:1:9: warning: '0o' prefixed constants are a C2Y feature or GCC extension [-Wpedantic]
6
$ echo 'int i = 0o12;' | gcc-15 -xc - -fsyntax-only -std=c2y -Wpedantic # ok

Compiler Explorer https://godbolt.org/ kennt auch schon GCC v15.1 wenn 
du was ausprobieren willst.

Zum Portieren auf eine neue GCC Version gibt es auch immer Porting 
Notes:

https://gcc.gnu.org/gcc-13/porting_to.html
https://gcc.gnu.org/gcc-14/porting_to.html
https://gcc.gnu.org/gcc-15/porting_to.html

von Philipp Klaus K. (pkk)


Lesenswert?

Johann L. schrieb:
> * Implizite Oktal-Literals sind abgeschafft. Wer wirklich 12 oktal will
> schreibt also nicht mehr 012 sondern 0o12.

Die Änderung bezüglich der oktalen integer literals ist in C2y, nicht 
C23. Und auch in C2y ist die Variante mit führender 0 nicht 
"abgeschafft", sondern nur "obsolete".

von Falk B. (falk)


Lesenswert?

Hmmm schrieb:
>> Und was mache ich, wenn ich keine extra \0 haben will, was bei
>> Binärdateien der Normalfall ist?
>
> Meinst Du die Frage ernst?
>
> Johann L. schrieb:
>> , '\0'

Ach ich Depp, ich hab's falsch verstanden! War zu warm heute!

von Foka M. (foka)


Lesenswert?

Johann L. schrieb:
> Die diesjährige GCC Release v15 ist raus:
> https://gcc.gnu.org/gcc-15/changes.html

Vielen Dank!

Habe gerade paar meiner Projekte damit und aktueller avr-libc (git) 
durchgebaut. Generierter code scheint, bei mir, mit dem gcc-15.1 
deutlich kleiner zu sein als gcc-14.2. An gcc-13.1 kommt er allerdings 
nicht heran.

Trotzdem, vielen Dank noch mal fuer den unglaublichen Einsatz!


Wie wird uebrigens das hier funktionieren:
> * Unterstützung von Compact Vector Table (CVT).  Auch dies erfordert
> AVR-LibC v2.3.
In den neuen gcc/ld manpages habe ich nichts dazu gefunden. Wird es 
automatisch passieren, oder wird man sich dazu linker-command-files 
selber stricken muessen?

-Foka

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Foka M. schrieb:
> Generierter code scheint, bei mir, mit dem gcc-15.1 deutlich kleiner
> zu sein als gcc-14.2. An gcc-13.1 kommt er allerdings nicht heran.

Da wäre interessant zu sehen, wo es da hakt (also Testfall, Optionen 
etc.)

> Wie wird uebrigens das hier funktionieren:
>> * Unterstützung von Compact Vector Table (CVT).  Auch dies erfordert
>> AVR-LibC v2.3.
> In den neuen gcc/ld manpages habe ich nichts dazu gefunden.

https://gcc.gnu.org/onlinedocs/gcc-15.1.0/gcc/AVR-Options.html#index-mcvt

Linker und Linkerscript sind unverändert.

1) libc configure stellt fest, welche Devices CVT können.

2) Für entsprechende Devices gibt es eine neue Build-Variante 
crt<mcu>-cvt.o des Startup-Codes, der ja die Vectab mitbringt.

3) Welcher Startup-Code gelinkt wird entscheidet der Compiler anhand von 
-mcvt: crt<mcu>.o oder crt<mcu>-cvt.o.

4) crt<mcu>-cvt.o referenziert Code, der CVT aktiviert (in .init3).  Man 
braucht CVT also nicht händisch zu aktivieren.

https://github.com/avrdudes/avr-libc/blob/main/libc/misc/init_cvt.S

Falls man CVT selbst aktivieren möchte, dann definiert man Symbol 
__init_cvt so dass der Code nicht mehr aus der Devicelib gezogen wird.

crt<mcu>-cvt.o kann man natürlich auch mit älteren GCC Versionen 
verwenden, hat dann aber nicht den Comfort von -mcvt.

von Foka M. (foka)


Lesenswert?

Johann L. schrieb:
> Foka M. schrieb:
>> Generierter code scheint, bei mir, mit dem gcc-15.1 deutlich kleiner
>> zu sein als gcc-14.2. An gcc-13.1 kommt er allerdings nicht heran.
>
> Da wäre interessant zu sehen, wo es da hakt (also Testfall, Optionen
> etc.)

Ich versuche mal am kommenden langen WoE etwas mehr Inhalte zusammen zu 
bekommen.
Compiler wird aufgerufen mit (nur ein Beispiel):
1
avr-15.1.0/bin//avr-g++ -c -DF_CPU=4000000UL -DF_CLOCK=4000000UL \
2
-DCONFIG_H=\"config_atmega328p.h\" \
3
-I. -I../ -I../avrUtils -I../avrUtils/com -I../avrUtils/common/ -I./ \
4
-Os -g -mmcu=atmega328p -flto -mstrict-X -mrelax -maccumulate-args \
5
-mcall-prologues -funsigned-char -funsigned-bitfields \
6
-ffunction-sections -fdata-sections -fshort-enums -fno-strict-aliasing \
7
-Wall -Wextra -Wundef -Wunreachable-code -Wsign-compare \
8
-fno-threadsafe-statics -std=c++20 -MMD -MP -MF .dep/AvrAsyncTimer.o.d \
9
../Fio/avr/AvrAsyncTimer.cpp -o objs/AvrAsyncTimer.o

Ich mache vorwiegend C++ und bin gerade auf C++20 festgenagelt. Die 
Unterschiede koennten also auch hieraus entstehen. Auch wenn der gcc-13 
schon so ziemlich "feature complete" gewesen ist.

>> Wie wird uebrigens das hier funktionieren:
>>> * Unterstützung von Compact Vector Table (CVT).  Auch dies erfordert
>>> AVR-LibC v2.3.
>> In den neuen gcc/ld manpages habe ich nichts dazu gefunden.
>
> https://gcc.gnu.org/onlinedocs/gcc-15.1.0/gcc/AVR-Options.html#index-mcvt
>

Oh, richtig. Habe ich in der manpage echt uebersehen.
Danke fuer die Erklaerung. Das WoE wird echt zu kurz ;-)

-Foka

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Foka M. schrieb:
1
> avr-g++ ... -flto ... -o objs/AvrAsyncTimer.o

Mit LTO genügt zum Nachvollziehen nicht mehr das Präcompilat eines 
Moduls (z.B. mit -save-temps), weil *.o nur LTO-Bytecode enthält. 
(-ffat-lto-objects hilft auch nix, weil nicht-LTO Code zur lto Time 
verworfen wird).

Mit LTO braucht man also (die Präcompilate) alle(r) Module, um was 
nachzuvollziehen.  Evtl lässt sich mit -fno-lto eingrenzen, wo der 
Codezuwachs herhommt.  Wenn er nur mit -flto passiert ist es ein Indiz 
dafür, dass sich was beim IPA geändert hat (Inlining, Cloning, 
LTO-Partitioning, etc.).

: Bearbeitet durch User
von Foka M. (foka)


Lesenswert?

Johann L. schrieb:
> Foka M. schrieb:
>
1
>> avr-g++ ... -flto ... -o objs/AvrAsyncTimer.o
>
> Mit LTO genügt zum Nachvollziehen nicht mehr das Präcompilat eines
> Moduls (z.B. mit -save-temps), weil *.o nur LTO-Bytecode enthält.
> (-ffat-lto-objects hilft auch nix, weil nicht-LTO Code zur lto Time
> verworfen wird).

Ich habe jetzt das gleiche ohne lto gemacht.
Geiches Projekt, gleiche compile optionen, in beiden Faellen ohne lto.
gcc-13.1:
1
Sections:
2
Idx Name          Size      VMA       LMA       File off  Algn
3
  0 .data         00000050  00800100  00001b0c  00001bc0  2**0
4
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
5
  1 .text         00001b0c  00000000  00000000  000000b4  2**1
6
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
7
  2 .bss          00000091  00800150  00800150  00001c10  2**0

gcc-15.1:
1
Sections:
2
Idx Name          Size      VMA       LMA       File off  Algn
3
  0 .data         00000050  00800100  00001b7e  00001c32  2**0
4
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
5
  1 .text         00001b7e  00000000  00000000  000000b4  2**1
6
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
7
  2 .bss          00000091  00800150  00800150  00001c82  2**0
Das sind, bei ca. 7kB in .text, 114Byte Unterschied zu Gunsten des 
gcc-13.1.

Wie gesagt, ich werde mir am WoE die einzelnen Objekte ansehen, und 
melde mich wieder falls ich etwas greifbareres habe.

-Foka

von Rolf M. (rmagnus)


Lesenswert?

Johann L. schrieb:
> * Implizite Oktal-Literals sind abgeschafft. Wer wirklich 12 oktal will
> schreibt also nicht mehr 012 sondern 0o12.

Hmm, dann kann man jetzt endlich die 0 in dezimal schreiben. 😀

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Rolf M. schrieb:
> Johann L. schrieb:
>> Wer wirklich 12 oktal will schreibt also nicht mehr 012 sondern 0o12.
>
> Hmm, dann kann man jetzt endlich die 0 in dezimal schreiben. 😀

Nicht mal das. N3193:

>> Zero remains a traditional octal constant

Da oktal in MISRA absolut verboten ist, darf man also immer noch nicht 
"x = 0;" schreiben sondern muss weiterhin "x = 1-1;" o.ä.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Johann L. schrieb:
> Da oktal in MISRA absolut verboten ist, darf man also immer noch nicht
> "x = 0;" schreiben

Prust! Aber man kann jetzt immerhin "x = 0815;" schreiben. :-)

von Foka M. (foka)


Lesenswert?

Foka M. schrieb:
> Johann L. schrieb:
>> Foka M. schrieb:
>>
1
>>> avr-g++ ... -flto ... -o objs/AvrAsyncTimer.o
>>
>> Mit LTO genügt zum Nachvollziehen nicht mehr das Präcompilat eines
>> Moduls (z.B. mit -save-temps), weil *.o nur LTO-Bytecode enthält.
>> (-ffat-lto-objects hilft auch nix, weil nicht-LTO Code zur lto Time
>> verworfen wird).
>
> Wie gesagt, ich werde mir am WoE die einzelnen Objekte ansehen, und
> melde mich wieder falls ich etwas greifbareres habe.
>

Ich habe jetzt mal paar Codestellen die gcc-15.1 dicker macht genauer 
angesehen. Zum einen muss ich zu geben, dass ich die gcc-13.1 und 15.1 
tool-chains mit verschiedenen avr-libc Versionen gebaut habe. 
Dummerweise beide direkt auf dem, damaligen, git-master basierend. Dh. 
um wirklich fundierte Vergleiche zu bekommen muesste ich beide compiler 
mit der gleichen avr-libc verwenden.

Mir fiel jedoch auf, dass der gcc-15.1 sich mehr um den stack pointer 
'kuemmert' und dazu neigt prologue/epilogue fetter zu machen. Hier mal 
eine kleine Funktion die zwei bytes auf SPI schreibt. Eigentlich sollte 
es nur CS-ziehen, zwei mal `txRaw` (schreibt einen byte und wartet auf 
fertig) aufrufen und dann wieder CS los lassen.

Beim gcc-13.1 sieht es so aus ('//' sind meine kommentare):
1
#    template <class Locker = DefaultLockTypeT>
2
#    static uint8_t               txCmd( uint8_t _cmd, uint8_t _byte ) {
3
     3d8:  cf 93         push  r28
4
     3da:  c6 2f         mov  r28, r22
5
     3dc:  40 98         cbi  0x08, 0  ; 8  // pull CS
6
     3de:  f5 df         rcall  .-22       ; 0x3ca <Fl::AvrIO::AvrSpiMaster<Fl::AvrIO::PinX<(unsigned char)0, Fl::AvrIO::PortX<38> > >::txRaw(unsigned char)>
7
     3e0:  8c 2f         mov  r24, r28
8
     3e2:  f3 df         rcall  .-26       ; 0x3ca <Fl::AvrIO::AvrSpiMaster<Fl::AvrIO::PinX<(unsigned char)0, Fl::AvrIO::PortX<38> > >::txRaw(unsigned char)>
9
     3e4:  40 9a         sbi  0x08, 0  ; 8  // release CS
10
     3e6:  cf 91         pop  r28
11
     3e8:  08 95         ret

Der gcc-15.1 macht daraus:
1
#    template <class Locker = DefaultLockTypeT>
2
#    static uint8_t               txCmd( uint8_t _cmd, uint8_t _byte ) {
3
     3e8:  a1 e0         ldi  r26, 0x01  ; 1
4
     3ea:  b0 e0         ldi  r27, 0x00  ; 0
5
     3ec:  ea ef         ldi  r30, 0xFA  ; 250
6
     3ee:  f1 e0         ldi  r31, 0x01  ; 1
7
     3f0:  0c 94 4c 0d   jmp  0x1a98  ; 0x1a98 <.Loc.16>
8
     3f4:  69 83         std  Y+1, r22  ; 0x01
9
     3f6:  40 98         cbi  0x08, 0  ; 8  // pull CS
10
     3f8:  f0 df         rcall  .-32       ; 0x3da <Fl::AvrIO::AvrSpiMaster<Fl::AvrIO::PinX<(unsigned char)0, Fl::AvrIO::PortX<38> > >::txRaw(unsigned char)>
11
     3fa:  89 81         ldd  r24, Y+1  ; 0x01
12
     3fc:  ee df         rcall  .-36       ; 0x3da <Fl::AvrIO::AvrSpiMaster<Fl::AvrIO::PinX<(unsigned char)0, Fl::AvrIO::PortX<38> > >::txRaw(unsigned char)>
13
     3fe:  40 9a         sbi  0x08, 0  ; 8  // release CS
14
     400:  21 96         adiw  r28, 0x01  ; 1
15
     402:  e2 e0         ldi  r30, 0x02  ; 2
16
     404:  0c 94 68 0d   jmp  0x1ad0  ; 0x1ad0 <.Loc.16>

In `.Loc.16` ist eine sub-routine die den SREG rettet, interrupts 
stoppt, stack pointer runter schiebt, und dann den SREG wieder zurueck 
holt (gcc-15.1):
1
00001ad0 <.Loc.16>:
2
    1ad0:  aa 81         ldd  r26, Y+2  ; 0x02
3
    1ad2:  b9 81         ldd  r27, Y+1  ; 0x01
4
    1ad4:  ce 0f         add  r28, r30
5
    1ad6:  d1 1d         adc  r29, r1
6
    1ad8:  0f b6         in  r0, 0x3f  ; 63
7
    1ada:  f8 94         cli
8
    1adc:  de bf         out  0x3e, r29  ; 62
9
    1ade:  0f be         out  0x3f, r0  ; 63
10
    1ae0:  cd bf         out  0x3d, r28  ; 61
11
    1ae2:  ed 01         movw  r28, r26
12
    1ae4:  08 95         ret
Klingt plausiebel. Aber ich frage mich, warum der gcc-13.1 das nicht 
macht. Sind im neuen GCC vielleicht irgendwelche stack pointer 
Schutzmechanismen eingebaut worden die jetzt mehr speicher verbrauchen?

Der gcc-13.1 schiebt den stack pointer natuerlich auch immer wieder 
herum. Aber vor allem dann, wenn eine groessere sub-routine (oder 
mehrere davon) aufgerufen wird. Ich habe kaum Stellen gesehen an den es 
so aufwaendig gemacht wird, obwohl die sub-routine wirklich so banal ist 
wie mein `txRaw` oben.

Falls es etwas bringt, kann ich den generierten code fuer die kleine 
`txRaw` auch posten.

Ich habe noch paar andere Stellen gefunden, an den der gcc-15.1 sich dem 
stack pointer mehr zuwendet. Es ist etwas weniger aufwaendig wie oben 
und ist vollstaendig, ohne 'jump', in den prologue der Funktion 
eingebettet. Allerdings macht an der gleichen Stellen der gcc-13.1 
nichts weiter als nur den Stackpointer zu speichern, was viel weniger 
aufwaendig und damit kuerzer ist.
Hier ein Auszug aus einer etwas groesseren Funktion. Nur der prologue.
gcc-13.1:
1
# RadioHandler<PolicyT, IsrImpl>::receivePingRequest(){
2
     bd6:  cf 92         push  r12
3
     bd8:  df 92         push  r13
4
     bda:  ef 92         push  r14
5
     bdc:  0f 93         push  r16
6
     bde:  1f 93         push  r17
7
     be0:  cf 93         push  r28
8
     be2:  df 93         push  r29
9
     be4:  00 d0         rcall  .+0        ; 0xbe6 <L0^A>
10
00000be6 <L0^A>:
11
     be6:  00 d0         rcall  .+0        ; 0xbe8 <L0^A>
12
00000be8 <L0^A>:
13
     be8:  00 d0         rcall  .+0        ; 0xbea <L0^A>
14
00000bea <L0^A>:
15
     bea:  cd b7         in  r28, 0x3d  ; 61  // store spl
16
     bec:  de b7         in  r29, 0x3e  ; 62  // store sph
17
     bee:  6c 01         movw  r12, r24
18
19
00000bf0 <.Loc.879>:
20
#    RxData<PacketType::PingRequestPkt> rxData{mRxMetaData.mRxData};
21
     bf0:  fc 01         movw  r30, r24
22
     bf2:  a3 85         ldd  r26, Z+11  ; 0x0b  // ab hier alles wieder gleich
23
     bf4:  b4 85         ldd  r27, Z+12  ; 0x0c
24
...

Dagegen gcc-15.1 ('//' wieder von mir):
1
# RadioHandler<PolicyT, IsrImpl>::receivePingRequest(){
2
     c50:  ef 92         push  r14
3
     c52:  0f 93         push  r16
4
     c54:  1f 93         push  r17
5
     c56:  cf 93         push  r28
6
     c58:  df 93         push  r29
7
     c5a:  cd b7         in  r28, 0x3d  ; 61  // store spl
8
     c5c:  de b7         in  r29, 0x3e  ; 62  // store sph
9
     c5e:  28 97         sbiw  r28, 0x08  ; 8  // reduce stack pointer by 8
10
     c60:  0f b6         in  r0, 0x3f  ; 63  // sreg write
11
     c62:  f8 94         cli        // shut up
12
     c64:  de bf         out  0x3e, r29  ; 62  // restore sph
13
     c66:  0f be         out  0x3f, r0  ; 63  // restore sreg
14
     c68:  cd bf         out  0x3d, r28  ; 61  // restore spl
15
     c6a:  8f 83         std  Y+7, r24  ; 0x07
16
     c6c:  98 87         std  Y+8, r25  ; 0x08
17
18
00000c6e <.Loc.872>:
19
#    RxData<PacketType::PingRequestPkt> rxData{mRxMetaData.mRxData};
20
     c6e:  fc 01         movw  r30, r24
21
     c70:  a3 85         ldd  r26, Z+11  ; 0x0b  // ab hier alles wieder gleich
22
     c72:  b4 85         ldd  r27, Z+12  ; 0x0c

Ist es moeglich dem gcc-15.1 etwas schlankere Funktionsaufrufe 
beizubringen? Ich habe das Gefuel, dass ich, zumindest in meinem Code, 
einiges sparen koennte.

-Foka

von Philipp Klaus K. (pkk)


Lesenswert?

Jörg W. schrieb:
> Johann L. schrieb:
>> Da oktal in MISRA absolut verboten ist, darf man also immer noch nicht
>> "x = 0;" schreiben
>
> Prust! Aber man kann jetzt immerhin "x = 0815;" schreiben. :-)

0815 ist weiterhin eine oktale Ganzzahl. Ab C2y in einer dann 
veralteten, aber weiterhin unterstützten Schreibweise.

von Oliver S. (oliverso)


Lesenswert?

Foka M. schrieb:
> Ist es moeglich dem gcc-15.1 etwas schlankere Funktionsaufrufe
> beizubringen?

Bestimmt. Wie überall bei open source gilt: einfach machen...

Ob sich überhaupt jemand sich gross um den avr-g++ kümmert, keine 
Ahnung. Der hat ja mit dem hier (implizit) besprochenen C-Compiler 
nichts zu tun.

Oliver

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Foka M. schrieb:
> Zum einen muss ich zu geben, dass ich die gcc-13.1 und 15.1
> tool-chains mit verschiedenen avr-libc Versionen gebaut habe.

Spielt auf der Ebene keine Rolle.

> In `.Loc.16` ist eine sub-routine die den SREG rettet, interrupts
> stoppt, stack pointer runter schiebt, und dann den SREG wieder
> zurueck holt (gcc-15.1):

Das ist __epilogue_restores

https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=libgcc/config/avr/lib1funcs.S;h=dfe99b1ea06f5b45e0a19942c42fe92f46e497ac;hb=HEAD#l2241

das Gegenstück zu __prologue_saves

https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=libgcc/config/avr/lib1funcs.S;h=dfe99b1ea06f5b45e0a19942c42fe92f46e497ac;hb=HEAD#l2188

Beide können verwendet werden wenn -mcall-prologues an ist.

> Aber ich frage mich, warum der gcc-13.1 das nicht macht.

Weil, wie du bereitst feststelltest, v15 mehr Stack beansprucht.

> Falls es etwas bringt, kann ich den generierten code fuer die kleine
> `txRaw` auch posten.

Den generierten Code seh ich ja.  Bestenfalls könnte man mit dem 
Präcompilat (*.ii von -save-temps) was anfangen.

> Ist es moeglich dem gcc-15.1 etwas schlankere Funktionsaufrufe
> beizubringen?

Da es sich um den Register-Allokator handelt wäre eine Änderung 
hochgradig nichttrivial und würde alle Targets betreffen, also nicht nur 
AVR.

Mit C vs. C++ hat das überigens nichts zu tun. Die > 300 Passes nach dem 
Frontend sind für C und C++ die selben.

von Rolf M. (rmagnus)


Lesenswert?

Jörg W. schrieb:
> Prust! Aber man kann jetzt immerhin "x = 0815;" schreiben. :-)

Oder "x = 08/15", was dann auch wieder 0 wäre. 😀

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.