MMIX LOGO

MMIX Instruction Set

Table of Content

Content

The MMIX Instruction Set

The descriptions below are translated from the MMIX Buch.

Content

Integer Arithmetic

Signed Arithmetic

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

Specification:
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)⌋ if $Z ≠ 0
0 if $Z = 0

the integer part of the Quotient and

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

the remainder in special register rR.

All instructions exist in two variants. The second operand can either be a register $Z or an immediate value Z.

Timing:

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

Description:

These are instructions for computations with signed integers. The instructions record exceptions like overflow or division by zero in special register rA and, if enabled, cause a TRIP.

See also:

Unsigned Arithmetic.

Unsigned Arithmetic

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

Specification:

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) if u($Z) > u(rD)
u($Y) otherwise

The special register rD is prepended to the register $Y to form a 128 bit number. This number is divided by $Z and the result is stored in $X. The remainder is stored in special register rR.

If, however, rD ≥ $Z, then the result of the division would be greater than 264 and the quotient will not be computed. Instead, rD is stored in $X and $Y is stored in rR. In Donald Knuth's "The Art of Computer Programming", Volume 2, "Seminumerical Algorithms", Chapter 4.3.1 will explain how to use this instruction to implement division of high-precision numbers with 128 bit or more.

All instructions exist in two variants. The second operand can either be a register $Z or an immediate value Z.

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

Description:

These instructions perform arithmetic operations on unsigned numbers. They never cause overflow or other exceptions, not even if dividing by zero.

See also:

Signed Arithmetic.

NEG and NEGU

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

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

Timing:

Description:

Y is a nonnegative constant, usually zero. If Y has the value zero, it can be omitted. The instruction is used to negate $Z.

Compare instructions

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

Specification:

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

Timing:

Description:

Compares two integer numbers. The result can be used to control Branches or Conditional Set instructions.

Floating Point Arithmetic

Floating Point Conversion

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

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

Timing:

Description:

Converts numbers from integer representation to floating point representation and vice versa. An optional Y-Operand can be used to specify one of the following rounding modes: ROUND_OFF, ROUND_UP, ROUND_DOWN, or ROUND_NEAR.

Floating Point Arithmetic

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

Specification:
FDIV: f($X) ← f($Y) ∕ f($Z)
FREM: f($X) ← f($Y) rem f($Z)
y rem z is defined as y-nz, where n is the integer number closest to y∕z, or the closest even number in case of multiple closest integers.
FINT: f($X) ← f(int(f($Z)))
FSQRT: f($X) ← f($Z)12

Timing:

4υ for FADD, FSUB, FMUL, FREM and FINT
40υ for FDIV and FSQRT

Description:

FADD, FSUB, FMUL, and FDIV perform arithmetic on floating point numbers. FINT rounds a floating point number to the nearest integer number using the current rounding mode. Unlike FIX, the result is still in floating point format. The instructions FINT and FSQRT can use the optional Y-Operand to specify a rounding mode: ROUND_OFF, ROUND_UP, ROUND_DOWN, or ROUND_NEAR.

Comparing Floating Point Numbers

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

