Mach 30: Die Programmierung des MC68030, Teil 4

Im Atari TT serienmäßig, im STE in den vorhandenen Sockel einsetzbar, im ST durch eine Zusatzplatine nachrüstbar: -wovon hier die Rede ist? - vom mathematischen Coprozessor 68881 und dessen rund doppelt so schnellen, dennoch kompatiblen Nachfolger 68882.

Eigentlich hatte Motorola erst ab dem MC68020 die Integration eines mathematischen Coprozessors von Haus aus vorgesehen. Erst diese Prozessoren verfügen über eine Schnittstelle zur schnellen Kommunikation zwischen Haupt- und Coprozessor. Beim 68000er hingegen stellten sich lange Zeit mehrere Hürden in den Weg. Dies ist wohl mit ein Grund, weshalb sich erst in den STE-Modellen serienmäßig ein Coprozessorsockel befindet. Auch die Coprozessorkarte für die Mega STs ließ lange auf sich warten und der richtige Durchbruch ist ihr bis heute versagt geblieben.

Zum besseren Verständnis für die zu überwindenden Schwierigkeiten sei noch einmal die in (1) ausführlich besprochene Coprozessorverbindung auf Software-Ebene zusammengefaßt: Alle Prozessorbefehle, deren erstes Nibble (4 Bit) den Wert $F enthält, repräsentieren einen Coprozessorbefehl. Dabei muß es sich aber nicht zwangsläufig um einen mathematischen Coprozessor handeln. Genauer gesagt, hat Motorola hier Platz für 16 Subprozessoren gelassen. Das zweite Nibble im Befehlscode enthält nämlich immer die Coprozessor-Nummer, wobei derzeit $0 und $1 für den MMU-Coprozessor reserviert sind und $2 und $3 für den mathematischen Coprozessor. Erst nach diesen beiden Nibbles beginnt der Coprozessor-spezifische Befehlscode. Ist ein angesprochener Coprozessor nicht vorhanden oder ist der nachfolgende Befehlscode dem Coprozessor unbekannt, wird ein Interrupt ausgelöst (Line-F-Trap: $FXXX).

Aufgrund des fehlenden Coprozessor-Interfaces der 68000-Prozessoren lösen diese immer den Line-F-Interrupt aus. Sowohl die Erweiterungskarte des Mega ST sowie der Mega STE binden den Coprozessor über Hardware-Register (CIR: Coprocessor Interface Register) ein. An den Adressen $FFFA40 bis $FFFA5C befinden sich alle I/O-Register, um mit dem Hilfsarbeiter zu kommunizieren (näheres in (2)). Natürlich ist jetzt noch ein Treiber nötig, der im Falle eines Interrupts den Coprozessorbefehl via I/O-Register an den Spezialisten sendet und dort auch wieder das berechnete Ergebnis abholt. Damit sind wir auch schon beim nächsten Problem: das Betriebssystem des Atari benutzt bis zur Version »TOS 1.04« die Line-F-Traps für private Unterfunktionsaufrufe, was zwar den Vorteil hat, daß sich das TOS leichter patchen läßt (nur der Trap-Handler und die neue Unterfunktion muß neugeschrieben werden), dafür aber unter Umständen mit den Coprozessorbefehlen kollidiert. Besagter Treiber muß also noch zwischen Coprozessorbefehlen und Betriebssystemroutinen unterscheiden. Dabei kann der Treiber sich die Arbeit etwas erleichtern, wenn er berücksichtigt, daß es sich um die Einbindung des mathematischen Coprozessors handelt, daß also die Befehle nicht nur mit $F beginnen, sondern sogar mit $F2 bzw. $F3 beginnen müssen (2 bzw. 3 für mathematischen Coprozessor). Beim TT-TOS bzw. dem TOS 2.06 verzichtete Atari auf den Mißbrauch der Line-F-Traps für private Zwecke.

Bild 1. Mit dem FPCR-Register stellt man den Rundungsmodus ein und legt die gültigen Ausnahmebehandlungsroutinen fest
Bild 2. Das FPSR-Register enthält nähere Informationen zur zuletzt ausgeführten Fließkommaoperation

Befehle mit einem Operanden

   
FABS absoluter Wert (immer positiv)
FACOS Arcus Cosinus
FASIN Arcus Sinus
FATAN Arcus Tangens
FATANH Area Tangenshyperboi cus
FCOS Kosinus
FCOSH Hyperbelkosinus
FETOX ex
FET0XM1 e x -1
FGETEXP Nur Exponent der Zahl
FGETNAM Nur Mantisse der Zah
FINT Auf ganze Zahl runden
FINTRZ Auf ganze Zahl abrunden
FLOGN ln(x)
FL0GNP1 ln(x+1)
FLOG 10 Iog10(x)
FL0G2 log2(x)
FNEG Zahl negieren
FSIN Sinus
FSINH Hyperbelsinus
FSQRT Quadratwurzel
FTAN Tangens
FTANH Hyperbeltangens
FTENTOX 10x
FTWOTOX 2X

