68040 Nimmt Falsche Verzweigung von Wenn Else

8

Irgendwelche guten 68k Assembly Programmierer da draußen ?? Ich verwende einen kommerziellen Green Hills Compiler für ein Motorola 68040 und ich sehe ein sehr seltsames Verhalten aus dem Code. Manchmal führt der Code einen if / else-Vergleich durch und nimmt den falschen Zweig. Zum Beispiel:

%Vor%

Der Code wird manchmal zu d !? Ich habe festgestellt, dass, wenn dieser Fehler auftritt, immer ein bestimmter ISR den Vergleich unterbricht. Ich habe mir die generierte Baugruppe für die ISR angeschaut und ein paar Dinge gesehen, die für mich keinen Sinn ergeben. Zunächst sieht es so aus, als ob die Floating-Point-Statusregister FPSR, FPCR und FPIAR nicht im ISR gespeichert sind. Dies würde erklären, warum die If / ens den falschen Zweig nehmen. Das FPSR-Register wird verwendet, um das Ergebnis eines Vergleichs zu bestimmen, und wenn dieses Register in einem ISR überschrieben wird, kann die Verzweigung den falschen Pfad nehmen. Im Folgenden finden Sie die vom Compiler generierte Entry- und Exit-Assembly:

%Vor%

Ich habe das Referenzhandbuch des Programmiergeräts durchgesehen und kann nichts finden, was darauf hindeutet, dass FSAVE oder FMOVEM die FP-Statusregister speichert. Tatsächlich habe ich einen Kommentar gesehen, der andeutet, dass dies nicht der Fall ist: "Der FSAVE speichert nicht die Modellregister des Programmierers der Gleitkommaeinheit; er speichert nur den unsichtbaren Teil des Gerätes des Benutzers." Also habe ich eine eigene Assembly hinzugefügt, um die Register am Anfang der ISR zu speichern und sie am Ende wiederherzustellen, und dies hat die Performance dramatisch verbessert, aber ich sehe immer noch einige Probleme. Nachfolgend sind die Ergänzungen, die ich gemacht habe; Die Sicherungsvariablen werden im C-Code als unsigned long eingegeben:

%Vor%

Es fiel mir schwer zu glauben, dass der Compiler tatsächlich einen Fehler hatte, indem ich die Register nicht speicherte. Also habe ich angefangen, die Werte von FPx und Dx zu betrachten, um zu sehen, dass sie auf den richtigen Wert wiederhergestellt sind, und es sieht so aus, als wären sie nicht. Aber ich bin nicht 100% ig, dass ich den Assembly-Code nicht mit meinen Änderungen verschmiere. Es folgt der Code, den ich hinzugefügt habe, um die Register zu speichern. Die Debug-Variablen werden als unsigned longs eingegeben:

%Vor%

Kurz gesagt sind meine Fragen,

1) gibt es ein Problem mit der generierten Assembly, da es die FPSR-, FPCR- und FPIAR-Register nicht speichert und

2) speichere ich die Werte der Register richtig, wenn ich die ISR betrete und verlasse?

Es wäre großartig, wenn ich einen anderen Compiler hätte, mit dem ich vergleichen könnte. Leider kann ich keinen Debugger an den Code anhängen. Ich habe viel Erfahrung in C / C ++ / C # / Java / Python / PHP / etc., Aber ich bin weit von einem Assembly-Experten.

Irgendwelche Ideen werden geschätzt!

    
Samuel 14.11.2011, 05:46
quelle

2 Antworten

2

Ich habe seit den Tagen der 68020 keine 68K-Programmierung gemacht, aber ich werde versuchen, in die relevanten grauen Materie und / oder Web-Ressourcen zu gelangen: -)

Beantworten Sie Ihre spezifischen Fragen:

  

Gibt es ein Problem mit der generierten Assembly, indem die FPSR-, FPCR- und FPIAR-Register nicht gespeichert werden?

Ich würde ja sagen, aber nur, wenn es etwas in der ISR gibt, das sie betrifft . Während das unwahrscheinlich erscheint (ISRs sollen schnell sein, also würde ich nicht erwarten, dass sie sich mit Fließkomma-Dingen herumärgern), scheint die Umsicht darauf hinzudeuten, dass eine Routine alles speichert, was sie gerade macht. Chance, dass Code kann es ändern.

Nachdem ich das gesagt habe, bin ich mir nicht sicher, wie Sie die ISR kompilieren (oder ob es überhaupt Ihr Code ist). Es kann sein, dass ein spezielles Flag erforderlich ist, damit der Compiler mehr Code zum Speichern anderer Dinge generiert.

  

Speichere ich die Werte der Register richtig, wenn ich die ISR betrete und verlasse?

Auch das hängt davon ab. Es sieht gut aus, aber ich wäre ein wenig besorgt über die Verwendung bestimmter Speicherorte wie fpiar_backup oder debug26 , es sei denn, Sie sind sehr sicher, dass der ISR selbst nicht anfällig für einen anderen Interrupt ist.

Wenn die Interrupts während der ISR-Verarbeitung deaktiviert sind, sind Sie wahrscheinlich in Ordnung.

Außerdem hängt es davon ab, was diese ISR bedient. Die Dokumente scheinen anzuzeigen, dass alle ISRs, die Gleitkommaprobleme behandeln, immer das fsave zuerst tun sollten.

Es wäre hilfreich, wenn Sie die Werte dieser debugX -Positionen auslassen würden, damit Sie sehen können, welche Werte sich zwischen dem ISR-Eintrag und dem ISR-Wert unterscheiden. Und stellen Sie sicher, dass sie die richtige Größe haben. Und sei vorsichtig, dass du sie nicht in der Mitte des ISR ansiehst, wo sie mit Sicherheit anders aussehen werden.

    
paxdiablo 14.11.2011 06:24
quelle
2

Zukünftig wurde das Problem tatsächlich darauf bezogen, dass der Compiler den Wert von Fließkomma-Statusregistern nicht speicherte. Ich habe Green Hills kontaktiert und ihnen zufolge ist dies kein Fehler, und die Speicherung des Wertes der Register liegt in der Verantwortung des Programmierers. Was mir komisch ist, weil der Compiler alle anderen internen Register speichert, einschließlich des internen Zustands der FPU, warum mit den Statusregistern aufhören?

Kurz gesagt, das Speichern des Werts des FPSR und des FPIAR, die beim Verlassen des ISR eintreten, wird das Problem beheben. Folgendes sollte den Trick machen:

%Vor%     
Samuel 15.11.2011 16:19
quelle