Hi, hier meine build-optionsZitat von ogni42
Aber selbst damit bekommst du noch lange nicht alle Warnungen...Code:avr-gcc -mmcu=atmega88 -S fixedPointArithmetics.c -dp -save-temps -fverbose-asm -Wall -Os -morder1 -W -Winline -fno-keep-inline-functions -DF_CPU=1000000 -fno-common -Wstrict-prototypes
Das kommt deshalb hin, weil die Funktionen nie geinlinet werden und die Register-Allokierung von avr-gcc eben so ist, daß die Register immer in der passenden Klasse liegen.Zitat von ogni42
Falsch ist es ja nicht, nur werden die Funktionen so nie geinlinet...Zitat von ogni42
Funktionen können nur dann geinlint werden, wenn dem Compiler der Quellcode der zu inlinenden Funktionen bekannt ist. Du gibt dem Compiler aber lediglich via #include "foo.h" das Interface zu sehen!
Das "extern" bewirkt hier nur, daß die so deklarierten Inline-Funktionen vom Compiler implementiert werden und als Object zur Verfügung stehen, wenn das Symbol gebraucht wird (Funktionsaufruf von ausserhalb, Funktionsadresse nehmen, etc).
Damit der Code tatsächlich geinlint wird, muss er also im Header (und damit im C-Modul, das das Zeug verwendet) sichtbar sein.
Du kannst also die Implementierungen in den Header schreiben und die Funktionen als static inline deklarieren und dann implementieren.
GCC hat allerdings eine recht genaue Vorstellung davon, für welche Funkrtionen ein inline lohnt und wann nicht (Größe des Tree, Anzahl insns, ...). inline ist also nur eine Empfehlung, ein heherer Wunsch an GCC. Wenn auf jeden Fall (vorausgesetzt immer, daß es prinzipiell möglich ist) geinlint werden soll, dann gibt man der Funktion das Attribut always_inline:
Ob das in Deinem Fall notwendig ist kann ich nicht sagen, weil ich nicht weiß, wie GCC asm behandelt (GCC kann nicht wissen, wieviel/was für'n Code sich darin verbirgt).Code:#define INLINE __attribute__((always_inline)) static INLINE ...
Allerdings wirst du beobachten, daß der Code nicht so optimal ist, wie du dir wünscht. Ursache dafür ist die argument und return parameter promotion die erfolgt und die auch nicht umgangen werden kann. Du wirst also ständig überflüssige zeroextends vorfinden, d.h. 8-Bit-Werte werden zu 16-Bit-Werten expandiert, obwohl nie per 16 Bit auf den Wert zugegriffen wird. Das gibt viel Overhead in Laufzeit und Code, vorallem weil das Inlinen als Multiplikator wirkt.
Promotion kannst du nur dadurch vermeiden, indem du den Code -- zugegeben nicht sonderlich hübsch -- in Makros steckst, etwa als valued block.
Noch besser und wirklich optimalen Code bekommst du, wenn GCC eine Vorstellung davon hat, was er da treibt. Das würde bedeuten, die Funktionen als builtins (intrinsics) zur Verfügung zu stellen...![]()
Lesezeichen