Ken Shirriff hat die Tangensberechnung des Gleitkomma-Koprozessors Intel 8087 rekonstruiert. Intel brachte den Chip 1980 für den IBM PC und andere Systeme auf den Markt. Eine Tangensberechnung dauerte damit etwa 90 Mikrosekunden. Auf dem 8086 benötigte die emulierte Berechnung rund 13.000 Mikrosekunden.
FPTAN:
#1039 st(0) -> tmpA store argument in tmpA
#1040 stackPtr-- check if room on stack to push result
#1041 stack overflow?
#1042 jmp #1022 if tmp empty/special/overflow/div exit if bad argument or stack overflow
#1043 jmp #1045 if tmpA:tag ZERO is argument 0?
#1044 except:precision precision exception except for 0
#1045 expconst 0x3ff0 Test if exponent >= -16
#1046 adder: tmpA:exp + 0 cin=1 argument exponent + 1
#1047 expConst -> Breg
#1048 adder: sumreg:frac - Breg cin=1 subtract -15
#1049 jmp #1061 if adder pos CORDIC if exponent >= -16
#1050 expconst 0x3fff non-CORDIC path:
#1051 tmpA:exp -> Breg check original exponent
#1052 expConst -> tmpB:frac against exponent 0
#1053 adder: tmpB:frac - Breg cin=1 subtract
#1054 sumreg:frac -> expConv 3fff - exp (i.e. -exp unbiased)Shirriff entfernte den Chipdeckel mit einem Meißel und untersuchte den Die unter einem Mikroskop. Das zentrale Mikrocode-ROM enthält 1.648 Mikroinstruktionen mit jeweils 16 Bit. Im unteren Teil des Dies liegen der Gleitkomma-Datenpfad, ein Exponenten-ROM, ein Konstanten-ROM, der Shifter, der Addierer, die Stack-Register, temporäre Register und ein 16-Bit-Schieberegister für die CORDIC-Entscheidungen.
CORDIC entwickelte Jack Volder 1956 für den digitalen Navigationsrechner des Convair B-58 Hustler. Der Algorithmus stellt einen Winkel durch einen Vektor dar und führt Rotationen aus, deren Tangens jeweils einer Zweierpotenz entspricht. Diese Rotationen brauchen deshalb nur Schiebeoperationen, Additionen und Subtraktionen. Die Winkelwerte liegen in einer Tabelle. Der für den B-58 eingesetzte CORDIC-II-Rechner war ein serieller 30-Bit-Rechner mit 198,4 kHz. Er wog 134 Pfund, enthielt 2.498 Transistoren und 4.265 Dioden und speicherte etwa 39 Kilobyte auf einer Trommel. Eine CORDIC-Operation dauerte 5 Millisekunden.
Der 8087 verwendet eine Variante, die jeden Tabellenwinkel auswählt oder überspringt. Zunächst reduziert er den Eingabewinkel mit bis zu 16 CORDIC-Schritten. Das liefert ungefähr 16 Bit Genauigkeit. Für den kleinen Restwinkel verwendet der Chip die rationale Approximation 3x/(3-x2). Ihr Fehler wächst proportional zu x4. Bei einem Rest kleiner als 2-16 bleibt der Fehler unter 2-64. Der Prozessor hält Zähler und Nenner als getrennte Vektorkoordinaten vor und spart dadurch eine abschließende Division. FPTAN liefert X als Nenner und Y als Zähler. Intel bezeichnete dieses Ergebnis als Partial Tangent.
Der Mikrocode gliedert die Berechnung in CORDIC-Pseudodivision, rationale Approximation und CORDIC-Pseudomultiplikation. Bei der Pseudodivision vergleicht der Chip den Restwinkel mit den gespeicherten Winkeln und schreibt jeweils 1 oder 0 in das Schieberegister. Für das Beispiel 0,95 Radiant entsteht die Folge [1,0,0,1,0,1,0,1,0,0,1,0,0,1,1,1]. Die Rotationen werden später in umgekehrter Reihenfolge angewandt. Der kleinste Winkel kommt zuerst, damit Rundungsfehler geringer bleiben. Der Vektor verlässt dabei den Einheitskreis, doch Y/X ergibt weiterhin den Tangens.
Der FPTAN-Mikrocode beginnt bei Adresse #1039. Zuerst prüft er ungültige Eingaben und einen möglichen Stack-Überlauf. Bei einem Exponenten von -64 oder kleiner gibt er die Eingabe unverändert zurück und legt 1 als Nenner ab. Bei einem Exponenten von -17 oder kleiner entfällt CORDIC, und die Ausführung springt direkt zur rationalen Approximation. Exponenten von -1 bis -16 führen über den CORDIC-Pfad. Intel dokumentierte den Eingabebereich 0<θ<π/4. Der Code behandelt den Wert null ausdrücklich und funktioniert offenbar auch bei größeren Werten, wobei die Genauigkeit nahe π/2 sinkt. Das Beispiel 0,95 liegt außerhalb des dokumentierten Bereichs.
Für die Approximation muss der Restwinkel quadriert werden. Der 8087 verwendet dafür eine Radix-4-Booth-Multiplikation, die zwei Bits pro Schritt verarbeitet. Die Hardware führt in einer von Mikrocode gesteuerten Schleife 32 Additionen aus. Die Konstante 3 entsteht durch spezielle Transistorlogik. Die übrigen Operationen verwenden Schieben und Addieren. Eine teure Division findet nicht statt.
Intern speichert der 8087 Zahlen im 80-Bit-Format Temporary Real. Es enthält ein Vorzeichenbit, einen 15-Bit-Exponenten und eine 64-Bit-Signifikand. Der Exponenten-Bias beträgt 16383. Ein Exponent von 1 wird daher als 0x4000 gespeichert, -16 als 0x3fef. Die acht Stack-Register tragen die Zustände zero, valid, special oder empty. tmpA und tmpB sind 80-Bit-Register. tmpC besitzt kein Vorzeichen, keinen Exponenten und kein Tag-Bit. Es verwendet eine 68-Bit-Signifikand sowie Überlauf-, Guard-, Round- und Sticky-Bits.
Der Mikrocode arbeitet mit integerähnlichen Festkommawerten. Die Exponenten existieren dabei nur implizit. Schiebeoperationen halten die relevanten Bits während der Pseudodivision und Pseudomultiplikation im nutzbaren Bereich. Teile des Datenpfads verwenden einen 68 Bit breiten Shifter und einen 69 Bit breiten Addierer. Eine Schiebe- oder Additionsoperation benötigt normalerweise zwei Mikroinstruktionen. Das B-Register des Addierers ist vom Register tmpB getrennt.
Bei der Eingabe 0,95 entfallen 33 Prozent der Zeit auf die CORDIC-Pseudodivision. Die rationale Approximation benötigt 15 Prozent, überwiegend für das Quadrieren. Die Pseudomultiplikation beansprucht 47 Prozent. Weitere 5 Prozent entfallen auf Verwaltungsaufwand. FPTAN benötigt typischerweise 450 Taktzyklen. Je nach Eingabe sind 30 bis 540 Zyklen möglich.
Intel wechselte beim Pentium zu polynomialen Approximationen, weil dessen Multiplizierer diesen Ansatz praktikabel machte. Moderne Intel-Bibliotheken wie MKL und SVML verwenden polynomiale Verfahren mit SIMD-Instruktionen. x87-Operationen und 80-Bit-Gleitkommawerte spielen in 64-Bit-Software nur noch eine geringe Rolle.
Bei der Rekonstruktion halfen Shirriff Mitglieder des Opcode Collective, besonders Smartest Blob und Gloriouscow. Die Gruppe wandelte ROM-Aufnahmen in Mikrocode-Daten um und setzte maschinelles Lernen zur Klassifizierung der ROM-Zellen ein. Die rekonstruierten 8087-Daten liegen im granite-Repository auf GitHub.




Kommentare
Noch keine Kommentare — schreib den ersten.
Starte die Diskussion
Kein Konto, kein Passwort nötig — gib einfach deine E-Mail-Adresse ein, wir senden dir einen einmaligen Anmelde-Link. Beim ersten Mal bist du damit automatisch angemeldet.
Deine Bewertung wird nach der Anmeldung automatisch übernommen.
Schau in dein Postfach
Wir haben einen Anmelde-Link an … gesendet. Öffne ihn auf diesem Gerät — dieser Tab meldet dich automatisch an.
Nichts angekommen? Wirf einen Blick in den Spam-Ordner — und markiere die Mail dort als „Kein Spam“, dann landet sie künftig direkt im Postfach.