MMIX LOGO

MMIX Instruction Set (German)

Table of Content

Content

Die MMIX Instruktionen

Die hier gegebenen Beschreibungen sind dem MMIX Buch entnommen. Für eine ausführlichere Beschreibung in Deutsch wird auf das Buch verwiesen.

Inhalt

Arithmetik mit ganzen Zahlen

Die arithmetischen Befehle

Name:
ADD $X,$Y,$ZADD $X,$Y,Z
SUB $X,$Y,$ZSUB $X,$Y,Z
MUL $X,$Y,$ZMUL $X,$Y,Z
DIV $X,$Y,$ZDIV $X,$Y,Z

Spezifikation:
ADD: s($X) ← s($Y) + s($Z)
SUB: s($X) ← s($Y) - s($Z)
MUL: s($X) ← s($Y) * s($Z)
DIV:
s($X) ← { ⌊s($Y) / s($Z)⌋ falls $Z ≠ 0
0 falls $Z = 0

also der ganzzahlige Anteil des Quotienten

s(rR) ← { s($Y) mod s($Z) falls $Z ≠ 0
s($Y) falls $Z = 0

also der Divisionsrest im Spezialregister rR.

Alle Befehle sind in zwei Varianten vorhanden: Einmal kommt der zweite Operand aus dem Register $Z und einmal ist der Operand Z Teil des Befehls selbst. Man nennt dies einen Direktoperanden oder immediate Operanden.

Zeit:

ADD:
SUB:
MUL: 10υ
DIV: 60υ

Beschreibung:

Arithmetische Befehle für Rechnungen mit vorzeichenbehafteten Zahlen. Diese Befehle können einen Überlauf erzeugen, was ebenso wie eine Division durch Null in Register rA festgehalten wird.

Siehe auch:

Arithmetische Befehle für vorzeichenlose Berechnungen.

Arithmetische Befehle für vorzeichenlose Berechnungen

Name:
ADDU $X,$Y,$ZADDU $X,$Y,Z
SUBU $X,$Y,$ZSUBU $X,$Y,Z
MULU $X,$Y,$ZMULU $X,$Y,Z
DIVU $X,$Y,$ZDIVU $X,$Y,Z

Spezifikation:

ADDU: u($X) ← (u($Y) + u($Z)) mod 264
SUBU: u($X) ← (u($Y) -u($Z)) mod 264
MULU:u(rH $X) ← u($Y) * u($Z)
DIVU:
u($X) ← { ⌊u(rD $Y) / u($Z)⌋ falls u($Z) > u(rD)
u(rD) sonst

u(rR) ← { u(rD $Y) mod u($Z) falls u($Z) > u(rD)
u($Y) sonst

Das Spezialregister rD wird dem Register $Y vorangestellt und man erhält so eine 128-Bit Zahl. Diese wird durch $Z dividiert. Das Ergebnis wird in $X gespeichert. Der Rest bei der Divison wird in rR gespeichert.

Falls jedoch rD ≥ $Z, so ist das Ergebnis der Division größer als 264 und die Division wird nicht durchgeführt. In diesem Falle wird rD in $X gespeichert und $Y in rR. In Donald Knuth's "The Art of Computer Programming", Volume 2, "Seminumerical Algorithms", Kapitel 4.3.1 wird erklärt wie man mit dieser Instruktion die Division von Zahlen mit mehr als 128 Bit bewerkstelligt.

Alle Befehle sind in zwei Varianten vorhanden: Einmal kommt der zweite Operand aus dem Register $Z und einmal ist der Operand (Z) Teil des Befehls selbst. Man nennt dies einen Direktoperanden oder immediate Operanden.

Zeit:
ADDU: 1υ
SUBU: 1υ
MULU: 10υ
DIVU: 60υ

Beschreibung:

Arithmetische Befehle für Rechnungen mit vorzeichenlosen Zahlen. Sie erzeugen keinen Überlauf, selbst nicht bei Division durch Null.

Siehe auch:

Arithmetische Befehle für vorzeichenbehaftete Berechnungen.

Die Befehle NEG und NEGU

Name:
NEG $X,Y,$Z NEG $X,Y,Z
NEGU $X,Y,$ZNEGU $X,Y,Z

Spezifikation:
NEG: s($X) ← Y - s($Z)
NEGU: u($X) ← (Y - u($Z))mod264

Zeit:

Beschreibung:

Y ist eine nichtnegative Konstante, üblicherweise 0. Der Befehl dient zum negieren von $Z. Falls Y den Wert 0 hat, darf der Wert weggelassen werden.

Vergleichsbefehle

Name:
CMP $X,$Y,$Z CMP $X,$Y,Z
CMPU $X,$Y,$ZCMPU $X,$Y,Z

Spezifikation:

CMP:
s($X) ← { - 1 falls s($Y) < s($Z)
0 falls s($Y) = s($Z)
+ 1 falls s($Y) > s($Z)
CMPU:
s($X) ← { - 1 falls u($Y) < u($Z)
0 falls u($Y) = u($Z)
+ 1 falls u($Y) > u($Z)

Zeit:

Beschreibung:

Vergleicht zwei ganze Zahlen miteinander. Das Ergebnis kann als Grundlage für bedingte Verzweigungen oder begingte Zuweisungen verwendet werden.

Arithmetik mit Gleitkommazahlen

Befehle für Umwandlung von Gleitkommazahlen

Name:
FLOT $X,$Z FLOT $X,Z
FLOTU $X,$ZFLOTU $X,Z
FIX $X,$Z FIXU $X,$Z

Spezifikation:
FLOT: f($X) ← s($Z)
FLOTU: f($X) ← u($Z)
FIX: s($X) ← int(f($Z))
FIXU: u($X) ← (int(f($Z)))mod264

Zeit:

Beschreibung:

Wandlung des Formats der Interndarstellung zwischen ganzen Zahlen und Zahlen im Gleitkommaformat. Optional kann als Y-Operand einer der Rundungsmodi ROUND_OFF, ROUND_UP, ROUND_DOWN oder ROUND_NEAR angegeben werden.

Befehle zum Rechnen mit Gleitkommazahlen

Name:

FADD $X,$Y,$Z
FSUB $X,$Y,$Z
FMUL $X,$Y,$Z
FDIV $X,$Y,$Z
FREM $X,$Y,$Z
FSQRT $X,$Z
FINT $X,$Z

Spezifikation:
FDIV: f($X) ← f($Y) ∕ f($Z)
FREM: f($X) ← f($Y) rem f($Z)
y rem z ist definiert als y-nz, wobei n die zu y∕z nächstgelegene ganze Zahl ist bzw. die nächstgelegene gerade Zahl im Fall von Mehrdeutigkeiten.
FINT: f($X) ← f(int(f($Z)))
FSQRT: f($X) ← f($Z)12

Zeit:

4υ für FADD, FSUB, FMUL, FREM und FINT
40υ für FDIV und FSQRT

Beschreibung:

FADD, FSUB, FMULund FDIV: arithmetische Befehle für Gleitkommazahlen. FINT rundet zu einer ganzen Zahl (liefert aber im Gegensatz zu FIX als Ergebnis wieder eine Zahl im Gleitkommaformat). Die Befehle FINT und FSQRT können als Y-Operand optional einen der Rundungsmodi ROUND_OFF, ROUND_UP, ROUND_DOWN oder ROUND_NEAR erhalten.

Befehle für Vergleiche von Gleitkommazahlen

Name:

FCMP $X,$Y,$Z
FEQL $X,$Y,$Z
FUN $X,$Y,$Z
FCMPE $X,$Y,$Z
FEQLE $X,$Y,$Z
FUNE $X,$Y,$Z

Spezifikation:
FCMP:
s($X) ← { - 1 falls f($Y) < f($Z)
0 falls f($Y) = f($Z)
+1 falls f($Y) > f($Z)
FEQL:
s($X) ← { 1 falls f ($Y) = f($Z)
0 sonst

Es sei Nε(u) = {x| |x - u|≤ ε 2e-q}, wobei q der Exzess und e = E + q die Summe aus Exponent und Exzess der Gleitkommadarstellung der Zahl u sind. Damit:
FCMPE:
s($X) ← { - 1 falls f($Y) < Nε(f($Z)) und Nε(f($Y)) < f($Z)
0 falls f($Y) ∈ Nε(f($Z)) oder f($Z) ∈ Nε(f ($Y))
+1 falls f($Y) > Nε(f($Z)) und Nε(f($Y)) > f($Z)
FEQLE:
s($X) ← { 1 falls f($Y) ∈ Nε(f($Z)) und f($Z) ∈ Nε(f ($Y))
0 sonst

Der Wert von ε muss dazu im Spezialregister rE hinterlegt sein.

FUN:
s($X) ← { 1 falls entweder $Y oder $Z keine echten Zahlen (NaN) sind,
0 sonst
FUNE:
s($X) ← { 1 falls entweder $Y, $Z oder rE keine echten Zahlen (NaN) sind,
0 sonst

Beschreibung:

Vergleiche von Gleitkommazahlen. Eine ausführliche Beschreibung findet sich z.B. in [mmix-doc].

Konvertieren von Short Floats

Name:

SFLOT $X,$Z bzw. SFLOT $X,Z
SFLOTU $X,$Z bzw. SFLOTU $X,Z

Spezifikation:
SFLOT: f($X) ← f(T) ← s($Z)
SFLOTU: f($X) ← f(T) ← u($Z)

Zeit:

Beschreibung:

Konvertiert eine ganze Zahl in ein short (32-Bit) float. Dabei bezeichnet T eine 32-Bit-Zwischengröße, in welche die Zahl zuerst gewandelt wird. Dabei kann eine Rundung auftreten; erst nach dieser Rundung wird die Erweiterung auf 64 Bit durchgeführt. Im Y-Feld kann bei Bedarf, genau wie beim Befehl FLOT, spezifiziert werden, wie gerundet wird.

Siehe auch:

FLOT und FLOTU.

Bits und Bytes

Befehle für bitweise logische Verknüpfungen

Name:
AND $X,$Y,$Z AND $X,$Y,Z
OR $X,$Y,$Z OR $X,$Y,Z
XOR $X,$Y,$Z XOR $X,$Y,Z
ANDN $X,$Y,$ZANDN $X,$Y,Z
ORN $X,$Y,$Z ORN $X,$Y,Z
NAND $X,$Y,$ZNAND $X,$Y,Z
NOR $X,$Y,$Z NOR $X,$Y,Z
NXOR $X,$Y,$ZNXOR $X,$Y,Z

Spezifikation:

In der folgenden Tabelle steht a für ein Bit des Quelloperanden $Y, b steht für das entsprechende Bit des Quelloperanden $Z bzw. Z und in den anderen Spalten sind die Ergebnisse der entsprechenden Operationen angegeben.

abAND(&)OR(|)XOR(ˆ) NAND( ˜ & )NOR(˜ |)NXOR(˜ ˆ) ANDN(\)ORN(|˜ )
00 0 0 0 1 1 1 0 1
10 0 1 1 1 0 0 1 1
01 0 1 1 1 0 0 0 0
11 1 1 0 0 0 1 0 1

Zeit:

Beschreibung:

Mit einer bitweisen Verknüpfung werden die 64 Bit der beteiligten Operanden Bit für Bit miteinander verknüpft, entsprechend der durch den Befehl angegebenen Verknüpfungsvorschrift. Wenn wir zwei Bit a und b betrachten, so gibt es vier mögliche Wertekombinationen, die diese annehmen können (a = b = 0, a = 1, b = 0 sowie umgekehrt a = 0, b = 1 und schließlich a = b = 1). Eine bitweise Operation ordnet jeder dieser Möglichkeiten jeweils den Wert 0 oder 1 zu.

Befehle zum Schieben von Bitmustern

Name:
SL $X,$Y,$Z SL $X,$Y,Z
SLU $X,$Y,$ZSLU $X,$Y,Z
SR $X,$Y,$Z SR $X,$Y,Z
SRU $X,$Y,$ZSRU $X,$Y,Z

Spezifikation:
SL: s($X) ← s($Y) × 2u($Z)
SLU: u($X) ← (u($Y) × 2u($Z)) mod 264
SR: s($X) ← ⌊s($Y) / 2u($Z)
SRU: u($X) ← ⌊u($Y) / 2u($Z)

Zeit:

Beschreibung:

SL schiebt Register $Y bitweise nach links und erzeugt ggf. einen Überlauf, falls Bits ungleich dem Vorzeichen Bit herausgeschoben werden. Von rechts werden 0-Bit nachgezogen. SLU arbeitet analog, es kann aber kein Überlauf auftreten.

SR schiebt nach rechts und zieht Bit mit dem Wert des Vorzeichens nach; SRU zieht stets 0-Bit nach.

Mix and Match

Name:

MOR $X,$Y,$Z
MXOR $X,$Y,$Z

Spezifikation:

Die 64 Bit aus $Y seien wie folgt nummeriert (analoges gelte für Nummerierung der Bit in Register $Z):

y00y01...y07 y10y11...y17 ... y70y71...y77

Für das Bit xij aus Register $X bewirkt die Operation:

MOR: xij = y0j& zi0 | y1j& zi1 | ... | y7j& zi7
MXOR: xij = y0j & zi0 ˆ y1j & zi1 ˆ ... ˆ y7j & zi7

Zeit:

Beschreibung:

Die Befehle Betrachten die 8 Byte eines Octabyte als 8×8-Matrix und führen eine Matrixmultiplikation durch, wobei die Addition bei MOR durch die logische Oder-Verknüpfung (|) und bei MXOR durch die Exklusiv-Oder-Verknüpfung (ˆ) sowie die Multiplikation durch die logische Und-Verknüpfung (&) ersetzt wird.

Byteweise Operationen

Name:
BDIF $X,$Y,$ZBDIF $X,$Y,Z
WDIF $X,$Y,$ZWDIF $X,$Y,Z
TDIF $X,$Y,$ZTDIF $X,$Y,Z
ODIF $X,$Y,$ZODIF $X,$Y,Z

Spezifikation:

x ← y-˙z = max (0,y - z)
Dabei sind x,y,z entsprechende Elemente der Vektoren $X, $Y, und $Z.

Zeit:

Beschreibung:

Saturierte Differenz. Ein Octabyte wird als Vektor von acht Byte bzw. von vier Wyde oder zwei Tetra aufgefasst.

Bitweise Operationen mit 16-Bit-Direktoperanden

Name:
ORH $X,YZ, ORMH $X,YZ, ORML $X,YZ, ORL $X,YZ
ANDNH $X,YZ,ANDNMH $X,YZ,ANDNML $X,YZ,ANDNL $X,YZ

Spezifikation:

Der Operator ⊙ steht hier jeweils für die Und-nicht-Verknüpfung (\) oder für die Oder-Verknüpfung (|):
ANDNH bzw. ORH: $X ← $X ⊙ YZ×248
ANDNMH bzw. ORMH: $X ← $X ⊙ YZ×232
ANDNML bzw. ORML: $X ← $X ⊙ YZ×216
ANDNL bzw. ORL: $X ← $X ⊙ YZ

Zeit:

Beschreibung:

Bitweise Verknüpfungen mit einem 16-Bit-Direktoperanden. Der Operand wird vor der logischen Verknüpfung an eine der vier möglichen Wyde-Positionen in einem Octabyte gebracht. Der nicht angesprochene Teil des Zielregisters bleibt unverändert.

Der Befehl SADD

Name:

SADD $X,$Y,$Z

Spezifikation:
s($X) ← s(∑ (v($Y)&˜ v($Z)))

Zeit:

SADD: υ

Beschreibung:

Diese Instruktion (Sideways Add) zählt die Anzahl der Bitpositionen, in denen $Y eine 1 und $Z eine 0 hat. das Ergebnis wird in $X abgelegt.

Der Befehl MUX

Name:

MUX $X,$Y,$Z

Spezifikation:
v($X) ← (v($Y) ∧ v(rM)) ∨ (v($Z) ∧˜v(rM))

Zeit:

MUX: υ

Beschreibung:

(Bitwise Multiplex) Dieser Befehl kombiniert zwei Bitmuster unter Verwendung des Multiplex-Mask-Registers rM. Die Bit im Ergebnis werden von $Y genommen, wo rM 1 ist, und von $Z, wo rM 0 ist.

Adressberechnung

Der Pseudobefehl LDA

Name:

LDA $X,Label

Spezifikation:

LDA: u($X) ← Label

Zeit:

Beschreibung:

Bringt den Wert der durch das Symbol Label bezeichneten Adresse in das Register $X. Dabei muss entweder Bezug auf ein globales Register genommen werden oder die Assembler-Option -x verwendet werden.

Dieser Befehl wird als ADDUI assembliert.

Siehe auch: ADDU

Get Adress (GETA)

Name:

GETA $X,Label

Spezifikation:
u($X) ← RA, mit
RA ← @+ 4*YZ bei Vorwärtsverweisen
RA ← @+4*(YZ-216) bei Rückwärtsverweisen

Zeit:

Beschreibung:

Schreibt eine Adresse in Register $X, wobei relativ adressiert wird. Der Assembler kann für diesen Befehl Vorwärtsverweise auflösen. Der Assembler stellt selbstständig fest, ob es sich um einen Verweis nach vorne oder zurück handelt; entsprechend wählt er den passenden Opcode.

Die Befehle 2ADDU, 4ADDU, 8ADDU und 16ADDU

Name:
2ADDU $X,$Y,$Z 2ADDU $X,$Y,Z
4ADDU $X,$Y,$Z 4ADDU $X,$Y,Z
8ADDU $X,$Y,$Z 8ADDU $X,$Y,Z
16ADDU $X,$Y,$Z16ADDU $X,$Y,Z

Spezifikation:

u($X) ← u($Y) × s + u($Z) bzw.
u($X) ← u($Y) × s + u(Z)

wobei je nach Instruktion s = 2, 4, 8 oder 16 ist.

Zeit:

sADDU: 1υ

Beschreibung:

Die Befehle sADDU dienen zur Adressberechnung bei Feldern, deren Elemente 2, 4, 8 oder 16 Byte lang sind. Ist die Feldadresse in $Z bzw. Z und der Index in $Y, so berechnet der Befehl durch einen Shift und eine Addition direkt die Adresse des Feldelements. Diese Adresse kann bei einem anschließenden Lade- oder Speicherbefehl noch mit einem Offset innerhalb des Elements kombiniert werden.

Siehe auch:

ADDU und LDA .

Die Befehle SET, SETH, SETMH, SETML und SETL

Name:

SETH $X,YZ
SETMH $X,YZ
SETML $X,YZ
SETL $X,YZ

Spezifikation:
SETH: u($X) ← YZ × 248
SETMH: u($X) ← YZ × 232
SETML: u($X) ← YZ × 216
SETL: u($X) ← YZ

Zeit:

Beschreibung:

Die Befehle dienen zum Laden von 16-Bit-Konstanten in ein Register. Dabei kann man sowohl die obersten (High), die zweitobersten (Medium High), die zweituntersten (Medium Low) oder die untersten (Low) zwei Byte laden. Die übrigen Bit des Registers werden dabei auf Null gesetzt.

Der Befehl SET $X,YZ steht für SETL $X,YZ.

Der Befehl SET $X,$Y steht für OR $X,$Y,0.

Siehe auch:

Bitweise Operationen mit 16-Bit-Direktoperanden sowie INCH .

Die Befehle INCH, INCMH, INCML und INCL

Name:

INCH $X,YZ
INCMH $X,YZ
INCML $X,YZ
INCL $X,YZ

Spezifikation:
INCH: u($X) ← (u($X) + YZ × 248) mod 264
INCMH: u($X) ← (u($X) + YZ × 232) mod 264
INCML: u($X) ← (u($X) + YZ × 216) mod 264
INCL: u($X) ← (u($X) + YZ) mod 264

Zeit:

Beschreibung:

Bei dieser Serie von Inkrementbefehlen wird zunächst die 16-Bit Konstante YZ um 6, 4, 2 oder 0 Byte nach links verschoben und dann das Ergebnis zu $X addiert.

Siehe auch:

ORH und ANDNH sowie SETH .

Laden und Speichern

Die Ladebefehle

Name:
LDB $X,$Y,$ZLDB $X,$Y,ZLoad Byte/Load Byte Immediate
LDW $X,$Y,$ZLDW $X,$Y,ZLoad Wyde/Load Wyde Immediate
LDT $X,$Y,$ZLDT $X,$Y,ZLoad Tetra/Load Tetra Immediate
LDO $X,$Y,$ZLDO $X,$Y,ZLoad Octa/Load Octa Immediate

Spezifikation:

Mit A ← $Y+$Z bzw. A ← $Y+Z gilt:
LDB: s($X) ← s(M1[A])
LDW: s($X) ← s(M2[A])
LDT: s($X) ← s(M4[A])
LDO: s($X) ← s(M8[A])
Zeit:

μ + υ

Beschreibung:

Lädt ein Byte, Wyde, Tetrabyte oder Octabyte. Beim Laden wird das Zielregister $X mit dem Vorzeichenbit der jeweils geladenen Einheit bis auf 64 Bit aufgefüllt.

Die Adresse A wird wenn nötig abgerundet um das "Alignment" der Daten sicher zu stellen. Adressen von Octas müssen Vielfache von 8, von Tetras Vielfache von 4 und von Wydes Vielfache von 2 sein.

Siehe auch:

Ladebefehle ohne Berücksichtigung des Vorzeichens.

Die Speicherbefehle

Name:
STB $X,$Y,$ZSTB $X,$Y,ZStore Byte/Store Byte Immediate
STW $X,$Y,$ZSTW $X,$Y,ZStore Wyde/Store Wyde Immediate
STT $X,$Y,$ZSTT $X,$Y,ZStore Tetra/Store Tetra Immediate
STO $X,$Y,$ZSTO $X,$Y,ZStore Octa/Store Octa Immediate

Spezifikation:

Mit A ← $Y+$Z bzw. A ← $Y+Z gilt:
STB: s(M1[A]) ← s($X)
STW: s(M2[A]) ← s($X)
STT: s(M4[A]) ← s($X)
STO: s(M8[A]) ← s($X)

Zeit:

μ + υ

Beschreibung:

Schreibt ein Byte, Wyde, Tetrabyte oder Octabyte in den Speicher. Dabei kann ein Überlauf auftreten.

Die Adresse A wird wenn nötig abgerundet um das "Alignment" der Daten sicher zu stellen. Adressen von Octas müssen Vielfache von 8, von Tetras Vielfache von 4 und von Wydes Vielfache von 2 sein.

Siehe auch:

Befehle zum Speichern ohne Berücksichtigung des Vorzeichens.

Der Befehl STCO

Name:
STCO X,$Y,$ZSTCO X,$Y,Z

Spezifikation:

Mit A ← $Y+$Z bzw. A ← $Y+Z gilt:
u(M8[A]) ← X

Zeit:

STCO: υ + μ

Beschreibung:

Schreibt die Byte-Konstante X als vorzeichenloses Octa in den Speicher.

Die Adresse A wird wenn nötig auf ein Vielfaches von 8 abgerundet um das "Alignment" der Daten sicher zu stellen.

Die Ladebefehle ohne Berücksichtigung des Vorzeichens

Name:
LDBU $X,$Y,$ZLDBU $X,$Y,Z
LDWU $X,$Y,$ZLDWU $X,$Y,Z
LDTU $X,$Y,$ZLDTU $X,$Y,Z
LDOU $X,$Y,$ZLDOU $X,$Y,Z

Spezifikation:

Mit A ← $Y+$Z bzw. A ← $Y+Z gilt:
LDBU: u($X) ← u(M1[A])
LDWU: u($X) ← u(M2[A])
LDTU: u($X) ← u(M4[A])
LDOU: u($X) ← u(M8[A])

Zeit:

1μ + 1υ

Beschreibung:

Lädt ein Byte, Wyde, Tetrabyte oder Octabyte. Beim Laden wird das Zielregister $X mit Nullen bis auf 64 Bit aufgefüllt.

Die Adresse A wird wenn nötig abgerundet um das "Alignment" der Daten sicher zu stellen. Adressen von Octas müssen Vielfache von 8, von Tetras Vielfache von 4 und von Wydes Vielfache von 2 sein.

Siehe auch:

Ladebefehle mit Berücksichtigung des Vorzeichens.

Die Befehle zum Speichern ohne Berücksichtigung des Vorzeichens

Name:
STBU $X,$Y,$ZSTBU $X,$Y,Z
STWU $X,$Y,$ZSTWU $X,$Y,Z
STTU $X,$Y,$ZSTTU $X,$Y,Z
STOU $X,$Y,$ZSTOU $X,$Y,Z

Spezifikation:

Mit A ← $Y+$Z bzw. A ← $Y+Z gilt:
STBU: u(M1[A]) ← u($X) mod 28
STWU: u(M2[A]) ← u($X) mod 216
STTU: u(M4[A]) ← u($X) mod 232
STOU: u(M8[A]) ← u($X)

Zeit:

1μ + 1υ

Beschreibung:

Schreibt ein Byte, Wyde, Tetrabyte oder Octabyte in den Speicher. Dabei kann kein Überlauf auftreten.

Die Adresse A wird wenn nötig abgerundet um das "Alignment" der Daten sicher zu stellen. Adressen von Octas müssen Vielfache von 8, von Tetras Vielfache von 4 und von Wydes Vielfache von 2 sein.

Siehe auch:

Befehle zum Speichern mit Berücksichtigung des Vorzeichens.

Der Befehl LDHT

Name:
LDHT $X,$Y,$ZLDHT $X,$Y,Z

Spezifikation:
u($X) ← u(M4[$Y + $Z]) × 232

Zeit:

1υ + 1μ

Beschreibung:

Lädt ein Tetrabyte aus dem Speicher in die oberen vier Byte von Register $X, das High-Tetra.

Siehe auch:

STHT und LDT zum Laden des unteren Tetras.

Der Befehl STHT

Name:
STHT $X,$Y,$ZSTHT $X,$Y,Z

Spezifikation:
u(M4[$Y + $Z]) ← ⌊u($X)∕232

Zeit:

1υ + 1μ

Beschreibung:

Speichert die oberen vier Byte von $X, das High-Tetra, an die angegebene Adresse.

Siehe auch:

LDHT, und STT zum Speichern des unteren Tetras.

Laden und Speichern von Short Floats

Name:
LDSF $X,$Y,$ZLDSF $X,$Y,Z
STSF $X,$Y,$ZSTSF $X,$Y,Z

Spezifikation:
LDSF: f($X) ← f(M4[$Y + $Z])
STSF: f(M4[$Y + $Z]) ← f($X)

Zeit:

1υ + 1μ

Beschreibung:

Lädt bzw. speichert eine 32-Bit-Gleitkommazahl. Dabei findet eine Umwandlung ins/vom 64-Bit-Format statt.

Siehe auch:

LDT und STT (für 32-Bit-Festkommazahlen).

Sprünge und Verzweigungen

Unbedingte Sprünge mit JMP

Name:

JMP XYZ

Spezifikation:
@ ← RA mit
RA ← @+4*XYZ bei einem Vorwärtssprung
RA ← @+4*(XYZ-224) bei einem Rückwärtssprung

Zeit:

Beschreibung:

Führt einen bedingungslosen Sprung durch. Das Sprungziel sollte über eine Marke angegeben werden. Der Assembler stellt selbstständig fest, ob es sich um einen Sprung nach vorne oder zurück handelt; entsprechend wählt er den passenden Opcode.

Der Befehl GO

Name:

GO $X,$Y,Z
GO $X,$Y,$Z

Spezifikation:
u($X) ← @+4
@ ← $Y + Z

Zeit:

Beschreibung:

Unbedingter Sprung mit absoluter Adressangabe. Der Befehl GO $X,$Y,Z bewirkt, dass die Adresse des unmittelbar nachfolgenden Befehls in Register $X gespeichert wird und die Programmausführung an der Adresse $Y + Z fortgesetzt wird. Dieser Befehl eignet sich auch zur Realisierung von Unterprogrammen.

Siehe auch:

PUSHGO, GETA, LDA, PREGO

Bedingte Sprünge

Name:
BZ $X,YZ PBZ $X,YZ (Probable) Branch if zero
BNZ $X,YZPBNZ $X,YZ(Probable) Branch if nonzero
BN $X,YZ PBN $X,YZ (Probable) Branch if negative
BNN $X,YZPBNN $X,YZ(Probable) Branch if nonnegative
BP $X,YZ PBP $X,YZ (Probable) Branch if positive
BNP $X,YZPBNP $X,YZ(Probable) Branch if nonpositive
BOD $X,YZPBOD $X,YZ(Probable) Branch if odd
BEV $X,YZPBEV $X,YZ(Probable) Branch if even

Spezifikation:

Mit RA ← @+4*YZ bei Vorwärtssprüngen
und RA ← @+4*(YZ-216) bei Rückwärtssprüngen (Branch backwards) gilt:
BZ: @ ← RA, falls s($X) = 0
BNZ:@ ← RA, falls s($X)≠0
BN: @ ← RA, falls s($X) < 0
BNN:@ ← RA, falls s($X) ≥ 0
BP: @ ← RA, falls s($X) > 0
BNP: @ ← RA,falls s($X) ≤ 0
BOD: @ ← RA,falls s($X) mod 2 = 1, d.h. s($X) ungerade
BEV: @ ← RA,falls s($X) mod 2 = 0, d.h. s($X) gerade

Zeit:

1υ, falls die Branch Prediction den Sprung richtig vorher sagt (Good Guess), und 3υ sonst (Bad Guess).

Beschreibung:

Bedingte Verzweigungen. Der Assembler stellt selbstständig fest, ob es sich um einen Sprung nach vorne oder zurück handelt; entsprechend wählt er den passenden Opcode. Die Variante der "Probable Branches" mit einem vorangestellten "P" teilt dem Prozessor mit, dass der Sprung wahrscheinlich ausgeführt wird, und ist ein Hinweis für die Branch Prediction Logik des Prozessors. Diese ermöglicht es die entsprechenden Befehle von der Stelle des Sprungziels schon vorzeitig zu laden und zu decodieren.

Befehle für bedingte Zuweisungen

Name:
CSZ $X,$Y,$Z CSZ $X,$Y,Z ZSZ $X,$Y,$Z ZSZ $X,$Y,Z
CSNZ $X,$Y,$ZCSNZ $X,$Y,Z ZSNZ $X,$Y,$ZZSNZ $X,$Y,Z
CSN $X,$Y,$Z CSN $X,$Y,Z ZSN $X,$Y,$Z ZSN $X,$Y,Z
CSNN $X,$Y,$ZCSNN $X,$Y,Z ZSNN $X,$Y,$ZZSNN $X,$Y,Z
CSP $X,$Y,$Z CSP $X,$Y,Z ZSP $X,$Y,$Z ZSP $X,$Y,Z
CSNP $X,$Y,$ZCSNP $X,$Y,Z ZSNP $X,$Y,$ZZSNP $X,$Y,Z
CSOD $X,$Y,$ZCSOD $X,$Y,Z ZSOD $X,$Y,$ZZSOD $X,$Y,Z
CSEV $X,$Y,$ZCSEV $X,$Y,Z ZSEV $X,$Y,$ZZSEV $X,$Y,Z

Spezifikation:
CSxx: s($X) ← s($Z) falls s($Y) die Bedingung xx erfüllt.
ZSxx:
s($X) ← { s($Z) falls s($Y) die Bedingung xx erfüllt
0 sonst

Zeit:

Beschreibung:

Die Befehle "Conditional Set" bzw. "Zero or Set" führen eine bedingte Zuweisung durch. Die Bedingung wird jeweils für $Y geprüft.

Siehe auch:

Bedingte Sprünge.

Unterprogramme und Prozesse

Die Befehle PUSHJ und PUSHGO

Name:

PUSHJ $X,YZ
PUSHGO $X,$Y,Z

Spezifikation: Falls X < rG, so kommen die Register 0 bis $X - 1 auf den Registerstack (Push). War das Register $X marginal, so wird es automatisch lokal wie bei einer Zuweisung. Anschließend kommt der Wert X auf den Registerstack.

Falls X ≥ rG, so kommen die Register $0 bis $rL-1 auf den Registerstack, gefolgt vom dem Wert rL. Dann wird rL ← 0.

Ferner:
rJ ← @ + 4
@ ← @ + 4YZ (PUSHJ) oder
@ ← @ + 4(YZ - 216) (PUSHJB) oder
@ ← $Y + $Z (PUSHGO) oder
@ ← $Y + Z (PUSHGOI)

Die PUSHJ-Operation von x + 1 Registern auf den Registerstack S[0],…,S[τ - 1] bedeutet im Einzelnen:
S[τ] ← $0
S[τ + 1] ← $1
S[τ + x - 1] ← $(X - 1),
S[τ + x] ← x,
τ ← τ + x + 1,
$0 ← $(x + 1)
$(rL - x - 2) ← $(rL - 1),
rL ← rL - x - 1.

Zeit:

PUSHJ: 1υ

PUSHGO: 3υ

Beschreibung:

Die Befehle PUSHJ und PUSHGO dienen zum Sprung in ein Unterprogramm. Sie unterscheiden sich nur in der Art der Adressierung. PUSHJ verwendet eine 16 Bit lange relative Adresse ähnlich wie ein JMP während PUSHGO eine absolute Adresse durch das Register $Y und ein Offset in $Z bzw. Z spezifiziert so wie ein GO.

Siehe auch:

POP und
GO

Der Befehl POP

Name:

POP X,YZ

Spezifikation:

Falls X > rL, so wird erst X durch rL + 1 ersetzt.

Der Registerstack S[0],…,S[τ - 1] wird verändert wie folgt:

x ← S[τ - 1]mod256 (die Größe des aufrufenden Stackframes),
S[τ - 1] ← $(X - 1) (der Haupt-Rückgabewert),
rL ← min(x + X,rG),
$(rL - 1) ← $(rL - x - 2)
$(x + 1) ← $0,
$x ← S[τ - 1]
$0 ← S[τ - x - 1],
τ ← τ - x - 1
@ ← rJ + 4YZ

Zeit:

Beschreibung:

Die POP-Instruktion macht den Effekt einer vorausgegangenen PUSHJ-Instruktion wieder rückgängig. X gibt die Anzahl der Rückgabewerte an, die in den Registern $0 bis $X - 1 stehen. Dabei ist $X - 1 der Haupt-Rückgabewert. Zunächst steht direkt unter dem Register $0 auf dem Registerstack die Größe x des vorausgehenden Stackframes, also die Anzahl der lokalen Variablen. An diesen Platz im Registerstack kommt der Haupt-Rückgabewert. Dann werden die Register einfach umnummeriert. Nach dem Rücksprung sind die alten lokalen Register wieder in $0, $1 usw. und die Rückgabewerte sind dann in den Registern $X und folgende zu finden, wobei hier das Register $X aus der vorangegangenen PUSHJ-Instruktion gemeint ist.

Siehe auch:

PUSHJ

Die Befehle SAVE und UNSAVE

Name:

SAVE $X,0
UNSAVE $Z

Spezifikation:
SAVE: Bedingung X ≥ rG
u($X) ← context
rL ← 0.
UNSAVE: context ← u($Z)

Zeit:

υ + 20μ

Beschreibung:

Sichert und restauriert den Zustand eines Prozesses im Registerstack.

Der Befehl CSWAP

Name:

CSWAP $X,$Y,$Z

Spezifikation:

Falls u(M8[$Y + $Z]) = rP
dann u(M8[$Y + $Z]) ← $X und $X ← 1
andernfalls rP ← u(M8[$Y + $Z]) und $X ← 0

Zeit:

2υ + 2μ

Beschreibung:

Vergleiche und Vertausche (Compare and Swap). Vergleicht das Octabyte an der Adresse $Y+$Z mit dem Inhalt des Prediction-Registers rP. Falls die beiden Werte gleich sind so wird $X gespeichert und danach auf 1 gesetzt, andernfalls wird der Speicherinhalt ins Register rP geladen und $X wird auf 0 gesetzt.

Dies ist eine atomare Operation, und daher dazu geeignet, verschiedene Prozesse über einen gemeinsamen Speicher zu synchronisieren.

Spezialregister und Systemprogrammierung

Die Befehle PUT und GET

Name:
PUT X,$Z
PUT X,Z
GET $X,Z

Spezifikation:
PUT: u(g[X]) ← u($Z)
PUT: u(g[X]) ← u(Z)
GET: u($X) ← u(g[Z])

Zeit:

Beschreibung:

GET lädt den Wert eines Spezialregisters in ein normales Register. PUT schreibt umgekehrt den Wert eines normalen Registers oder einer Konstanten in ein Spezialregister.

Für die Spezialregister verwendet man die vordefinierten Konstanten rA…rZ sowie rBB, rTT, rWW,rXX,rYY und rZZ.

In folgende Register kann im "User Mode" nicht geschrieben werden: rC, rL, rN, rO, rS, rI, rT, rTT, rK, rQ, rU und rV.

Nach rG kann kein Wert geschrieben werden, der kleiner ist als 32 (oder kleiner als der aktuell in rL enthaltene Wert) oder größer als 255.

Nach rA kann kein Wert geschrieben werden, der größer ist als #3FFFF.

Das Y Feld muss Null sein (braucht aber nicht angegeben werden).

Der Befehl TRIP

Name:

TRIP X,Y,Z

Spezifikation:
rB ← $255
$255 ← rJ
rW ← @+4
rX ← #8000 0000≪ 32∥#FF X Y Z
rY ← $Y
rZ ← $Z

Zeit:

Beschreibung:

Löst einen Trip-Interrupt aus und führt den Trip-Handler ab Adresse #00 aus.

Siehe auch:

TRAP und RESUME

Der Befehl TRAP

Name:

TRAP X,Y,Z

Spezifikation:
rBB ← $255
$255 ← rJ
rWW ← @+4
rXX ←#8000 0000≪ 32∥#00 X Y Z
rYY ← $Y
rZZ ← $Z

Zeit:

Beschreibung:

Löst einen Trap-Interrupt aus und führt eine Betriebssystemroutine aus (Trap-Handler), die ab der in rT angegebenen Adresse steht.

Siehe auch:

TRIP und RESUME

Der Befehl RESUME

RESUME Z

Spezifikation: Unvollständig
@ ←rW-4

Zeit:

Beschreibung:

Setzt das unterbrochene Programm nach einem Interrupt fort.

Siehe auch:

TRIP und TRAP

Die Befehle LDUNC und STUNC

Name:

LDUNC $X,$Y,$Z
STUNC $X,$Y,$Z

Spezifikation:
s($X) ← s(M8[$Y + $Z]) bzw.
s(M8[$Y + $Z]) ← $X

Zeit:

1υ + 1μ

Beschreibung:

Diese Befehle laden bzw. schreiben ein Octabyte genauso wie LDO und STO. Sie Informieren jedoch die Maschine, dass der Wert und seine Nachbarn wahrscheinlich in nächster Zukunft nicht mehr gebraucht werden und deshalb nicht im Cache vorgehalten werden sollten.

Siehe auch:

LDO und STO.

Die Befehle PRELD, PREST und PREGO

Name:

PRELD X,$Y,$Z
PREST $X,$Y,$Z
PREGO X,$Y,$Z

Zeit:

Beschreibung:

Informieren die Maschine darüber, dass der Inhalt des Speichers im Bereich $Y+$Z bis X+$Y+$Z demnächst

  • wahrscheinlich geladen oder gespeichert wird (PRELD),
  • definitiv neu geschrieben wird, bevor er das nächste mal gelesen wird (PREST), bzw.
  • wahrscheinlich ausgeführt wird (PREGO).

Der Befehl SYNC

Name:

SYNC XYZ

Zeit:

Beschreibung:

Ermöglicht die Synchronisierung paralleler Prozesse. XYZ hat einen Wert zwischen 0 und 7. Anwendungsprogramme dürfen nur die Werte bis 3 verwenden, die größeren Werte sind dem Betriebssystem vorbehalten.

Der Befehl SYNCID

Name:

SYNCID X,$Y,$Z

Zeit:

SYNCID: υ

Beschreibung:

Synchronisiert den Daten Cache mit dem Instruktions Cache im Bereich $Y+$Z bis X+$Y+$Z.

Der Befehl SYNCD

Name:

SYNCD X,$Y,$Z

Zeit:

SYNCD: υ

Beschreibung:

Synchronisiert Daten Cache und Hauptspeicher im Bereich $Y+$Z bis X+$Y+$Z.

Der Befehl LDVTS

Name:

LDVTS $X,$Y,$Z LDVTS $X,$Y,Z

Zeit:

Beschreibung:

Lädt einen Wert in die virtual translation tables.

Der Befehl SWYM

Name:

SWYM X,Y,Z

Zeit:

Beschreibung:

Sympathize with your machinery: Bei diesem Befehl gönnt sich der MMIX-Prozessor eine kleine (1υ) Verschnaufpause.

Assembler Anweisungen

Definieren von Namen mit IS

Name:

Name IS Ausdruck

Beschreibung:

Teilt dem Assembler mit, dass Name ab sofort für den gegebenen Ausdruck steht. Der Ausdruck darf sich dabei nur auf Werte beziehen, die bereits definiert wurden. Der Befehl kann auch verwendet werden, um Namen für Register zu vereinbaren.

Siehe auch:

PREFIX .

Die Anweisung LOC

Name:

LOC Ausdruck

Spezifikation:
@ ← Ausdruck

Beschreibung:

Legt die Adresse fest, ab der im weiteren Verlauf der Assemblierung der Speicher gefüllt wird (Symbol @ steht für "The place where we are at").

Die Segmente in dem für den Anwender zugänglichen Teil des Hauptspeichers.
SegmentSymbolStartadresseZweck
Textsegment   #0

Programm und statische Daten

DatensegmentData_Segment #2000000000000000

veränderliche Daten

Poolsegment Pool_Segment #4000000000000000  
Stacksegment Stack_Segment#6000000000000000  

Vorbelegen von Speicher

Name:

BYTE Ausdrücke
WYDE Ausdrücke
TETRA Ausdrücke
OCTA Ausdrücke

Beschreibung:

Pseudobefehle zum Vorbelegen von Speicher. Die durch Ausdrücke angegebenen Werte werden zunächst in die Objektdatei eingetragen und stehen zum Zeitpunkt der Programmausführung an der angegebenen Stelle im Speicher. Die durch Kommata getrennten Ausdrücke (keine Leerschritte!) werden jeweils auf das angegebene Format (1, 2, 4 oder 8 Byte) gebracht.

Zeichenketten (eingeschlossen in doppelte Anführungszeichen) stehen für eine Liste von ASCII Werten. Vorsicht: auch diese Werte werden auf das angegebene Format (1, 2, 4 oder 8 Byte) gebracht.

Setzen von globalen Registern mit GREG

Name:

GREG Ausdruck

Beschreibung:

Reserviert ein neues globales Register. Der durch Ausdruck angegebene Wert steht zum Programmstart in diesem Register zur Verfügung.

Register $255 ist stets ein globales Register. Beim ersten GREG wird automatisch das Register $254 als global vereinbart, beim zweiten GREG dann $253 usw.

Wird eine Marke mit angegeben, so wird damit ein symbolischer Name für das festgelegte globale Register bestimmt.

Definieren von separaten Namensräumen mit PREFIX

Name:

PREFIX Name

Spezifikation:
Das aktuelle Präfix wird auf Name gesetzt.

Beschreibung:

Jeder Name im Programm, der nicht mit einem Doppelpunkt beginnt wird automatisch durch das aktuelle Präfix zu einem vollständigen Namen ergänzt.

Beim Start des Assemblers ist das aktuelle Präfix einfach nur ein Doppelpunkt. Diesen Zustand kann man durch PREFIX : jederzeit wiederherstellen.

Der Pseudobefehl LOCAL

Name:

LOCAL Ausdruck

Beschreibung:

Dieser Befehl deklariert den gegebenen Ausdruck als ein lokales Register. Der Assembler erzeugt eine Fehlermeldung, wenn am Ende der Assemblierung der Wert von rG nicht größer ist, als alle Register, die mit dieser Anweisung als lokal deklariert sind. Die LOCAL-Anweisung ist nur nötig, wenn die gegebene Registernummer wenigstens 32 ist, da kleinere Register nie global sein können.

Siehe auch:

PUSHJ

Die Anweisungen BSPEC und ESPEC

Name:

BSPEC Ausdruck
ESPEC

Beschreibung:

Die Anweisung BSPEC steht für "Begin Special Mode" und entspechend steht ESPEC für "End Special Mode".

Der Text zwischen diesen Anweisungen wird direkt in die Ausgabedatei geschrieben, aber nicht als Teil des assemblierten Programms geladen. So bilden diese Anweisungen einen Mechanismus, mit dem Systemfunktionen Daten durch den Assembler hindurch direkt in die Ausgabe übermitteln können. So kann etwa der Übersetzer einer Hochsprache in dieser Weise Informationen über die Zeilennummern für einen Debugger in die erzeugte Objektdatei einfügen.

Normale MMIX-Instruktionen sind in Special Mode nicht zulässig; nur die Pseudobefehle IS, PREFIX, BYTE, WYDE, TETRA, OCTA, GREG und LOCAL sind dort erlaubt.

Der Ausdruck nach BSPEC sollte in zwei Byte passen und kann dazu verwendet werden, Informationen über die Art des nachfolgenden Textes zu übermitteln. So kann etwa BSPEC 1 zur Übermittlung von Zeilennummern und BSPEC 2 zur Übermittlung von Dateinamen dienen.

Please help to keep this site up to date! If you want to point out important material or projects that are not listed here, if you find errors or want to suggest improvements, please send email to email