-
Die Erfindung betrifft ein Verfahren zum Umsetzen von mindestens zwei Befehlen mit Basisregister-relativer Adressierung bei einer Emulation eines für einen Ursprungsprozessor erstellten Programmcodes auf einem Zielprozessor, wobei der Ursprungsprozessor Adressen einer ersten Länge von n Bit zur Adressierung in einem zyklischen Adressraums einsetzt und der Zielprozessor Adressen einer Länge von m Bit zur Adressierung einsetzt und wobei m größer ist als n.
-
Bei der Einführung neuerer Prozessorsysteme und – architekturen ist es wünschenswert, die für ältere Prozessorsysteme entwickelten Programme weiter nutzen zu können. Zu diesem Zweck werden Emulatoren eingesetzt, die ältere Prozessorsysteme auf den neueren nachahmen und ermöglichen, ein für einen älteren Prozessor, auch Ursprungsprozessor genannt, erstellten Programmcode auf dem neueren Prozessor, auch Zielprozessor genannt, auszuführen. Emulatoren sind üblicherweise selbst Programme, die auf dem Zielprozessor ausgeführt werden und Befehlsfolgen des Programmcodes für den Ursprungsprozessor dynamisch in Befehlsfolgen für den Zielprozessor transformieren, um diese dann direkt auf dem Zielprozessor effizient auszuführen.
-
Im Rahmen der Übersetzung der Befehle müssen auch Adressoperatoren von Befehlen, zum Beispiel von Ladebefehlen und von Sprungbefehlen, korrekt übersetzt werden. Bei einer in vielen Prozessorarchitekturen vorgesehenen und häufig eingesetzten Adressierungsmethode wird eine Adresse durch die Angabe eines Basisregisters und eines Distanzwertes definiert. Die Adresse errechnet sich zur Laufzeit als Summe des Inhalts des angegebenen Basisregisters und des Distanzwertes. Befehle, die von dieser Adressierungsmethode Gebrauch machen werden auch als Befehle mit Basisregisterrelativer Adressierung genannt. Abkürzend ist auch eine Bezeichnung als „Basisregister-relativer Befehl” gebräuchlich.
-
Häufig ist der mittels eines solchen Basisregister-relativen Befehls erreichbare Adressraum in seiner Größe kleiner als der von einem Register aufgrund der Bitbreite des Registers maximal adressierbare Adressraum. Bei Prozessoren vom Typ S/390 der Firma IBM sind beispielsweise Register mit einer Bitbreite von 32 Bit vorhanden. Demgegenüber kann wahlweise ein Adressraum mit Adressen einer Länge von 24 oder von 31 Bit gewählt werden, so dass der mögliche Adressraum Adressen in einem Bereich von 0 bis 224 – 1 beziehungsweise von 0 bis 231 – 1 umfasst. Der Adressraum ist dabei zyklisch ausgestaltet, derart dass berechnete Adressen, die über den Rand des Adressraums hinausgehen, wieder auf den Adressraum abgebildet werden (wrap-around). Dieses kann zum Beispiel dadurch geschehen, dass die Adresse, die sich aus dem Inhalt des Basisregisters plus Distanzwert ergibt, ganzzahlig durch die Größe des Adressraums dividiert wird, und der bei dieser Division auftretende Rest als effektive Adresse, die dann im Adressraum liegt, zur Adressierung eingesetzt wird. Eine solche Berechnung wird modulo-Operation oder wrap-around Berechnung genannt.
-
Wegen der im Allgemeinen größeren Adressierungsbreiten bei neueren Prozessorarchitekturen unterstützen neuere Prozessoren die kleineren Adressräume älterer Prozessorsysteme nicht zwangsläufig. Unterschiedlich große Adressräume können bei der Emulation von Programmcode jedoch problematisch sein. Eine berechnete Adresse, zum Beispiel bei einem Lade- oder Sprungbefehl, die außerhalb des Adressraums des Ursprungsprozessors liegt, jedoch im größeren Adressraum des Zielprozessors dargestellt werden kann, unterscheidet sich im emulierten Programm somit von der unter Berücksichtigung des wrap-around bestimmten effektiven Adresse auf dem Ursprungsprozessor. Um bei einer Emulation dennoch die Adresse korrekt zu berechnen, ist es notwendig, zusätzliche Befehle in den übersetzten Programmcode einzuarbeiten, durch die die kleinere Größe des Adressraums im Ursprungsprozessor berücksichtigt wird. Dieses kann beispielsweise dadurch erfolgen, dass zunächst eine Adresse in einem temporären Register als Summe des Inhalts des Basisregisters und des Distanzwertes in einem ersten Befehl bestimmt wird und in einem zweiten Befehl dann das wrap-around in den kleineren Adressraum dadurch nachgebildet wird, dass eine Operation vom Typ modulo 2n auf den Wert des temporären Registers angewendet wird, wobei n die Länge der Adressen im kleineren Adressraum des Ursprungsprozessor angibt. Danach kann ein Sprung oder ein Datenzugriff über die im temporären Register stehende Adresse ausgeführt werden. Auf diese Weise wird der Basisregister-relative Befehl in der Emulation zwar semantisch korrekt nachgebildet, es werden jedoch für jeden Befehl zwei zusätzliche Programmbefehle bei der Emulation benötigt, wodurch diese verlangsamt wird.
-
Es ist daher eine Aufgabe der vorliegenden Erfindung, ein Verfahren zum Umsetzen von Basisregister-relativen Befehlen bei einer Emulation anzugeben, bei dem die unterschiedliche Größe der Adressräume von Ursprungs- und Zielprozessor korrekt berücksichtigt wird und das gleichzeitig eine effektive Emulation mit möglichst wenigen hinzugefügten Befehlen ermöglicht.
-
Diese Aufgabe wird durch ein Verfahren und einen Emulator mit den Merkmalen der unabhängigen Ansprüche gelöst. Vorteilhafte Ausgestaltungen und Weiterbildungen sind in den jeweiligen abhängigen Ansprüchen angegeben.
-
Im Folgenden wird das erfindungsgemäße Verfahren anhand von Ausführungsbeispielen mit Hilfe von Figuren näher erläutert.
-
Es zeigen:
-
1 ein Flussdiagramm eines Verfahrens zum Umsetzen von zwei Befehlen mit Basisregister-relativer Adressierung,
-
2 eine Pseudocodedarstellung des in 1 gezeigten Verfahrens,
-
3 bis 8 weitere Ausführungsbeispiele von Verfahren zum Umsetzen von Basisregister-relativen Befehlen in Pseudocodedarstellung.
-
Im Rahmen der folgenden Figurenbeschreibung werden Basisregister des Ursprungsprozessors mit einem R als Bezugszeichen bezeichnet und Register des Zielprozessors mit einem r angegeben. Ein Index kann eingesetzt sein, um verschiedene Register ri zu unterscheiden. Der Einfachheit halber ist mit dem Bezugszeichen R, r sowohl das jeweilige Register bezeichnet, als auch in Formeln oder Berechnungen der jeweilige Registerinhalt. Distanzwerte für den Ursprungsbeziehungsweise Zielprozessor tragen ein D beziehungsweise ein d als Bezugszeichen. Verschiedene Distanzwerte werden durch Angabe eines Index unterschieden, zum Beispiel D1, D2.
-
Ein in eckige Klammern gesetzter Ausdruck bezeichnet eine von einem jeweiligen Prozessor automatisch vorgenommene Bestimmung einer effektiven Adresse zu der von dem Ausdruck angegebenen Adresse. An der Klammer kann in einem solchen Fall die Länge einer Adresse in dem jeweiligen Adressraum, für den die effektive Adresse berechnet wird, angegeben sein. Der Ausdruck [216 + 5]n=16 bedeutet demnach, dass der Adresswert 216+5 zu einer effektiven Adresse in einem 16 Bit breiten zyklischen Adressraum umgesetzt wird. In dem gegebenen beispielhaften Fall tritt also ein wrap-around ein, sodass der gegebene Ausdruck zu einer effektiven Adresse von 5 führt.
-
Die 1 zeigt ein Flussdiagramm eines ersten Ausführungsbeispiels eines Verfahrens zum Umsetzen von Befehlen mit Basisregister-relativer Adressierung. Das gezeigte Verfahren wird im Rahmen einer Emulation eines Programmcodes, der für einen Ursprungsprozessor erstellt wurde, auf einem Zielprozessor ausgeführt. Die Emulation kann dabei die Befehle im ursprünglichen Programmcode einzeln nacheinander jeweils in Programmcode für den Zielprozessor umsetzten und direkt ausführen (Interpretation). Zur Beschleunigung der Emulation, insbesondere wenn eine mehrfache Ausführung von Programmteilen zu erwarten ist, wie zum Beispiel bei Schleifenstrukturen, kann eine dynamischen Übersetzung von zumindest Teilen des Programmcodes erfolgen. Dabei werden jeweils häufig auszuführende Teile des Ursprungsprogramms dynamisch, d. h. während der Emulationszeit, in Programmcode für den Zielprozessor übersetzt, dieser im Arbeitsspeicher des Zielprozessors abgelegt und schließlich unter der Kontrolle des Emulators direkt auf dem Zielprozessor gegebenenfalls mehrfach ausgeführt.
-
Der Ursprungs- und der Zielprozessor haben unterschiedlich große Adressräume. Zur vereinfachten Angabe der Größe von Adressräumen wird im Folgenden der Begriff Breite beziehungsweise Bitbreite nicht nur für Register sondern auch für Adressräume benutzt. Ein Adressraum einer Breite von n Bit bedeutet dabei, dass im Adressraum Adressen einer Länge von n Bit zur Adressierung eingesetzt werden. In allen folgenden Ausführungsbeispielen hat der Ursprungsprozessor einen Adressraum mit n Bit Breite und der Zielprozessor einen Adressraum mit m Bit Breite, wobei m größer ist als n. Weiterhin ist der Adressraum des Ursprungsprozessors zyklisch, der des Zielprozessors kann, muss aber nicht zyklisch sein. Im Folgenden wird jedoch von dem üblicheren Fall ausgegangen, dass der zweite Adressraum ebenfalls zyklisch ist.
-
In einem ersten Schritt S1 wird von dem Emulator als Befehl im ursprünglichen Programmcode ein erster Basisregister-relativer Befehl mit dem Basisregister R und dem Distanzwert D1 eingelesen. Zur Umsetzung dieses Befehls zur Ausführung auf dem Zielprozessor wird in einem Schritt S2 zunächst ein Register r des Zielprozessors mit dem Inhalt des Basisregisters R geladen. Dieses Register r führt somit das Basisregister R nach. Im Allgemeinen wird das Basisregister R innerhalb eines Programms nicht verändert. Der Schritt S2 wird somit im Rahmen der Emulation eines Programms nur einmal erforderlich, üblicherweise im Zusammenhang mit dem ersten auftretenden Basisregister-relativen Befehl.
-
In einem anschließenden Schritt S3 wird die Summe aus dem Inhalt des Registers r und dem Distanzwert D1 des im Schritt S1 eingelesenen Befehls gebildet und dieses einem Register r1 des Zielprozessors zugewiesen. Alternativ zur im Flussdiagramm dargestellten einfachen Summenbildung r + D1 kann der Inhalt des Registers r1 auch als effektive Adresse im m-Bit breiten Adressraums des Zielprozessors berechnet werden, also als [r + D1]m. Insbesondere wenn auch der zweite Adressraum zyklisch ausgestaltet ist, stehen meist spezielle Prozessorbefehle zum Laden eines Registers mit einem effektiven Adresswert bereit.
-
Im sich anschließenden Schritt S4 wird der Inhalt des Registers r1 auf einen mit einer Adresslänge von n, also einem Adressraum der Größe des Ursprungsprozessors, projiziert. Diese Projektion erfolgt durch Restwertbildung nach Division durch den Wert 2n, was üblicherweise als modulo-Operation bezeichnet wird.
-
In einem anschließenden Schritt S5 wird schließlich auf dem Zielprozessor der emulierte erste Befehl mit der in den Schritten S3 und S4 bestimmten projizierten Adresse als ein Befehl mit indirekter Adressierung über das Register r1 ausgeführt.
-
Im weiteren Verlauf der Emulation wird in einem Schritt S6 ein zweiter Basisregister-relativer Befehl des Programmcodes des Ursprungsprozessors eingelesen. Dieser zweite Befehl bezieht sich wiederum auf das Basisregister R, von dem zusätzlich angenommen wird, dass sich sein Inhalt seit dem Schritt S1 nicht verändert hat, und einen Distanzwert D2.
-
In einem folgenden Schritt S7 wird eine zweite Adresse als Summe der projizierten Adresse, die noch im Register r1 abgelegt ist, und dem zweiten Distanzwert D2 abzüglich des ersten Distanzwertes D1 gebildet. Die so berechnete zweite Adresse wird in einem Register r2 abgelegt. Wie beim Schritt S3 kann auch hier der Inhalt des Registers r2 als effektive Adresse im m Bit breiten Adressraums des Zielprozessors erfolgen.
-
In einem folgenden Schritt S8 wird schließlich auf dem Zielprozessor im emulierten Programm der emulierte zweite Befehl mit der zweiten Adresse, die im Register r2 abgelegt ist, als Befehl mit indirekter Adressierung ausgeführt.
-
Bei der Beschreibung der 1 wird davon ausgegangen, dass im Rahmen eines Interpretationsmodus die übersetzten Befehlssequenzen auch gleich ausgeführt werden. Wie bereits angegeben, ist es alternativ dazu ebenso möglich, die Übersetzung auszuführen und den ermittelten Programmcode zunächst abzuspeichern, um ihn danach einfach oder bevorzugt mehrfach ohne erneute Übersetzung beziehungsweise Interpretation ausführen zu können (dynamische Übersetzung).
-
Verglichen mit bekannten Verfahren, bei denen bei jedem Basisregister-relativen Befehl die (kleinere) Bitbreite des Adressraums des Ursprungsprozessors durch eine Addition und die Anwendung der modulo-Operation berücksichtigt werden muss, braucht dieses beim vorgestellten Verfahren nur bei der Umsetzung des ersten Befehls zu erfolgen (Schritte S3 und S4). Die effektive Adresse für den zweiten Befehl wird nur über eine einfache Addition bestimmt (Schritt S7). Die Ausführungszeit der Emulation wird durch das Einsparen der modulo-Operation verringert. Dieses gilt insbesondere, wenn der zweite Befehl aufgrund einer Schleife mehrfach auszuführen ist oder wenn weitere Befehle im Ursprungsprogrammcode folgen, deren effektive Adresse analog zu der des zweiten Befehls bestimmt werden kann.
-
Für die Distanzwerte D in Befehlen mit Basisregister-relativer Adressierung beim Ursprungsprozessor ist üblicherweise ein nur beschränkter Wertebereich zulässig, dessen Größe oft deutlich kleiner als die des Adressraums ist. Werden die Grenzen des erlaubten Wertebereichs mit min und max angegeben, ergibt sich min ≤ D ≤ max. Bei einem Prozessor vom Typ S/390 der Firma IBM beträgt der Wertebereich beispielsweise 0 ≤ D ≤ 4095 (12 Bit).
-
Der zweite Befehl im Schritt S8 kann auf dem Zielprozessor besonders effektiv als Basisregister-relativer Befehl mit dem Register r1 als Basis und der Differenz von d = (D2 – D1) aus Schritt S7 als Distanzwert realisiert werden. Aufgrund dieser Differenzbildung können somit negative Werte für den Distanzwert d auftreten. Damit ergibt sich als Vorraussetzung für das dargestellte Verfahren, dass der Zielprozessor bei Basisregister-relevanten Sprüngen negative Werte für den Distanzwert d zulässt, und zwar im Bereich min – max ≤ d ≤ max – min. Bei den meisten neueren Prozessoren ist dieses jedoch gegeben, so beispielsweise bei Prozessoren der Serie X86 der Firma Intel, die uneingeschränkt Distanzwerte d im Wertebereich –231 ≤ d ≤ 231 – 1 zulassen.
-
Weiterhin setzt das dargestellte Verfahren voraus, dass von dem eigentlichen Adressraum des Ursprungsprozessors mit Adressen von 0 bis 2n – 1 nur Adressen im Bereich von 0 bis 2n – 1 – (max – min) von dem emulierten Programm benutzt werden. Eine solche Einschränkung kann beispielsweise durch eine Konvention erreicht werden, der zufolge der benutzte Adressraum von Anwendungsprogrammen entsprechend beschränkt wird. Eine andere Möglichkeit besteht im Einsatz von Systemprogrammen, über die diese Einschränkung vorgegeben oder überwacht wird.
-
Ohne die Einschränkungen kommt es bei Adressen im ausgeschlossenen Bereich zu einer fehlerhaften Berechnung, da im Ursprungsprozessor bereits ein wrap-around eintreten würde, beim Zielprozessor jedoch nicht. Da die Differenz (max – min) jedoch üblicherweise deutlich kleiner als die Größe des Adressraums von 2n ist, stellt dieses in der Praxis keine nachteilige Beschränkung dar. Bei dem zuvor als Beispiel genannten System S/390 von IBM beträgt (max – min) 212 Byte = 4 kB (Kilobyte). Demgegenüber beträgt die Größe des unterstützte Adressraum 224 Byte = 16 MB (Megabyte) oder 231 Byte = 2 GB (Gigabyte). Von dem ursprünglich zur Verfügung stehenden Adressraum dieser Größenordnung wird lediglich ein Bereich von 4 KB den Anwendungsprogrammen nicht mehr zugänglich. Dieser obere Speicherbereich eines Adressraums ist üblicherweise zudem meist für das Betriebssystem reserviert und kann ohnehin von Anwendungsprogrammen nicht genutzt werden. Dieses macht sich die Erfindung zunutze.
-
Unter der Voraussetzung des eingeschränkten Adressraums muss für einen erfolgreichen Speicherzugriff die im Schritt S3 berechnete effektive Adresse im Bereich 0 ≤ r1 ≤ 2n – 1 – (max – min) liegen. Es wird angenommen, dass im Schritt S3 eine effektive Adresse berechnet wird, also r1 = [D2 – D1 + r1] = D2 – D1 + r1 modulo 2m. Zum Nachweis, dass die Übersetzung der Adressoperanden die Semantik des Ursprungsprozessors korrekt nachbildet, werden folgende Fälle unterschieden:
-
a) 0 ≤ D2 – D1 + r1 ≤ 2n – 1 – (max – min):
-
Der Ursprungsprozessor berechnet die effektive Adresse modulo 2n, der Zielprozessor modulo 2m. Da D2 - D1 + r1 < 2n < 2m berechnen beide Prozessoren die gleiche effektive Adresse, nämlich D2 – D1 + r1.
-
b) D2 – D1 + r1 < 0:
-
Der Ursprungsprozessor berechnet die effektive Adresse zu 2n + D2 – D1 + r1 ≥ 2n + max – min. Dies liegt außerhalb des eingeschränkten Adressraums, so dass der Ursprungsprozessor die Ausführung wegen Adressierungsfehler unterbrechen würde. Der Zielprozessor berechnet die effektive Adresse zu 2m + D2 – D1 + r1 ≥ 2n + max – min. Dies liegt ebenfalls außerhalb des eingeschränkten Adressraums, so dass auch der Zielprozessor die Ausführung wegen Adressierungsfehler unterbrechen würde. Beide Prozessoren reagieren also identisch mit Unterbrechung wegen Adressierungsfehler. Falls der Ursprungsprozessor die den Adressierungsfehler verursachende effektive Adresse der Unterbrechungsbehandlung in einem Spezialregister zur Verfügung stellt, dann muss die Emulation auf dem Zielprozessor diese zum Fehler führende effektive Adresse f vor Aufruf der Unterbrechungsbehandlung durch modulo 2n korrigieren.
-
c) D2 – D1 + r1 > 2n – 1 – (max – min):
-
Aufgrund der Beschränkungen für r1, D1 und D2 gilt 2n > D2 – D1 + r1, so dass beide Prozessoren die gleiche effektive Adresse berechnen, nämlich D2 – D1 + r1. Diese liegt aber außerhalb des eingeschränkten Adressraums, so dass beide Prozessoren die Programmausführung wegen Adressierungsfehler unterbrechen.
-
Damit ist gezeigt, dass die erfindungsgemäße Übersetzung der Adressoperanden in diesem Fall die Semantik des Ursprungsprozessors exakt auf dem Zielprozessor nachbildet.
-
In der 2 ist das Verfahren gemäß 1 in einer Pseudocodedarstellung wiedergegeben, beispielhaft mit Ladebefehlen mit Basisregister-relativer Adressierung. Bei dieser und allen folgenden Figuren sind jeweils auf der linken Seite die umzusetzenden Befehle im Programmcode des Ursprungsprozessors angegeben. Programmcodeabschnitte, im Folgenden auch kurz Programmblöcke genannt, für den Ursprungsprozessor sind mit einem mit „U” beginnenden Bezugszeichen versehen. Auf der rechten Seite ist jeweils der für den Zielprozessor transformierte Programmcode dargestellt. Zu Kennzeichnung von Programmblöcken für den Zielprozessor dienen hier mit „Z” beginnende Bezugszeichen, wobei korrespondierende Abschnitte für den Ursprungsbeziehungsweise den Zielprozessor Bezugszeichen mit der gleichen Ziffernfolge tragen. In allen dargestellten Fällen wird davon ausgegangen, dass eine Übertragung des Inhalts des Registers R des Ursprungsprozessors in ein Register r des Zielprozessors bereits erfolgt ist.
-
Zur Umsetzung eines ersten Basisregister-relativen Ladebefehls U21 im Ursprungsprogrammcode wird für den Zielprozessor der Programmcodeabschnitt Z21 generiert. Der Ladebefehl U21 (ld – load) bezieht sich auf den Speicherinhalt an einer Adresse, die durch den Inhalt des Basisregisters R und den Distanzwert D1 spezifiziert ist. Wie durch die eckige Klammer angedeutet ist, wird die Adresse als effektive Adresse berechnet, wobei die Breite des zyklischen Adressraum n Bit beträgt.
-
In dem Programmcodeabschnitt Z21 für den Zielprozessor wird zunächst im Zielprozessor ein Register rp mit dem Wert [D1 + r] geladen (lea – load effective address). Durch diesen speziellen Ladebefehl wird die Summe von D1 und dem Inhalt von r als effektive Adresse bestimmt, also als Adresse im zyklischen Adressraum der Breite m des Zielprozessors.
-
In dem folgenden Befehl (and – logical AND-Operation) wird die modulo 2n-Operation aus dem Schritt S4 der 1 durch ein bitweises logisches UND realisiert, indem alle Bits mit einer höheren Wertigkeit als das n-te Bit im Register auf Null werden.
-
In dem letzten Befehl des Programmcodeabschnitts Z21 wird schließlich ein Register r1 mit dem Speicherinhalt an der berechneten projizierten Adresse, die in dem Register rp gespeichert ist, geladen.
-
Im Ursprungscode erfolgt anschließend ein zweiter Basisregister-relativer Ladebefehl U22. Im entsprechenden Programmcodeabschnitt Z22 für den Zielprozessor wird analog zu den Schritten S7 und S8 der 1 ein Basisregister-relativer Ladebefehl generiert, bezogen auf das Basisregister rp und mit einem Distanzwert D2 – D1. Falls im Programmcode für den Zielprozessor nicht die Möglichkeit besteht, eine Differenzberechnung gleich innerhalb des Ladebefehls durchführen zu lassen, kann ein zweites Register eingesetzt erden, in dem zunächst die Differenz D2 – D1 zwischengespeichert wird, um sie dann dem Ladebefehl als Operand übergeben zu können. Verglichen mit der Umsetzung des ersten Ladebefehls im Programmcodeabschnitt Z21 wird im Abschnitt Z22 in jedem Fall der and-Befehl zur modulo 2n eingespart.
-
In 3 ist ein analoges Beispiel mit Basisregister-relativen Sprungbefehlen statt Ladebefehlen dargestellt.
-
Zur Umsetzung von zwei Basisregister-relativen Sprungbefehlen U31 und U32 im Ursprungsprogrammcode werden für den Zielprozessor die Programmcodeabschnitte Z31 und Z32 generiert. Die Sprungbefehl in U31 und U32 (jmp – jump) bezieht sich auf das Basisregister R und die Distanzwerte D1 beziehungsweise D2.
-
Wiederum wird zunächst in dem Programmcodeabschnitt Z31 für den Zielprozessor in einem Register rp die Sprungadresse des ersten Sprungbefehl semantisch korrekt (d. h. auf den Adressraum des Ursprungsprozessors projiziert) im Adressraums des Zielprozessors bestimmt und anschließend der erste Sprung zu dieser Adresse ausgeführt. Der zweite Sprung kann dann mithilfe der ersten Sprungadresse als Basisregisterwert und einem Distanzwert von D2 – D1 ausgeführt werden, wodurch für den zweiten Sprung wieder die für eine direkt semantisch korrekte Umsetzung erforderliche modulo-Operation eingespart werden kann.
-
Die bisher dargestellten Ausführungsbeispiele betrafen lineare Programmabläufe. Den Programmabschnitten U22 und U32 der 2 bzw. 3 ist beispielsweise zwingend der Programmabschnitt U21 vorausgegangen. Entsprechend werden die Programmabschnitte Z21 und Z31 ebenso sicher vor den entsprechenden Programmabschnitten Z22 und Z32 ausgeführt, wodurch sichergestellt ist, dass das Register rp auf den richtigen Wert, nämlich der auf den ersten Lade- bzw. Sprungbefehl bezogenen Adresse, gesetzt ist. In den folgenden Ausführungsbeispielen werden Fälle mit Programmverzweigung behandelt, bei denen dieses nicht mehr zwingend gegeben ist.
-
Bei dem in 4 in Pseudocode dargestellten Verfahren zur Umsetzung von Basisregister-relevanten Ladebefehlen sind im Programmcode für den Ursprungsprozessor zwei alternativ auszuführende Programmblöcke U41 und U42 vorgesehen, von denen aus nach den Ladebefehlen jeweils ein Sprung zu einer Sprungmarke M erfolgt, woraufhin ein dritter Programmblock U43 ausgeführt wird. Im dritten Programmblocks U43 ist ein dritter Ladebefehl auszuführen. Der dritte Ladebefehl steht im Programmcode nicht zwingend genau an der Adresse der Sprungmarke M, er kann nachfolgend jedoch nicht nach einer weiteren Programmverzweigung – im Programmblock U43 positioniert sein.
-
Alle Ladebefehle beziehen sich auf das Register R als Basisregister. Der erste Ladebefehl im Programmblock U41 weist den Distanzwert D1, der zweite im Programmblock U42 den Distanzwert D2 und der dritte Ladebefehl im Programmblock U43 den Distanzwert D3 auf.
-
Bei der Umsetzung des ersten Programmblocks U31 in einen Programmblock Z31 wird analog zur Umsetzung von Programmblock U21 in Programmblock Z21 die Ladeadresse unter Berücksichtigung der Größe des Adressraums bei dem Ursprungsprozessor semantisch korrekt berechnet und in dem Register rp gespeichert. Entsprechend erfolgt die Umsetzung des dritten Ladebefehls im Programmblock U43, der sich ja ebenfalls auf das Basisregister R bezieht und einen Distanzwert D3 aufweist, analog zur Umsetzung des Programmblocks U22 in den Programmblock Z22 in 2.
-
Zur Umsetzung des zweiten Ladebefehls im Programmblock Z42 wird nun berücksichtigt, dass im umgesetzten Programmblock U43 davon ausgegangen wird, dass im Register rp bereits der Distanzwert D1 des ersten Ladebefehls aus Programmblock U41 eingegangen ist. Vor dem Sprung zur Sprungmarke M muss das Register rp folglich so gesetzt werden, wie es bei einem Sprung aus Programmblock Z41 gesetzt wäre. Der dritte Ladebefehl in Programmblock Z43 wird dann in jedem Fall korrekt berechnet, unabhängig davon, von wo aus (Z41 oder Z42) das Programm zum Programmblock Z43 gelangt ist. Dieses wird dadurch erreicht, dass im Register rp zunächst semantisch korrekt die Ladeadresse des zweiten Ladebefehis ermittelt wird und der entsprechende Ladebefehl in das Register r1 ausgeführt wird. Bevor der Sprung zur Sprungmarke M dann ausgeführt wird, wird das Register rp mittels eines add-Befehls um den Unterschied der Sprungweiten D1 – D2 korrigiert.
-
Damit berechnet sich die Adresse für den dritten Ladebefehl im Programmblock Z43 als: rp + D3 – D1. Dabei ist rp = (r + D2) + (D1 – D2), wobei der Wert in der ersten Klammer aus dem ersten Befehl des Programmblocks Z42 (lea...) folgt und der Wert der zweiten Klammer aus dem vierten Befehl, dem Korrekturbefehl (add...), stammt. Eingesetzt ergibt sich die Sprungadresse als: rp + D3 – D1 = (r + D2) + (D1 – D2) + D3 – D1 = r + D3, was genau die Zieladresse des dritten Sprungs ist.
-
Durch die Übernahme der Adresse in das Register rp und ihre Korrektur sind zwar zwei zusätzliche Befehle im Programmcodeblock Z42 erforderlich, dafür wird die vereinfachte Umsetzung des Ladebefehls im dritten Programmblock U43 ermöglicht, bei der zeitaufwändige Befehle eingespart werden. Die gilt insbesondere, wenn der Ladebefehl in U43 mehrfach ausgeführt wird, zum Beispiel innerhalb einer Programmschleife.
-
5 zeigt eine bezüglich der Programmverzweigung analoge Situation wie 4. Aus zwei Programmblöcken U51 und U52, erfolgt je ein Sprung zu einer gemeinsamen Sprungmarke M in einem dritten Programmblock U53. Im Unterschied zum Ausführungsbeispiel von 4 sind Basisregister-relative Ladebefehle jedoch nur in den Programmblöcken U51 und U53 vorhanden, nicht aber in dem Programmblock U52.
-
Hier erfolgt ein Sprung zur Sprungmarke M in beiden Fällen, also aus den Programmblöcken Z51 und Z52, so, dass in dem Register rp bereits die Distanzweite D3 relativ zum Basisregister r enthalten ist. Die Zieladresse des im Zielcodeabschnitt Z53 auszuführenden Ladebefehls wird somit bereits vorab bestimmt und der dritte Ladebefehl als Ladebefehl mit vorbestimmter absoluten Adresse rp ausgeführt.
-
Um dieses zu gewährleisten, wird zum einen im Programmblock Z51 zunächst die semantisch korrekte Umsetzung der ersten Ladeadresse im Register rp vorgenommen und der entsprechende Ladebefehl zum Laden eines ersten Registers ausgeführt. Vor dem Sprung zur Sprungmarke M wird der Inhalt des Registers rp mittels eines add-Befehls um den Unterschied der Sprungweiten D3 – D1 korrigiert. Damit wird die Berechnung der Adresse des Ladebefehls gemäß Programmblock Z43 der 4 gewissermaßen vorweggenommen.
-
Zum anderen wird im Programmblock Z52 vor Ausführung des Sprungs zur Marke M die Ladeadresse des direkt mittels des gegebenen Distanzwertes D3 des Ladebefehls aus Programmblock U53 semantisch korrekt bestimmt und im Register rp abgelegt.
-
Verglichen mit einer konventionellen direkten semantischen korrekten Umsetzung der Ladebefehle der Programmblöcke U51 und U53 wird bei der hier vorgestellten Umsetzung auf dem Weg von Z52 nach Z53 zwar kein Befehl eingespart, wohl aber auf dem Weg von Z51 zu Z53. Die Einsparung ist analog zu der auf dem Weg Z42 zu Z43 beim Ausführungsbeispiel der 4.
-
6 zeigt, wiederum im Pseudocode, eine Umsetzung von Basisregister-relativen Ladebefehlen in einem Programmablauf, bei dem nach Erreichen der Sprungmarke M eine weitere Programmverzweigung auftritt.
-
Wie beim Ausführungsbeispiel der 5 erfolgt aus zwei alternativ auszuführenden Programmblöcken U61 und U62 ein Sprung zu (oder eine Programmfortführung bei) einer gemeinsamen Sprungmarke M in einem dritten Programmblock U63, wobei nur auf einem Programmpfad, im Programmblock U61, ein Basisregister-relativer Ladebefehl mit Distanzwert D1 auszuführen ist.
-
Im dritten Programmblock U73 ist eine Programmverzweigung vorgesehen, entweder in einen vierten Programmblock U64 oder in einen fünften Programmblock U65. Jeder dieser Blöcke weist einen Basisregister-relativen Ladebefehl auf, mit den Distanzwerten D4 beziehungsweise D5.
-
Die Umsetzung folgt prinzipiell nach dem gleichen Muster wie die Umsetzung im Ausführungsbeispiel der 5. Es wird bereits beim Sprung zur Marke M im Register rp der Distanzwert eines der weiteren Ladebefehle berücksichtigt, im vorliegenden Beispiel der des Ladebefehls im Programmabschnitt U64 mit dem Distanzwert D4. Die Umsetzung in den Zielcodeabschnitten Z61, Z62 und Z64 ist somit genau analog zu denen in den Blöcken Z51, Z52 und Z53 des Ausführungsbeispiels der 5. Entsprechend ergeben sich Vorteile dieser Umsetzung gegenüber einer konventionellen Umsetzung nur auf dem Pfad, der von dem Programmblock Z61 startet. Im Zielcodeabschnitt Z65 erfolgt die Umsetzung der Ladeadresse ebenfalls konventionell über eine semantisch korrekte Transformation, weswegen sich auf einem Pfad, der zum Programmcodeabschnitt Z65 geht, in keinem Fall ein Vorteil ergibt. Damit profitiert bei diesem Ausführungsbeispiel nur ein Pfad, nämlich der vom Programmblock Z61 zum Programmblock Z64.
-
Bei einer Emulation eines komplexen Programms ist es jedoch bekannt und üblich, Programmflussanalysen durchzuführen, um die relativen Häufigkeiten zu bestimmen oder abzuschätzen, mit denen verschiedene Pfade zur Ausführungszeit eines Programms vorgenommen werden. Die ermittelten relativen Häufigkeiten können einem Emulator bereitgestellt werden, so dass gerade die am häufigsten beschrittenen Pfade durch die zuvor beschriebenen Verfahren optimiert werden. Im Beispiel der 6 würde also gerade der häufiger ausgeführte der beiden Programmblöcke Z64 oder Z65 so optimiert, dass die Umsetzung des Ladebefehls durch einen einzelnen Befehl ausgeführt werden kann (wie hier im Falle des Blocks Z64).
-
Grundsätzlich können bekannte Programmflussanalysen zudem eingesetzt werden, um zur Implementierung der Erfindung verschiedenen Situationen im Programmfluss unterscheiden zu können.
-
7 zeigt eine alternative Ausführungsform des Verfahrens für die gleiche Ausgangssituation bezüglich des ursprünglichen Programmcode wie beim Beispiel der 6.
-
Im Unterschied zum Ausführungsbeispiel der 6 wird beim Sprung zur Marke M im Register rp jedoch nicht der Distanzwert eines der weiteren Ladebefehle berücksichtigt, sondern ein maximaler Distanzwert DMAX = max – min, wobei min und max die Grenzen des erlaubten Wertebereichs für Distanzwerte beim Ursprungsprozessor darstellen. Die Programmblöcke Z71 und Z72 entsprechen somit genau den Blöcken Z61 und Z62, wobei lediglich der Distanzwert D4 durch den maximalen Distanzwert DMAX ersetzt ist.
-
In den Programmblöcken Z74 und Z75 kann dann in beiden Fällen eine Bestimmung der Ladeadressen zu den Distanzwerten D4 und D5 durch einen Basisregister-relativen Ladebefehl mit dem Register rp als Basisregister erfolgen.
-
Wenn bei gegebenem Inhalt des Basisregisters R bei einer Umsetzung eines Basisregister-relativen Befehls ein wrap-around auftreten kann, dann sicher bei der Annahme des maximalen Distanzwertes DMAX. Die Vorwegnahme dieses Falles in Programmblock Z72 stellt somit die korrekte Adressbestimmung in beiden nachfolgenden Programmblöcken Z74 und Z75 sicher. Bei Beispiel der 6 war dieses nur für den in Block Z62 behandelten Falls des nachfolgenden Blocks Z64 gegeben, weswegen für den Block Z65 eine vollständige semantisch korrekte Adressberechnung erfolgen musste. Verglichen mit dem Beispiel der 6 wird somit eine Einsparung nicht nur auf dem Pfad Z71 -> Z74, sondern auch auf dem Pfad Z71 -> Z75 erreicht.
-
Eine diesem Beispiel analoge Vorgehensweise, bei der grundsätzlich der maximale Distanzwert DMAX der Bestimmung der projizierten Adresse im mitgeführten Register rp zugrunde gelegt wird, ist dabei nicht auf den in den 6 und 7 dargestellten Programmablauf beschränkt, sondern lässt sich bei allen denkbaren Programmabläufen realisieren, beispielsweise auch im Zusammenhang mit den in den 2 bis 5 gezeigten Ausführungsbeispielen.
-
Eine weitere Ausgestaltung der Erfindung betrifft Programme, die mehrere Adressräume gleichzeitig verwenden. Bei den zuvor bereits erwähnten Prozessoren S/390 der Firma IBM ist beispielsweise eine solche Nutzung mehrerer Adressräume möglich. Dabei gibt es zu jedem Basisregister R ein Adressraum-Auswahlregister (access register) A, dessen Inhalt eine Kennung des auszuwählenden Adressraums enthält. In 8 ist links ein Basisregister-relativer Ladebefehl mit dem Basisregister R, dem Distanzwert D1 und dem Adressraum-Auswahlregister A in einem Programmblock U81 für den Ursprungsprozessor angegeben.
-
Falls auf dem Zielprozessor parallel genutzte Adressräume nicht bekannt sind, er dafür aber einen einzigen ausreichend großen Adressraum (zum Beispiel mit 64 Bit langen Adressen, also m = 64) bereitstellt, dann kann der Ladebefehl wie in dem Programmblock Z81 gezeigt für den Zielprozessor umgesetzt werden.
-
Die ersten beiden Befehle im Programmcodeblock Z81 für den Zielprozessor dienen der Bestimmung einer projizierten Adresse im Register rp, genau wie zum Beispiel im Programmcodeblock Z21 der 2. Der danach zusätzlich eingefügte Befehl lädt den Inhalt eines Registers a, in dem das Adressraum-Auswahlregister A für die Emulation nachgeführt wird, in ein Register rx. Der folgende Befehl (shl rx, n + 1 – shift left) schiebt den (binären) Inhalt des Registers rx um (n + 1) Bits nach links. Dieses entspricht dem Aufaddieren von (a·2n+1) auf die primitive effektive Adresse, die Adressräume nicht berücksichtigt. Der Basisregister-relative Ladebefehl wird dann mit rp als Basisregister und rx als Distanzwert umgesetzt. Die einzelnen parallelen Adressräume des Ursprungsprozessors werden so in getrennte Bereiche des Adressraums beim Zielprozessor abgebildet. Bei den Adressen auf dem Zielprozessor belegen sie nebeneinander Stellen (Bits) unterschiedlicher Wertigkeit.
-
Falls auch diese Adressräume, jeder für sich, beschränkt werden, so dass jeweils nur die Adressen im Bereich a·2n+1 ... a·2n+1 + 2n – 1 – (max – min) zulässig sind, und falls die (ggf. kompakt in a kodierten) Adressraumkennungen begrenzt sind, so dass 0 < a·2n+1 < 2m – (max – min) gilt, dann gelten alle vorherigen Überlegungen sinngemäß auch für die mit dem Inhalt von A unterschiedenen Adressräume. Die durch die anmeldungsgemäßen Verfahren einsparbaren Befehle bei der Übersetzung eines auf einen ersten Basisregister-relativen Sprung folgenden zweiten Basisregister-relativen Sprungs umfassen dann auch den ld- und shl-Befehl, so dass insgesamt 4 Befehle eingespart werden können.