Befehle mit zwei Operanden

   
FADD Addition
FCMP Zwei Zahlen vergleichen
FDIV Division
FMOD Modulo
FMUL Multiplikation
FREM Differenz zum nächstliegenden Vielfachen
FSCALE x*FINT(2y)
FSGLDIV Division (Ergebnis im Single Real Format)
FSGLMUL Multiplikation (Ergebnis im Single Real Format)
FSUB Subtraktion

Systemsteuerbefehle

   
FTRAPcc wie TRAPcc, nur für das FPSR
FSAVE FPU-Zustand sichern (wichtig für Taskwechsel)
FRESTORE FPU-Zustand vom Speicher laden

Datentransportbefehle

   
FMOVE Speicher/Fließkomma-Register laden
FMOVEM wie MOVEM nur für Fließkomma-Register
FMOVECR Konstanten wie pi oder e in Register laden

Steuerbefehle

   
FBcc Sprung bei erfüllter Bedingung (wie Bcc)
FDBcc wie DBcc
FNOP No operation (wie NOP)
FScc wie Scc
FTST Zahl testen und FPSR-Register setzen (wie TST)

Tabelle 1. Der umfangreiche Befehlssatz des Koprozessors 68881/2 läßt keine Wünsche offen.

Zustände der Bedingungsabfragen 1)

     
EQ SEQ Gleich
NE SNE Ungleich
F SF Immer falsch
T ST Immer richtig
GE OGE Gleich oder größer
GL OGL Ungleich
GLE OR kein NAN
GT OGT Größer
LE OLE Kleiner oder gleich
LT OLT Kleiner
NGE UGE 1
NGL UEQ 1 Gleiche Bedingungen wie zuvor, nur muß
NGLE UN 1 zusätzlich das NAN-Bit gesetzt sein.
NGT UGT 1 Damit lassen sich auch NANs mit einer
NLE ULE 1 Zahl vergleichen.
NLT ULT 1

Die Mnemonics der erste Spalte lösen eine Exception aus, wenn ein NAN beim Vergleich beteiligt war. Wfeiter wird dann das BSUB-Bit des FPSR gesetzt.

Tabelle 2. Auch Fließkommazahlen lassen sich mit dem 68881/2 bequem vergleichen

An dieser Stelle bietet sich ein Blick in die Zukunft an. Wie in (1) erwähnt, ist ein mathematischer Coprozessor im 68040 schon integriert, doch eben nur ein Coprozessor und nicht etwa »der« 68882. Genauer gesagt handelt es sich hier um einen kräftig abgespeckten 68882er. Da sich innerhalb eines Prozessors die Register schneller umschaufeln lassen, ist der 68040 bei den vorhandenen Befehlen deutlich schneller als das 68030/68882-Gespann. Die fehlenden Befehle ließen sich wieder über den Line-F-Trap emulieren, um auf diese Weise kompatibel zu bleiben. Motorola bietet einen solchen Treiber an, der soweit möglich die vorhandenen FPU-Befehle mitbenutzt. Der so emulierte 68882 soll nach Motorolas Worten bei gleicher Taktfrequenz sogar schneller sein als das Original.

Da die Programmierung der FPU in Assembler keine den Aufwand rechtfertigenden Vorteile bringt, wollen wir hier nicht die einzelnen Befehle erläutern, sondern geben nur eine kurze Zusammenfassung der Befehle in Tabelle 1 und Tabelle 2 wieder. Zum einen bringt

eine in Assembler geschriebene optimale FPU-Register-Verwaltung angesichts der enormen Ausführungszeiten der einzelnen Coprozessorbefehle nur wenig Zeitersparnis und zum anderen beherrschen heute alle Hochsprachen die Coprozessorunterstützung. Um den Hochsprachen aber nicht restlos ausgeliefert zu sein, und die Früchte der Compiler auf eventuelle Makel hin überprüfen zu können, mag ein Blick in den Assembler-Debugger dennoch hilfreich sein.

Die Mnemonic der FPU orientiert sich weitgehend am 68030-Befehlssatz:

Label: Befehl.<Format> <Register/Adresse>,<Register/Adresse>

