moin, moin,
wenn ich schon Floatingpoint-Hardware habe und eine geniale printf()
gefunden habe, könnte ich die auch benutzen -- dachte ich. Das Ergebnis
ist ein länglicher Kommentar in meinem Makefile. Es geht auch ohne bzw.
das Preis/Leistungsverhältnis ist mir zu schlecht, das ist jetzt kein
Problem. Aber evt. kann jemand etwas dazu sagen?
1
# DO NOT USE CFLAGS += -march=armv7e-m+fp -mtune=cortex-m4 -mfpu=fpv4-sp-d16
2
# DO NOT USE CFLAGS += -mfloat-abi=hard -fsingle-precision-constant
3
# DO NOT USE # CFLAGS += -mfloat-abi=softfp -fsingle-precision-constant
4
# DO NOT USE LDFLAGS += -lgcc
5
# DO NOT USE
6
# DO NOT USE Mit -march=armv7e-m+fp baut der GCC FPU-Befehle auch in reine
7
# DO NOT USE Integer-Funktionen ein. Also evt. auch in Interrupt-Routinen!
8
# DO NOT USE Wenn die FPU per default abgeschaltet ist, wie ARM behauptet,
9
# DO NOT USE gibt es dann einen fault.
10
# DO NOT USE Praktisch ist sie aber nicht abgeschaltet. Damit kostet jeder
11
# DO NOT USE Interrupt 72 Byte mehr Stack. Deshalb ist es nicht klar, ob der
12
# DO NOT USE SVC noch funktioniert bzw. was noch alles zu beachten ist.
13
# DO NOT USE
14
# DO NOT USE Es ist nicht praktikabel, die FPU nur in main() oder nur in
15
# DO NOT USE genau einer task zu benutzen um Stack und Zeit zu sparen
Bauform B. schrieb:> # DO NOT USE Mit -march=armv7e-m+fp baut der GCC FPU-Befehle auch in> reine> # DO NOT USE Integer-Funktionen ein. Also evt. auch in> Interrupt-Routinen!
Nur wenn man ohne Optimierungen kompiliert. Du kannst die FPU auch beim
Betreten der ISR abschalten (CPACR Register), sodass dann bei
fälschlicher Nutzung der FPU ein Fault kommt, und du den Bug finden
kannst. Du kannst die ISRs auch in eine separate Datei packen und diese
ohne FPU-Nutzung kompilieren. Außerdem gibt es ja noch das Lazy Context
Save.
Bauform B. schrieb:> Praktisch ist sie aber nicht abgeschaltet.
Dann wird sie irgendwo in deinem Startup-Code eingeschaltet.
Ich habe die FPU schon problemlos in Cortex-M4F- und Cortex-A8-Projekten
genutzt, auch in ISRs.
Was ist denn nun die Frage? Wie man die FPU abschaltet, oder wie man sie
einschaltet, oder was?
Und ja, nach ein paar Compilermäkeleien und Wirrwar mit den -D Flags
nutze ich die FPU nun.
Matthias S. schrieb:> Was ist denn nun die Frage?
Er versteht den Kommentar im Makefile nicht. Weil er das Konzept
"context saving" nicht verstanden hat. Und wie es mit der FPU
zusammenhängt. Der Kommentarschreiber hatte es anscheinend auch nicht
verstanden.
Wir haben also eine Situation, wo der Blinde dem Tauben etwas über
Farben erzählt. Sicher nicht zielführend, aber lustig anzusehen.
Programmierer schrieb:> Nur wenn man ohne Optimierungen kompiliert.
Oder mit -Os.
> Du kannst die FPU auch beim Betreten der ISR abschalten> (CPACR Register), sodass dann bei fälschlicher Nutzung der FPU> ein Fault kommt, und du den Bug finden kannst.
Das ist eine gute Idee für den Notfall. Aber eigentlich ist es dann
doppelt zu spät. Einmal hat der GCC schon falschen Code erzeugt und die
extra Bytes auf dem Stack sind schon verbraucht.
> Du kannst die ISRs auch in eine separate Datei packen und diese> ohne FPU-Nutzung kompilieren.
Dann habe ich aber zwei verschiedene Procedure Call Standards. Das ist
wie vom Regen in die Traufe, wer weiß, was das für Überraschungen gibt.
> Außerdem gibt es ja noch das Lazy Context Save.
Zweifellos sehr nett für zeitkritische Sachen, aber sonst ändert das
garnichts.
> Bauform B. schrieb:>> Praktisch ist sie aber nicht abgeschaltet.>> Dann wird sie irgendwo in deinem Startup-Code eingeschaltet.
Das wäre dann eine üble Nebenwirkung. Bis heute werden hier CPACR, FPCCR
usw. nirgendwo definiert oder benutzt. Es sieht sehr danach aus, dass
reset value eben nicht 000 ist.
> Ich habe die FPU schon problemlos in Cortex-M4F- und Cortex-A8-Projekten> genutzt, auch in ISRs.
Naja, hier hat auch alles funktioniert, aber ich weiß nicht warum und
wie lange. Es geht ja um Fehler, die nur sehr selten auftreten.
Freiwillig lässt man sich darauf nicht ein.
Matthias S. schrieb:> Und ja, nach ein paar Compilermäkeleien und Wirrwar mit den -D Flags> nutze ich die FPU nun.
Das macht es nur noch schlimmer. Was würde mir ein -D helfen?
Axel S. schrieb:> Er versteht den Kommentar im Makefile nicht. Weil er das Konzept> "context saving" nicht verstanden hat. Und wie es mit der FPU> zusammenhängt.
Egal was das ist und wie das zusammenhängt, warum sollte man die
FPU-Register anders behandeln als alle anderen? Das heißt eben auch,
wenn ich die FPU nur in main() benutze, muss auch nichts gerettet
werden. r4 bis r11 werden ja auch nur bei Bedarf gerettet.
Ich war davon ausgegangen, dass die FPU nur dort benutzt wird, wo auch
mit float gearbeitet wird. "Natürlich" ist es nicht so einfach.
Anscheinend kann man den context save sowieso nur zwischen lazy oder
nicht umschalten (und nicht ganz abschalten). Also geht nur alles oder
nichts und die FPU wird eben nicht benutzt.
> Wir haben also eine Situation, wo der Blinde dem Tauben etwas über> Farben erzählt. Sicher nicht zielführend, aber lustig anzusehen.
:)
Bauform B. schrieb:> Oder mit -Os.
Kannst du ein Beispiel zeigen?
Bauform B. schrieb:> und die> extra Bytes auf dem Stack sind schon verbraucht.
Nur wenn man das FP Context Saving eingeschaltet hat (FPCCR.ASPEN).
Bauform B. schrieb:> Dann habe ich aber zwei verschiedene Procedure Call Standards.
Nicht wenn du -mfloat-abi=softfp nutzt. Wenn du vom Nicht-FPU-ISR-Code
"normale" Funktionen mit potentieller FPU-Nutzung aufrufen willst,
verlagert sich das Problem natürlich nur; der gesamte ISR-Code inkl.
aufgerufener Funktionen müsste natürlich ohne FPU kompiliert worden
sein. Dann sind die unterschiedlichen ABIs egal.
Bauform B. schrieb:>> Außerdem gibt es ja noch das Lazy Context Save.> Zweifellos sehr nett für zeitkritische Sachen, aber sonst ändert das> garnichts.
Doch, damit kannst du gefahrlos in der ISR die FPU nutzen, und wenn du
sie nicht nutzt, wird auch nicht unnötig gesichert.
Bauform B. schrieb:> Es sieht sehr danach aus, dass> reset value eben nicht 000 ist.
Dann ist da etwas sehr faul. Welcher Controller ist das? Bei z.B. den
STM32F3 und den STM32F4 ist das nicht so.
Bauform B. schrieb:> Es geht ja um Fehler, die nur sehr selten auftreten.> Freiwillig lässt man sich darauf nicht ein.
Im Zweifelsfall guckt man sich das Disassembly an und sucht nach
FPU-Instruktionen.
Bauform B. schrieb:> Egal was das ist und wie das zusammenhängt, warum sollte man die> FPU-Register anders behandeln als alle anderen?
Weil die alle zu Sichern lange dauert. Genau deswegen hast du ja ein
Problem! Wenn du FPCCR.ASPEN=1 setzt werden sie automatisch bei
ISR-Eintritt gesichert und dein Problem löst sich auf.
Bauform B. schrieb:> Das heißt eben auch,> wenn ich die FPU nur in main() benutze, muss auch nichts gerettet> werden.
Korrekt. Dito wenn du sie nur in den ISRs nutzt und die nicht
verschachteln.
Bauform B. schrieb:> Ich war davon ausgegangen, dass die FPU nur dort benutzt wird, wo auch> mit float gearbeitet wird. "Natürlich" ist es nicht so einfach.
Der GCC ist halt clever genug auch andere Dinge, die von der FPU
profitieren, auf dieser auszuführen... Am Rande: Die "NEON" Erweiterung
der größeren ARMs kann nicht nur float, sondern auch
Vector-Integer-Operationen, weshalb der Neon-Status hier auch von
Integer-Operationen beeinflusst werden kann.
Bauform B. schrieb:> Anscheinend kann man den context save sowieso nur zwischen lazy oder> nicht umschalten (und nicht ganz abschalten). Also geht nur alles oder> nichts und die FPU wird eben nicht benutzt.
Nö, laut ARM gibt es drei Varianten:
When an ARMv7-M processor implements the FP extension, it has three
possible modes for stacking FP context information on taking an
exception:
* Do not stack any FP context. The processor stacks only a Basic frame,
as described in Operation of 8-byte stack alignment on page B1-535.
* Stack an Extended frame, containing the Basic frame and the FP state
information, as shown in Figure B1-4 on page B1-538. This preserves the
floating-point state required by the AAPCS.
* Reserve space on the stack for an Extended frame, but write-only the
Basic frame information. This is similar to the operation shown in
Figure B1-4 on page B1-538, except that no data is pushed into the stack
locations reserved for S0 - S15 and the FPSCR value. This is an FP lazy
context save, see Lazy context save of FP state on page B1-538.
The FPCCR.ASPEN and FPCCR.LSPEN bits determine which action is taken,
see Floating Point Context Control Register, FPCCR on page B3-615.
Programmierer schrieb:> Bauform B. schrieb:>> Oder mit -Os.>> Kannst du ein Beispiel zeigen?
Es passiert nur in einer Funktion und die ist praktisch "noreturn" weil
sie nur in einer noreturn-Funktion aufgerufen wird. Insofern darf die
FPU hier ohne save benutzt werden. Anscheinend ist der GCC wirklich
schlau. Ich hab' mal den obhdump angehängt, ist leider etwas sperrig.
Übersetzt wurde das mit -Os -g -march=armv7e-m+fp -mtune=cortex-m4
-mfpu=fpv4-sp-d16 -mfloat-abi=softfp. Mit -mfloat-abi=hard kommt
dasselbe raus.
> Bauform B. schrieb:>> Dann habe ich aber zwei verschiedene Procedure Call Standards.>> Nicht wenn du -mfloat-abi=softfp nutzt.
o.k., das wäre vernünftig, wenn nicht sogar logisch ;)
>> Es sieht sehr danach aus, dass>> reset value eben nicht 000 ist.>> Dann ist da etwas sehr faul. Welcher Controller ist das? Bei z.B. den> STM32F3 und den STM32F4 ist das nicht so.
das ist ein STM32L451, sowohl ARM als auch das PM0214 sagen: CPACR reset
value = 0. Allerdings FPCCR.ASPEN und .LSPEN reset value = 0b11. Ich
fasse beide Register nicht an, trotzdem funktionieren die FPU-Befehle.
Vom FPCCR her ist das ja klar und das CPACR wird evt. vom eingebauten
Bootloader gesetzt. Oder der Default ist bei neueren Chips
benutzerfreundlicher? Ich lade immer nur per Bootloader ins RAM und
starte auch auf dem Umweg.
> Im Zweifelsfall guckt man sich das Disassembly an und sucht nach> FPU-Instruktionen.
Rein zwecks der Neugierde hab' ich das gemacht. Hätte ich vielleicht
nicht tun sollen ;)
>> Ich war davon ausgegangen, dass die FPU nur dort benutzt wird, wo auch>> mit float gearbeitet wird. "Natürlich" ist es nicht so einfach.>> Der GCC ist halt clever genug auch andere Dinge, die von der FPU> profitieren, auf dieser auszuführen...
Eigentlich eine gute Sache, aber kein Vorteil ohne Nachteil...
>> Anscheinend kann man den context save sowieso nur zwischen lazy oder>> nicht umschalten (und nicht ganz abschalten).>> Nö, laut ARM gibt es drei Varianten:
o.k., wenn man das ganze Kapitel liest, schreibt STM letztlich doch
dasselbe
Bauform B. schrieb:> Das macht es nur noch schlimmer. Was würde mir ein -D helfen?
Ich meinte natürlich Flags wie -D__FPU_PRESENT=1 oder -DARM_MATH_CM4 in
deinem Makefile. Die fangen nun mal mit -D an.
Bauform B. schrieb:> Anscheinend ist der GCC wirklich schlau.
Ach! Wenn ich das richtig sehe sind die einzigen FPU-Instruktionen vpush
und vmov. Da wird anscheinend das FPU-Register s16 als zusätzliche
Datenablage missbraucht, um aufwendigere Stack-Zugriffe zu sparen.
Dieses Register ist Callee-Save, und dementsprechend wird es von der
Funktion gesichert. Das heißt, in diesem Fall gibt es sowieso kein
Problem.
Bauform B. schrieb:> trotzdem funktionieren die FPU-Befehle.
Kann es sein dass vmov und vpush trotzdem gehen?
Bauform B. schrieb:> Oder der Default ist bei neueren Chips benutzerfreundlicher
Dann wäre es aber Stromverbrauch-unfreundlicher. Schau dir doch mal
direkt im Reset_Handler das CPACR an.
Bauform B. schrieb:> Axel S. schrieb:>> Er versteht den Kommentar im Makefile nicht. Weil er das Konzept>> "context saving" nicht verstanden hat. Und wie es mit der FPU>> zusammenhängt.> Egal was das ist und wie das zusammenhängt, warum sollte man die> FPU-Register anders behandeln als alle anderen?
Wie gesagt: du hast context saving nicht verstanden.
Der Kommentar im Makefile besagt ja nur: wenn du mit hardfloat ABI
compilierst, dann werden die FPU Register genau so wie alle anderen
Register behandelt und die ISR muß sie sichern. Und der Kommentator
schreibt weiterhin, daß er es doof findet, daß das pro Interrupt so
viele CPU-Zyklen und Stack verbrät. Ja, das kann man so sehen.
Aber nein - deswegen ganz auf die FPU zu verzichten, ist auch Unsinn.
> Das heißt eben auch,> wenn ich die FPU nur in main() benutze, muss auch nichts gerettet> werden.
Nur wenn der Compiler sicher weiß, daß deine ISR keine FPU Operation
ausführen wird. Entweder direkt (im ISR Body) oder indirekt (über
Funktionsaufrufe aus der ISR heraus).
Und weil statische Codeanalyse dafür (außer in trivialen Fällen) nicht
ausreicht, versucht der Compiler gar nicht erst, das selber
rauszufinden.
Du mußt dem Compiler entweder explizit verklickern "diese ISR faßt die
FPU nicht an" oder du nutzt Tricks wie lazy FPU stacking.
Axel S. schrieb:> Und der Kommentator schreibt weiterhin, daß er es doof findet, daß das> pro Interrupt so viele CPU-Zyklen und Stack verbrät. Ja, das kann man so> sehen.
Dann ist er ein bisschen doof, wenn er einen 32 Bit Boliden mit FPU
verwendet und sich darüber beschwert, dass die FPU Register gesichert
werden.
Das ist, als ob man Ferrari fährt und jammert, dass der zu viel Sprit
braucht.
Tobias P. schrieb:> Axel S. schrieb:>> Und der Kommentator schreibt weiterhin, daß er es doof findet, daß das>> pro Interrupt so viele CPU-Zyklen und Stack verbrät. Ja, das kann man so>> sehen.>> Dann ist er ein bisschen doof, wenn er einen 32 Bit Boliden mit FPU> verwendet und sich darüber beschwert, dass die FPU Register gesichert> werden.
Das stimmt nicht so ganz. Denn tatsächlich muß der FPU-Kontext nur dann
gesichert werden, wenn die ISR die FPU auch benutzt. Bei einer ISR ist
es andererseits durchaus wahrscheinlich, daß sie die FPU nicht braucht.
Das Verhalten des Compilers, den FPU Kontext einfach immer zu sichern,
ist pessimistisch. In vielen Fällen unnötig pessimistisch. Genau
deswegen haben Leute über das Problem nachgedacht und die bereits
genannten Workarounds ausgeknobelt.
Wer sich allerdings auf den Standpunkt unseres TE stellt "nerv mich
nicht mit Details, mach einfach, daß es funktioniert", der kriegt dann
eben die langsame, sichere Variante. Keine Arme, keine Kekse!
Axel S. schrieb:> Das Verhalten des Compilers, den FPU Kontext einfach immer zu sichern,> ist pessimistisch.
Der Compiler sichert nie den ganzen FPU Content, sondern nur die
Callee-Save-Register s16-s32. Die Caller-Save-Register s0-s15 sichert
die CPU automatisch, lazy oder gar nicht, je nach Einstellung.
Man sollte also prüfen ob die ISRs direkt oder indirekt die FPU nutzen
und dann ggf. das lazy saving aktivieren, dann ist alles in Butter. Nur
wenn man echte Kontextwechsel für RTOS macht muss man etwas mehr
knobeln.
Tobias P. schrieb:> Das ist, als ob man Ferrari fährt und jammert, dass der zu viel Sprit> braucht.
Das ist eher wie: Man fährt Ferrari und beschwert sich dass der länger
zum Anlassen braucht. Außer bei extrem kurzen Strecken kommt man
trotzdem schneller ans Ziel (StVO außen vor ?).
Axel S. schrieb:> Aber nein - deswegen ganz auf die FPU zu verzichten, ist auch Unsinn.
Ganz genau! Die paar Takte Kontext Sichern sind durch die erste float
Addition wieder rein geholt.
Programmierer schrieb:> Nur wenn man echte Kontextwechsel für RTOS macht muss man etwas mehr> knobeln.
und halt im Zweifelsfall eben alle Register sichern.
Eine FPU kostet halt auch etwas, die kommt nicht umsonst. Und wenn man
so weit gekommen ist, dass die paar Takte zum Sichern der paar Register
auf einem so schnellen Rechner zu Engpässen führen, dann hat man sowieso
ein Design was auf Kante genäht ist - nicht gut. Die Zeit sollte man
schon haben.
Aber eben - jedenfalls in meinen Projekten generiert der GCC nur dann
Instruktionen zum Sichern der FPU-Register, wenn die auch benutzt
werden. Fass ich in einer Funktion/ISR kein float an, sehe ich da auch
nirgends push {s0-s15} oder ähnliches.
Nur sein push r7 streut der GCC überall hin, selbst wenn r7 nicht
verwendet wird. Weiss der Geier wieso. Aber das stört ja nicht, bei dem
CPU Takt können die paar ns nichts ausmachen.
Tobias P. schrieb:> Nur sein push r7 streut der GCC überall hin, selbst wenn r7 nicht> verwendet wird.
-fomit-frame-pointer ;-)
Tobias P. schrieb:> Und wenn man so weit gekommen ist, dass die paar Takte zum Sichern der> paar Register auf einem so schnellen Rechner zu Engpässen führen, dann> hat man sowieso ein Design was auf Kante genäht ist - nicht gut.
Ja, und wenn es mit FPU und mit Sichern zu langsam ist, dann ist es ohne
FPU definitiv zu langsam.
Tobias P. schrieb:> Aber eben - jedenfalls in meinen Projekten generiert der GCC nur dann> Instruktionen zum Sichern der FPU-Register, wenn die auch benutzt> werden.
Manchmal passiert es eben doch, s.o.
Falls sich mal jemand mit einem FPU-Problem hierher verirrt: die
Application Note 298 (ARM DAI0298A), "Cortex-M4(F) Lazy Stacking and
Context Switching" ist absolut lesenswert, mit Abstand das Beste, was
ich von ARM kenne. Einen Link gibt's leider nicht, ich hab' die mitten
in einem Haufen FAQs gefunden.
Pauschal kann ich jetzt sagen: mit viel RAM für den Stack und ohne
Multitasking kann man float überall benutzen, alles, auch verschachtelte
Interrupts funktionieren automatisch optimal. Es ist auch total ok, wenn
in reinen Integer-Funktionen FPU-Register benutzt werden. Dadurch hat
man einfach viel mehr freie Register für lau.
Man sollte nur aufpassen, dass man nicht versehentlich double benutzt,
dann wird's laaangsam. Dabei hilft die GCC-Option
-fsingle-precision-constant. Und man muss die FPU per SCB->CPACR
einschalten:
Bauform B. schrieb:> Wenn die FPU per default abgeschaltet ist, wie ARM behauptet,> gibt es dann einen fault.> Praktisch ist sie aber nicht abgeschaltet.Programmierer schrieb:> Schau dir doch mal direkt im Reset_Handler das CPACR an.
Wenn ich in der crt0 als erstes das CPACR ins RAM kopiere, sind die
cp10- und cp11-Bits
* nicht gesetzt, wenn das Programm normal aus dem Flash startet; dann
gibt es einen "Usage fault, No coprocessor".
* gesetzt, wenn ich das Programm mit dem eingebauten UART-Bootloader
ins RAM lade und starte.
In der AN2606 heißt es
1
Note: If you choose to execute the Go command, the peripheral registers
2
used by the bootloader are not initialized to their default reset
3
values before jumping to the user application. They should be
4
reconfigured in the user application if they are used.
Also passen Manual und Wirklichkeit zusammen. Wozu ein Bootloader die
FPU braucht will man garnicht wissen, aber sie sei ihm gegönnt ;)
Multitasking funktioniert auch automatisch, solange man float nur in
einer Task benutzt und diese getrennt mit -march=armv7e-m+fp übersetzt.
Der ganze Rest muss mit -march=armv7e-m übersetzt werden. Wer mehr will,
findet die Lösungen in der o.g. AN298. Aber aufpassen: Mit FPU braucht
man 108 statt 36 Byte Stack, für SVC und 2 geschachtelte Interrupts also
324 Byte nur für gerettete Register. Der Platz wird oft garnicht
gebraucht, aber immer reserviert.
Das Preis/Leistungsverhältnis von printf("%f",float) ist leider extrem
schlecht. Wegen der varargs muss float als double übergeben werden, d.h,
es wird nur für den Aufruf float->double->float per Software
konvertiert. Das dauert, kostet viel Platz und man braucht nur dafür die
libgcc. Dagegen hilft etwas wie
print_float (const char *format, float value).
Mit der GCC-Option -mfloat-abi=softfp werden für die Parameterübergabe
nur r0 bis r3 benutzt, auch für float. Mit -mfloat-abi=hard wird float
in FPU-Registern übergeben, man hat viel mehr freie Register. softfp
scheint mir eine Notlösung für fremde libs zu sein.
Bauform B. schrieb:> mit Abstand das Beste, was ich von ARM kenne.
Kennst du was schlechtes von ARM? Die ganze Doku ist extrem präzise,
vollständig und eindeutig. Da können sich die IC-Hersteller wie ST oder
TI noch ein paar ganze Laibe von abschneiden...
Bauform B. schrieb:> Dabei hilft die GCC-Option -fsingle-precision-constant
Oder immer 'f' an die Literale dran schreiben. Dann ist's portabler.
Bauform B. schrieb:> Also passen Manual und Wirklichkeit zusammen.
Ach!
Bauform B. schrieb:> softfp scheint mir eine Notlösung für fremde libs zu sein.
Das ist nützlich wenn man eine Menge Software von verschiedensten
Herstellern auf verschiedenen Plattformen nutzt. Daher wird das z.B. bei
Android verwendet. Libraries können einfach komplett mit Soft FP
kompiliert werden (wenn sie wenig float nutzen), oder dynamisch
entscheiden Soft oder Hard Float zu verwenden (für mehr number
crunching), aber das ABI bleibt immer gleich.
Fun fact: Der Linux Kernel hat Funktionen für Software Integer Division,
und prüft beim Hochfahren ob der Prozessor Hardware Integer Division
kann (udiv/sdiv). Falls ja, werden diese Funktionen mit dieser
Instruktion überschrieben (Self Modifying Code).
Hallo,
momentan versuche ich mich in das Thema einzuarbeiten, aber ich suche
ein Dokument das auch die Grundlagen erklärt, vor allem die Intention
der Teilung in Caller/Callee-Register(S0..S15 und S16..S31).
*Lazy Stacking:*
Soweit ich es verstehe wird durch das Lazy-Stacking bei einem
Kontext-Wechsel auf dem Stack der Platz für S0..S15 reserviert. Wenn der
Kontext in den gewechselt wird die FPU verwendet, werden in diesen
reservierten Bereich die Register S0..S15 gesichert. Bei einem
zurück-wechseln werden S0..S15 wieder hergestellt. Dies funktioniert bei
verschachtelten Kontextwechseln und funktioniert unabhängig von der
Verschachtelungstiefe.
Was ich nicht verstanden habe, wann S16—S31 verwendet werden und warum
nennen sich diese Caller/Callee-Register, was ist die Intention, und
wann wird das zum Sichern verwendet? Wie werden S16..S31 von der FPU
generell verwendet?
*Automatic Stacking:*
Zum „Automatic Stacking“ oder „Eagerly-Stacking“ das in z.B. der ST
AN4044 erwähnt wird, fehlt mir Dokumentation, ich weiß nicht was das ist
und wie es funktioniert. Da fehlt mir eine Definition und eine
Funktions/Implementierungsbeschreibung.
Vielen Dank.
Grüße, Seppel