Specification:
FCMP:
s($X) ← { - 1 if f($Y) < f($Z)
0 if f($Y) = f($Z)
+1 if f($Y) > f($Z)
FEQL:
s($X) ← { 1 if f ($Y) = f($Z)
0 otherwise

Let Nε(u) = {x| |x - u|≤ ε 2e-q}, where q is the excess and e = E + q is the sum of exponent and excess of the floating point representation of u. Then:
FCMPE:
s($X) ← { - 1 if f($Y) < Nε(f($Z)) and Nε(f($Y)) < f($Z)
0 if f($Y) ∈ Nε(f($Z)) or f($Z) ∈ Nε(f ($Y))
+1 if f($Y) > Nε(f($Z)) and Nε(f($Y)) > f($Z)
FEQLE:
s($X) ← { 1 if f($Y) ∈ Nε(f($Z)) and f($Z) ∈ Nε(f ($Y))
0 otherwise

The value of ε is taken from the special register rE.

FUN:
s($X) ← { 1 if either $Y or $Z is not a Number (NaN),
0 otherwise
FUNE:
s($X) ← { 1 if either $Y, $Z or rE is not a Number (NaN),
0 otherwise

Description:

For a more detailed description see for example [mmix-doc].

Conversion of Short Floats

Name:

SFLOT $X,$Z or SFLOT $X,Z
SFLOTU $X,$Z or SFLOTU $X,Z

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

Timing:

Description:

Converts an integer number to 32-bit IEEE floating point format. The number is first converted to T, a 32-bit intermediate value. This conversion might cause rounding. After this conversion, the number T is extended to a 64-bit floating point number. The Y-operand may contain a rounding mode similar to the FLOT instruction.

See also:

FLOT and FLOTU.

Bits and Bytes

Bitwise Logical Operations

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

Specification:

In the following table a is used for a bit from the source operand $Y and b for the corresponding bit in the source operand $Z (or Z). The other columns show the corresponding result bit.

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

Timing:

Description:

The specified operation is executed in parallel on each of the 64 bits of the two source operands which yields 64 result bits.

Shifting Bit Patterns

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

Specification:
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)

Timing:

Description:

SL shifts the bits in register $Y left. If bits unequal to the sign bit of $Y are shifted out during this process, an overflow is signaled. The result is filled with 0 bits from the right. SLU has the same effect but never causes overflow.

SR shifts the bits in register $Y to the right. It fills the target register from the left by replicating the sign bit and discards bits on the right; SRU fills the target register from the left with zeros.

Mix and Match

Name:

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

Specification:

Assume that the 64 bits in $Y are numbered as follows (and similar for the bits in register $Z and $X):

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

Now bit xij in register register $X is computed as follows:

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

Timing:

Description:

These instructions regard the 8 Byte of a register as a 8×8-Matrix and compute the result as a matrix multiplication, where in MOR, Addition is replaced by OR (logical or (|)) and in MXOR, Addition is replaced by XOR (exclusive or (ˆ)). In both cases the AND operation (&) is used instead of multiplication.

Bytewise Operations

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

Specification:

x ← y-˙z = max (0,y - z)
Here x,y,z are corresponding elements of the vectors $X, $Y, and $Z.

Timing:

Description:

Saturated Difference. An Octa byte is regarded as a vector of eight byte, four Wyde, or two Tetra respectively.

Bitwise Operations with 16-Bit Immediate values

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

Specification:

Below, operator ⊙ stands either for the And-Not (\) operation or the Or (|) operation:
ANDNH or ORH: $X ← $X ⊙ YZ×248
ANDNMH or ORMH: $X ← $X ⊙ YZ×232
ANDNML or ORML: $X ← $X ⊙ YZ×216
ANDNL or ORL: $X ← $X ⊙ YZ

Timing:

Description:

Bitwise operation on a 16-bit immediate value. Before the immediate wyde operand is used, it is shifted into one of the four possible positions of an octabyte.

The SADD Instruction

Name:

SADD $X,$Y,$Z

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

Timing:

SADD: υ

Description:

This instruction (Sideways Add) counts the number of bit positions in which $y has a 1 and $Z has a 0. The result is stored in $X.

The MUX Instruction

Name:

MUX $X,$Y,$Z

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

Timing:

MUX: υ

Description:

(Bitwise Multiplex) This instruction combines two bit pattern using the Multiplex-Mask-Registers rM. The bits in the result are taken from $Y, when the corresponding bit in rM is 1 and from $Z if the bit in rM is 0.

Address Computations

The Pseudo Instruction LDA

Name:

LDA $X,Label

Specification:

LDA: u($X) ← Label

Timing:

Description:

Stores the address indicated by the label in register $X. This instruction is assembled as an ADDUI instruction using a suitable global register or, with the -x option of mmixal it is assembled into a sequence of four instructions using 16-bit immediate operands.

See also: ADDU, Bitwise Operations with 16-Bit Immediate Values.

Get Address (GETA)

Name:

GETA $X,Label

Specification:
u($X) ← RA, with
RA ← @+ 4*YZ with forward references
RA ← @+4*(YZ-216) for backward references

Timing:

Description:

Stores an address in register $X using relative addressing. The assembler is able to resolve forward references and will automatically choose the appropriate opcode.

2ADDU, 4ADDU, 8ADDU and 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

Specification:

u($X) ← u($Y) × s + u($Z) or
u($X) ← u($Y) × s + u(Z)

were s = 2, 4, 8 or 16, depending on the instruction.

Timing:

sADDU: 1υ

Description:

The instructions sADDU are handy for address calculations with arrays of elements of size 2, 4, 8 or 16 byte.

See also:

ADDU and LDA .

SET, SETH, SETMH, SETML, and SETL

Name:

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

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

Timing:

Description:

This instruction are used to load 16-bit constants. Either the two highest(High), the second highest (Medium High), the second lowest (Medium Low), or the lowest(Low) two byte can be loaded. All other bytes of the result are set to zero.

The instruction SET $X,YZ is assembled as SETL $X,YZ.

The instruction SET $X,$Y is assembled as OR $X,$Y,0.

See also:

Bitwise Operations with 16-Bit Immediate Operands and INCH .

INCH, INCMH, INCML, and INCL

Name:

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

Specification:
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

Timing:

Description:

This collection of increment instructions will first shift the 16-bit immediate value to the left by 6, 4, 2, or 0 byte before adding it to $X.

See also:

ORH, ANDNH, and SETH.

Load and Store

Loading Signed Integers

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

Specification:

With A ← $Y+$Z respectively A ← $Y+Z we have:
LDB: s($X) ← s(M1[A])
LDW: s($X) ← s(M2[A])
LDT: s($X) ← s(M4[A])
LDO: s($X) ← s(M8[A])
Timing:

μ + υ

Description:

Loads one byte, wyde, tetrabyte, or octabyte. The target register $X is padded to the left using the sign bit.

The address A is rounded down, if necessary, according to the alignment requirements. Addresses for octabytes must be a multiple of 8, for tetrabytes a multiple of 4, and for wydes a multiple of 2.

See also:

Loading Unsigned Data.

Storing Signed Integers

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

Specification:

With A ← $Y+$Z respectively A ← $Y+Z we have:
STB: s(M1[A]) ← s($X)
STW: s(M2[A]) ← s($X)
STT: s(M4[A]) ← s($X)
STO: s(M8[A]) ← s($X)

Timing:

μ + υ

Description:

Writes one byte, wyde, tetrabyte, or octabyte to memory. Overflow may occur.

The address A is rounded down, if necessary, according to the alignment requirements. Addresses for octabytes must be a multiple of 8, for tetrabytes a multiple of 4, and for wydes a multiple of 2.

See also:

Storing Unsigned Data.

The STCO Instruction

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

Specification:

With A ← $Y+$Z respectively A ← $Y+Z we have:
u(M8[A]) ← X

Timing:

STCO: υ + μ

Description:

Stores the one byte constant X as an unsigned octa in main memory.

The address A is rounded down, if necessary, to a multiple of 8.

Loading Unsigned Data

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

Specification:

With A ← $Y+$Z respectively A ← $Y+Z we have:
LDBU: u($X) ← u(M1[A])
LDWU: u($X) ← u(M2[A])
LDTU: u($X) ← u(M4[A])
LDOU: u($X) ← u(M8[A])

Timing:

1μ + 1υ

Description:

Loads one byte, wyde, tetrabyte, or octabyte. The value is padded with zeros to the left to fill the 64-bit target register $X.

The address A is rounded down, if necessary, according to the alignment requirements. Addresses for octabytes must be a multiple of 8, for tetrabytes a multiple of 4, and for wydes a multiple of 2.

See also:

Loading Signed Integers.

Storing Unsigned Data

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

Specification:

With A ← $Y+$Z respectively A ← $Y+Z we have:
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)

Timing:

1μ + 1υ

Description:

Writes one byte, wyde, tetrabyte, or octabyte to main memory. No overflow will occur.

The address A is rounded down, if necessary, according to the alignment requirements. Addresses for octabytes must be a multiple of 8, for tetrabytes a multiple of 4, and for wydes a multiple of 2.

See also:

Storing Signed Integers.

The LDHT Instruction

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

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

Timing:

1υ + 1μ

Description:

Loads one tetrabyte from main memory into the high-tetra (the 4 most significant byte) of $X. The low tetra of $X is filled with zeros.

The address A is rounded down, if necessary, to be a multiple of 4.

See also:

STHT and LDT.

The STHT Instruction

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

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

Timing:

1υ + 1μ

Description:

Store the High-Tetra (the four most significant byte) of $X to main memory.

The address A is rounded down, if necessary, to be a multiple of 4.

See also:

LDHT and STT.

Loading and Storing of Short Floats

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

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

Timing:

1υ + 1μ

Description:

Loads respectively stores a 32-bit floating point number. Before storing, respectively after loading, a conversion from, respectively to, the 64-bit floating point format is done.

See also:

LDT and STT (for 32-bit fixed point numbers).

Jumps and Branches

Jumps with Relative Addresses

Name:

JMP XYZ

Specification:
@ ← RA with
RA ← @+4*XYZ for a jump forward,
RA ← @+4*(XYZ-224) for a jump backward.

Timing:

Description:

Executes an unconditional jump. Usually, a label is used to specify the jump target. The assembler will automatically determine whether it is a jump forward or backward and selects the appropriate instruction.

Jumps with Absolute Addresses

Name:

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

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

Timing:

Description:

Unconditional jump to Address $Y+$Z, respectively $Y+Z. The target address is rounded down to a multiple of 4. The address of the next instruction is stored as return address in $X. The instruction can be used to link subroutines or coroutines.

See also:

PUSHGO, GETA, LDA, PREGO

Branches

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

Specification:

With RA ← @+4*YZ for forward branches
and RA ← @+4*(YZ-216) for backward branches, we have:
BZ: @ ← RA, if s($X) = 0
BNZ:@ ← RA, if s($X)≠0
BN: @ ← RA, if s($X) < 0
BNN:@ ← RA, if s($X) ≥ 0
BP: @ ← RA, if s($X) > 0
BNP: @ ← RA,if s($X) ≤ 0
BOD: @ ← RA,if s($X) mod 2 = 1, d.h. s($X) odd
BEV: @ ← RA,if s($X) mod 2 = 0, d.h. s($X) even

Timing:

1υ, in case the branch prediction logic makes a correct prediction (good guess), and 3υ otherwise (bad guess).

Description:

Conditional Branches. The assembler determines automatically, whether the branch is forward or backward and chooses the appropriate instruction. Probable branches, with the prefix "P" are a hint for the processor that the branch is probably taken, directing the instruction fetch to the target address.

Conditional Assignments

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

Specification:
CSxx: s($X) ← s($Z) if s($Y) satisfies the condition xx.
ZSxx:
s($X) ← { s($Z) if s($Y) satisfies condition xx,
0 otherwise

Timing:

Description:

The "Conditional Set" and "Zero or Set" Instructions check the specified condition for the value $Y and conditional execute the assignment.

See also:

Branches.

Subroutines and Processes

PUSHJ and PUSHGO

Name:

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

Specification: assignment to $X. If X < rG, registers $0 to $X - 1 are pushed to the register stack. If $X is a marginal register, it is automatically made local as in an Finally, the value X is pushed on the register stack.

If X ≥ rG, registers $0 to $rL-1 are pushed to the register stack Finally, the value rL is pushed on the register stack and rL ← 0.

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

The PUSHJ-Operation of x + 1 registers to the register stack S[0],…,S[τ - 1] entails the following:
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.

Timing:

PUSHJ: 1υ

PUSHGO: 3υ

Description:

The PUSHJ and PUSHGO instructions are used to link subroutines. The only difference between the two is the computation of the target address. PUSHJ uses a 16-bit relative address, like branch instructions, while PUSHGO uses an absolute address $Y+$Z (or $Y+Z) like the GO instruction.

See also:

POP and
GO

The POP Instruction

Name:

POP X,YZ

Specification:

If X > rL, then first replace X by rL + 1.

The register stack S[0],…,S[τ - 1] is changed as follows:

x ← S[τ - 1]mod256 (size of the callee's stack frame),
S[τ - 1] ← $(X - 1) (main return value),
rL ← min(x + X,rG),
$(rL - 1) ← $(rL - x - 2)
$(x + 1) ← $0,
$x ← S[τ - 1]
$0 ← S[τ - x - 1],
τ ← τ - x - 1
@ ← rJ + 4YZ

Timing:

Description:

The POP instruction undoes the effect of a previous PUSHJ Instruction. X indicates the number of return values in registers $0 to $(X-1), where $(X-1) contains the main return value. Initially, the size x of the callee's stack frame (the number of its local registers) is directly below $0 on the register stack. This value is replaced by the main return value. After that, the registers are renumbered such that the callee's local registers are again $0, $1, ... and the return values are in registers $X and following (where the $X here is from the previous PUSHJ instruction).

See also:

PUSHJ

SAVE and UNSAVE

Name:

SAVE $X,0
UNSAVE $Z

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

Timing:

υ + 20μ

Description:

Saves and restore the process state in the register stack.

CSWAP

Name:

CSWAP $X,$Y,$Z

Specification:

If u(M8[$Y + $Z]) = rP
then u(M8[$Y + $Z]) ← $X and $X ← 1
otherwise rP ← u(M8[$Y + $Z]) and $X ← 0

Timing:

2υ + 2μ

Description:

Compare and Swap. Compare the octabyte at the address $Y+$Z (or $Y+Z) with the content of the prediction register rP. If both are equal, store $X at the given address and set $X to 1, otherwise load the value from the given address into rP and set $X to 0.

This is an atomic operation, and therefore suitable to synchronize processes using memory locations.

Special Registers and System Programming

PUT and GET

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

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

Timing:

Description:

GET transfers the value of a special register into a regular register. PUT goes the other way round, transferring the value from a regular register or a constant to a special register.

To indicate one of the special registers, use the predefined constants rA…rZ as well as rBB, rTT, rWW,rXX,rYY and rZZ.

The following registers are read only in user mode: rC, rL, rN, rO, rS, rI, rT, rTT, rK, rQ, rU and rV.

It is not possible to store a value in rG that is less than 32, or less than the current value of rL, or greater than 255.

It is not possible to store a value in rA that is greater than #3FFFF.

The Y field must be zero (but can be omitted).

TRIP

Name:

TRIP X,Y,Z

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

Timing:

Description:

Causes a Trip interrupt and jumps to the Trip handler at address #00.

See also:

TRAP and RESUME

TRAP

Name:

TRAP X,Y,Z

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

Timing:

Description:

Causes a Trap Interrupt and executes a Trap Handler inside the operating system at address rT.

See also:

TRIP and RESUME

RESUME

RESUME Z

Specification: Incomplete
@ ←rW-4

Timing:

Description:

Undoes the effect of a previous TRIP or TRAP instruction.

See also:

TRIP and TRAP

LDUNC and STUNC

Name:

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

Specification:
s($X) ← s(M8[$Y + $Z]) or
s(M8[$Y + $Z]) ← $X

Timing:

1υ + 1μ

Description:

Load or store an octabyte, similar to LDO and STO, without using the cache.

See also:

LDO and STO.

PRELD, PREST, and PREGO

Name:

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

Timing:

Description:

Informs the machine that the content of the memory region from $Y+$Z to X+$Y+$Z will

  • probably soon be used in a load or store instruction (PRELD),
  • definitively be written before the next load (PREST), or
  • probably soon be used as an instruction (PREGO).

SYNC

Name:

SYNC XYZ

Timing:

Description:

Needed to synchronize processes. XYZ has a value from 0 to 7, where values greater 3 are reserved for the operating system.

SYNCID

Name:

SYNCID X,$Y,$Z

Timing:

SYNCID: υ

Description:

Synchronize instruction and data cache in the region $Y+$Z to X+$Y+$Z.

SYNCD

Name:

SYNCD X,$Y,$Z

Timing:

SYNCD: υ

Description:

Synchronize data cache und main memory in the region $Y+$Z to X+$Y+$Z.

The LDVTS Instruction

Name:

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

Timing:

Description:

Load virtual translation table. Modifies the tables used to cache translations from virtual to physical addresses.

SWYM

Name:

SWYM X,Y,Z

Timing:

Description:

Sympathize with your machinery. This instruction gives the MMIX CPU a short break.

Assembler Instructions

Defining Names with IS

Name:

Label IS Expression

Description:

Tells the assembler that Label is used from now on to stand for Expression. The Expression can use previously defined names. The IS instruction can be used to define names for registers.

See also:

PREFIX .

The LOC instruction

Name:

LOC Expression

Specification:
@ ← Expression

Description:

Defines the new current location in memory. The assembler always places instructions and data in memory at the current location, incrementing the current location as needed. The symbol @ ("The location where we are at") can be used for the current location in an expression.

In user mode, the program has access to four segments in main memory:
SegmentSymbolStart addressUse
Text Segment   #0

Program and static data

Data SegmentData_Segment #2000000000000000

variable Data

Pool Segment Pool_Segment #4000000000000000  
Stack Segment Stack_Segment#6000000000000000  

Assembling Data

Name:

BYTE Expressions
WYDE Expressions
TETRA Expressions
OCTA Expressions

Description:

These instructions are used to assemble predefined data. The comma separated expressions will be evaluated and then padded with zeros to have the required size (1, 2, 4 or 8 byte). The values will be put in memory before the program starts.

Strings (enclosed in double quotes) denote a list of ASCII values. Note: These values, too, will be padded to have the required size.

Defining global Registers with GREG

Name:

GREG Expression

Description:

Allocates a new global register. The expression is evaluated and is used to initialize the global register before the program starts. If the value is not zero, mmixal assumes that the value is constant and can be used in address calculations.

Register $255 is always a global register. The first GREG will allocate $254 and the next $253, and so on.

An optional label can be used to give a name to the new global register.

Defining Namespaces with PREFIX

Name:

PREFIX Name

Specification:
Set the current prefix to Name.

Description:

Every name in a program is either complete or incomplete. A name is complete, if it starts with a colon (:), otherwise it is incomplete. Incomplete names are completed by adding the current prefix to them.

At the very beginning of assembling a program, the current prefix is just the colon (:). This situation can be restored any time by saying "PREFIX :".

The LOCAL Instruction

Name:

LOCAL Expression

Description:

This instruction declares the Expression as a local register. The assembler will issue an error message if at the end of assembling the file, rG is not greater than all the register number declared to be local. The LOCAL instruction is only necessary for register numbers greater or equal to 32, since registers with smaller numbers are never global.

See also:

PUSHJ

BSPEC and ESPEC

Name:

BSPEC Expression
ESPEC

Description:

BSPEC stands for "Begin Special Mode" and ESPEC stands for "End Special Mode".

The assembler writes the text between these two instructions directly to the output file, but does not load it as part of the assembled program. This mechanism can be used to transmit information from the source to the object file for later use. For instance high level languages might embed debug information into the object file.

Regular MMIX instructions are not allowed in special mode, however, the pseudo instructions IS, PREFIX, BYTE, WYDE, TETRA, OCTA, GREG, and LOCAL are allowed.

The Expression following BSPEC should fit into two byte and can be used to pass information regarding format and type of the following information. For example BSPEC 1 might be used to pass source line numbers and BSPEC 2 for source file names.

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