Sogar die vielfältigen Adressierungsarten des 68030 bringen den Rechenspezialisten nicht in Verlegenheit. Ausgestattet mit acht 96 Bit breiten Fließkommaregistern (FP0 bis FP7) benutzt der Zahlenjongleur bei Coprozessorbefehlen natürlich diese als Daten register. Bedingt durch die weiteren Datenformate (Bild 3) stellt man den Befehlen ».S« für einfache Genauigkeit (Single Precision), ».D« für doppelte Genauigkeit (Double Precision), ».E« für erweiterte Genauigkeit (Extended Precision) und ».P« für das gepackte Stringformat (Packed Decimal String) nach. Anders als bei den Integerberechnungen des Hauptprozessors (.B:Byte, .W:Word und .L:Long) verändern auch die kleineren Datenformate (also z.B. Single) das komplette Fließkommaregister. Denn, egal mit welchem Datenformat man die FPU füttert, sie konvertiert den Wert immer in ein eigenes Format, bevor dieser in ein Fließkommaregister gelangt.

Die Gründe für die Benutzung eines eigenen Zahlenformates sind vielfältig. Zum einen ist das eigene Format das genaueste (96 Bit). Es spielt also keine Rolle mit welchen Zahlenformat man den Prozessor füttert, intern rechnet er immer im 96-Bit-Format und erst das Ergebnis wird dann dem Wunsch entsprechend wieder zurückkonvertiert. Auf diese Weise fallen die Rundungsfehler geringer aus. Andererseits enthält dieses Format weitere Steuer-Bits, wie zum Beispiel das Overflow-Bit oder das Sticky-Bit, was bei größeren Berechnungen, also immer dort, wo Zwischenergebnisse anfallen, zu nochmals genaueren Berechnungen führt und außerdem nach der Berechnung noch jeden Rundungsmodus erlaubt.

Wurde aufgrund einer Berechnung eine Zahl so klein, daß deren 63-Bit-Mantisse Null ist, das Ergebnis aber dennoch von Null verschieden sein soll, kommt das Sticky-Bit ebenfalls zum Einsatz. Ist dieses Bit gesetzt signalisiert es einen sehr kleinen, in der 63-Bit-Auflösung nicht mehr darstellbaren, aber von Null verschiedenen Wert. Mit diesem Wert läßt sich, wenn auch in begrenztem Umfang, sogar weiterrechnen.

Außerdem unterscheiden die Vergleichsfunktionen (z.B. »FCMP« in Kombination mit »FBcc«) zwischen Null und diesem sehr kleinen Wert.

Der dritte Grund für ein eigenes Datenformat liegt im einfacheren Weiterrechnen, weil zum Beispiel der Exponent schon im Zweierkomplement vorliegt.

Neben vielen Konstanten wie »pi« oder der Eulerschen Zahl, arbeitet der Rechenknecht auch mit 47- Unendlich oder NANs (»Not A Number« z.B.: Null durch Null). Bei komplexeren Berechnungen braucht man so nicht jede einzelne Rechenoperation auf unsinnige Ergebnisse hin zu überprüfen, da sich NANs bzw. 47-Unendlich durch die einzelnen Operationen weitervererben, und somit immer auch das Schlußresultat keine »echte« Zahl darstellt.

Anders als bei Fließkomma-Bibliotheksfunktionen spielt das Umrechnen in die verschiedenen Datenformate beim Coprozessor zeitlich keine Rolle, denn dieser beherrscht die Formatumwandlung sozusagen nebenbei. Während der Befehlsanalyse kann die FPU parallel dazu die Zahlen konvertieren.

Eine große Entlastung für die Textausgabe von Fließkommazahlen bringt das »Packed Decimal Real Format«. Dieses 96-Bit-Format beinhaltet den Exponenten (3-4 Ziffern) wie die Mantisse (17 Ziffern) im BCD-Format. Die Umwandlung in einen ASCII-String ist somit ein Leichtes.

Sollte diese Artikelreihe Ihr Interesse am 68030/ 68882-Duo geweckt haben, finden Sie weitere Informationen in (3) und (4). (ah)

Bild 3. Diese vier Fließkommadatenformate versteht der 68881/2. Dennoch rechnet er intern mit einem anderen Format.

Literaturhinweise:

(1) TOS-Magazin, Mach 30, Teil 1. Ausgabe 8/92, Seite 88ff

(2) ATARI Profibuch. Jankowski/Rabich/Reschke, 11. Auflage, SYBEX-Verlag, S. 1331ff

(3) 68030 Assembly Language Reverence, Steve Williams. Addison-Wesley

(4) Motorola Semiconductors. »MC68030 Enhanced 32-Bit Microprocessors User’s Manual« und »MC68881/68882 Floating Point Coprocessors User's Manual«. Prentice Hall


Jürgen Lietzow
Aus: TOS 11 / 1992, Seite 50

Links

Copyright-Bestimmungen: siehe Über diese Seite