Hi Georg-Johann,

vielen Dank für Dein ausführliches Feedback. Das hilft mir sehr weiter. Die Constraints werde ich noch anpassen.

Den sbiw baue ich bein den sub und add noch ein. (Da ich die ganze Woche unterwegs war, ist der Code noch auf einem anderen Rechner)

Was ist die Idee hinter dem Ganzen?

Klassisch gibt es zwei Möglichkeiten Signalverarbeitungsroutinen auf Non-DSPs zu implementieren, Fließpunkt- oder Festpunktarithmetik. Floats sind auf dem AVR Overkill und der Flash/RAM sind schnell aufgebraucht. Daher kommt eigentlich nur Festpunktarithmetik in Frage. Die AVRs bieten Festpunktbefehle in Assembler an, aber es gibt keinen Weg, von aus C da ran zu kommen - außer per inline Assembler eben.

Der Vorteil der fmulx Opcodes ist, dass der Wertebereich immer [-1, 1[ bzw [0, 2[ angenommen wird. Daher sind Multiplikationen immer ohne Überläufe zu handhaben. Des weiteren ist der FixpointMultiplyAndAccumulate für viele Signalverarbeitungsalgorithmen hilfreich. Division kommt eher selten vor. Atmel bietet ja ein paar Beispiele zur Nutzung von FMAC etc., die haben aber m.E. zwei wesentliche Nachteile:
- kein Clipping, Bereichsüberläufe werden nicht behandelt, die sind aber wichtig
- Die Atmel Implementierung nimmt keine Rücksicht auf die Genauigkeit und verschwendet dadurch Rechenzeit (aus zwei 16 bit Werten wird ein 32bit Wert dessen untere 16 bit aber nicht weiter helfen).

Für meine Anwendung ist dann die Balance zwischen Speicherverbrauch und Geschwindigkeit zu halten. Inline C-Funktionen scheinen mir da am Besten geeignet. Wenn der Flash eng wird, kommt das inline raus und weiter gehts.

Die Routinen sind einerseits bei für mich ausreichender (hoffe ich) Genauigkeit erheblich schneller als eine Implementierung in C andererseits noch so kompakt, dass sie für einen Assembler-Laien wie mich überschaubar bleiben. Mit der Parameter-Promotion muss ich da wohl leben. Die Alternative mit #defines finde so fies, dass ich nur in der größten Not darauf zurück greifen möchte.

Hab' auch nochmal die GCC Doku etwas genauer gelesen. An einer Stelle steht inline in der declaration an anderer inline in der definition, die dann im Header landen soll. Letzteres funktioniert dann auch (wie Du bereits geschrieben hast)

Ingo