
Content

The MMIX Instruction Set
The descriptions below are translated from the
MMIX Buch.
Content
Name:
ADD $X,$Y,$Z  ADD $X,$Y,Z 
SUB $X,$Y,$Z  SUB $X,$Y,Z 
MUL $X,$Y,$Z  MUL $X,$Y,Z 
DIV $X,$Y,$Z  DIV $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:  1υ
 SUB:  1υ
 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.

Name:
ADDU $X,$Y,$Z  ADDU $X,$Y,Z 
SUBU $X,$Y,$Z  SUBU $X,$Y,Z 
MULU $X,$Y,$Z  MULU $X,$Y,Z 
DIVU $X,$Y,$Z  DIVU $X,$Y,Z 
Specification:
ADDU:  u($X) ← (u($Y) + u($Z)) mod 2^{64} 
SUBU:  u($X) ← (u($Y) u($Z)) mod 2^{64} 
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 2^{64}
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
highprecision 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,$Z  NEGU $X,Y,Z 

Specification:
NEG: s($X)  ← Y  s($Z)
 NEGU: u($X)  ← (Y  u($Z))mod2^{64}

Timing:
1υ
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,$Z  CMPU $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:
1υ
Description:
Compares two integer numbers. The result can be used to control
Branches or
Conditional Set instructions.

Floating Point Conversion
Name:
Specification:
FLOT:  f($X)  ← s($Z)
 FLOTU:  f($X)  ← u($Z)
 FIX:  s($X)  ← int(f($Z))
 FIXU:  u($X)  ← (int(f($Z)))mod2^{64}

Timing:
4υ
Description:
Converts numbers from integer representation to floating point representation
and vice versa.
An optional YOperand 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 ynz, 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)^{1∕2}

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 YOperand
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≤ ε 2^{eq}},
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
[mmixdoc].

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:
4υ
Description:
Converts an integer number to 32bit IEEE floating point format.
The number is first converted to T, a 32bit intermediate value.
This conversion might cause rounding. After this conversion, the
number T is extended to a 64bit floating point number.
The Yoperand may contain a rounding mode similar to the FLOT instruction.
See also:
FLOT and FLOTU.

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,$Z  ANDN $X,$Y,Z 
ORN $X,$Y,$Z  ORN $X,$Y,Z 
NAND $X,$Y,$Z  NAND $X,$Y,Z 
NOR $X,$Y,$Z  NOR $X,$Y,Z 
NXOR $X,$Y,$Z  NXOR $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.
a  b  AND(&)  OR()  XOR(ˆ)
 NAND( ˜ & )  NOR(˜ )  NXOR(˜ ˆ)
 ANDN(\)  ORN(˜ ) 
0  0  0  0  0 
1  1  1  0 
1 
1  0  0  1  1 
1  0  0  1 
1 
0  1  0  1  1 
1  0  0  0 
0 
1  1  1  1  0 
0  0  1  0 
1 
Timing:
1υ
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,$Z  SLU $X,$Y,Z 
SR $X,$Y,$Z  SR $X,$Y,Z 
SRU $X,$Y,$Z  SRU $X,$Y,Z 

Specification:
SL: s($X)  ← s($Y) × 2^{u($Z)}
 SLU: u($X)  ← (u($Y) × 2^{u($Z)}) mod 2^{64}
 SR: s($X)  ← ⌊s($Y) / 2^{u($Z)}⌋
 SRU: u($X)  ← ⌊u($Y) / 2^{u($Z)}⌋

Timing:
1υ
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):
y_{00}y_{01}...y_{07} y_{10}y_{11}...y_{17} ... y_{70}y_{71}...y_{77}
Now bit x_{ij} in register register $X is computed as follows:
MOR: 
x_{ij} = y_{0j}& z_{i0}  y_{1j}& z_{i1}  ...  y_{7j}& z_{i7}
 MXOR: 
x_{ij} = y_{0j} & z_{i0} ˆ y_{1j} & z_{i1} ˆ ... ˆ y_{7j} & z_{i7}

Timing:
1υ
Description:
These instructions regard the 8 Byte of a register as a 8×8Matrix
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,$Z  BDIF $X,$Y,Z 
WDIF $X,$Y,$Z  WDIF $X,$Y,Z 
TDIF $X,$Y,$Z  TDIF $X,$Y,Z 
ODIF $X,$Y,$Z  ODIF $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:
1υ
Description:
Saturated Difference. An Octa byte is regarded as a vector of
eight byte, four Wyde, or two Tetra respectively.

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
AndNot (\) operation or the Or () operation:
ANDNH  or ORH: $X  ← $X ⊙ YZ×2^{48}
 ANDNMH  or ORMH: $X  ← $X ⊙ YZ×2^{32}
 ANDNML  or ORML: $X  ← $X ⊙ YZ×2^{16}
 ANDNL  or ORL: $X  ← $X ⊙ YZ

Timing:
1υ
Description:
Bitwise operation on a 16bit 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
MultiplexMaskRegisters 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.

The Pseudo Instruction LDA
Name:
Specification:
Timing:
1υ
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 16bit immediate
operands.
See also:
ADDU,
Bitwise Operations with 16Bit Immediate Values.

Get Address (GETA)
Name:
GETA $X,Label
Specification:
u($X)  ← RA, with
 RA  ← @+ 4*YZ with forward references
 RA  ← @+4*(YZ2^{16}) for backward references

Timing:
1υ
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,$Z  16ADDU $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 × 2^{48}
 SETMH: u($X)  ← YZ × 2^{32}
 SETML: u($X)  ← YZ × 2^{16}
 SETL: u($X)  ← YZ

Timing:
1υ
Description:
This instruction are used to load 16bit 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 16Bit 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 × 2^{48}) mod 2^{64}
 INCMH: u($X)  ← (u($X) + YZ × 2^{32}) mod 2^{64}
 INCML: u($X)  ← (u($X) + YZ × 2^{16}) mod 2^{64}
 INCL: u($X)  ← (u($X) + YZ) mod 2^{64}

Timing:
1υ
Description:
This collection of increment instructions will first shift the 16bit
immediate value to the left by 6, 4, 2, or 0 byte before adding it
to $X.
See also:
ORH, ANDNH, and SETH.

Name:
LDB $X,$Y,$Z  LDB $X,$Y,Z  Load Byte/Load Byte Immediate 
LDW $X,$Y,$Z  LDW $X,$Y,Z  Load Wyde/Load Wyde Immediate 
LDT $X,$Y,$Z  LDT $X,$Y,Z  Load Tetra/Load Tetra Immediate 
LDO $X,$Y,$Z  LDO $X,$Y,Z  Load Octa/Load Octa Immediate 

Specification:
With A ← $Y+$Z respectively A ← $Y+Z we have:
LDB: s($X)  ← s(M_{1}[A])
 LDW: s($X)  ← s(M_{2}[A])
 LDT: s($X)  ← s(M_{4}[A])
 LDO: s($X)  ← s(M_{8}[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.

Name:
STB $X,$Y,$Z  STB $X,$Y,Z  Store Byte/Store Byte Immediate 
STW $X,$Y,$Z  STW $X,$Y,Z  Store Wyde/Store Wyde Immediate 
STT $X,$Y,$Z  STT $X,$Y,Z  Store Tetra/Store Tetra Immediate 
STO $X,$Y,$Z  STO $X,$Y,Z  Store Octa/Store Octa Immediate 

Specification:
With A ← $Y+$Z respectively A ← $Y+Z we have:
STB: s(M_{1}[A])  ← s($X)
 STW: s(M_{2}[A])  ← s($X)
 STT: s(M_{4}[A])  ← s($X)
 STO: s(M_{8}[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:
Specification:
With A ← $Y+$Z respectively A ← $Y+Z we have:
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.

Name:
LDBU $X,$Y,$Z  LDBU $X,$Y,Z 
LDWU $X,$Y,$Z  LDWU $X,$Y,Z 
LDTU $X,$Y,$Z  LDTU $X,$Y,Z 
LDOU $X,$Y,$Z  LDOU $X,$Y,Z 
Specification:
With A ← $Y+$Z respectively A ← $Y+Z we have:
LDBU: u($X)  ← u(M_{1}[A])
 LDWU: u($X)  ← u(M_{2}[A])
 LDTU: u($X)  ← u(M_{4}[A])
 LDOU: u($X)  ← u(M_{8}[A])

Timing:
1μ + 1υ
Description:
Loads one byte, wyde, tetrabyte, or octabyte. The value is padded with zeros to the left
to fill the 64bit 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.

Name:
STBU $X,$Y,$Z  STBU $X,$Y,Z 
STWU $X,$Y,$Z  STWU $X,$Y,Z 
STTU $X,$Y,$Z  STTU $X,$Y,Z 
STOU $X,$Y,$Z  STOU $X,$Y,Z 
Specification:
With A ← $Y+$Z respectively A ← $Y+Z we have:
STBU: u(M_{1}[A])  ← u($X) mod 2^{8}
 STWU: u(M_{2}[A])  ← u($X) mod 2^{16}
 STTU: u(M_{4}[A])  ← u($X) mod 2^{32}
 STOU: u(M_{8}[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,$Z  LDHT $X,$Y,Z 

Specification:
u($X)  ← u(M_{4}[$Y + $Z]) × 2^{32}

Timing:
1υ + 1μ
Description:
Loads one tetrabyte from main memory into the hightetra (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,$Z  STHT $X,$Y,Z 

Specification:
u(M_{4}[$Y + $Z]) 
← ⌊u($X)∕2^{32}⌋

Timing:
1υ + 1μ
Description:
Store the HighTetra (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,$Z  LDSF $X,$Y,Z 
STSF $X,$Y,$Z  STSF $X,$Y,Z 

Specification:
LDSF: f($X)  ← f(M_{4}[$Y + $Z])
 STSF: f(M_{4}[$Y + $Z])  ← f($X)

Timing:
1υ + 1μ
Description:
Loads respectively stores a 32bit floating point number. Before storing,
respectively after loading, a conversion from, respectively to,
the 64bit floating point format is done.
See also:
LDT and STT (for 32bit fixed point numbers).

Jumps with Relative Addresses
Name:
Specification:
@  ← RA with
 RA  ← @+4*XYZ for a jump forward,
 RA  ← @+4*(XYZ2^{24}) for a jump backward.

Timing:
1υ
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:
Specification:
Timing:
3υ
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

Name:
BZ $X,YZ  PBZ $X,YZ  (Probable) Branch if zero 
BNZ $X,YZ  PBNZ $X,YZ  (Probable) Branch if nonzero 
BN $X,YZ  PBN $X,YZ  (Probable) Branch if negative 
BNN $X,YZ  PBNN $X,YZ  (Probable) Branch if nonnegative 
BP $X,YZ  PBP $X,YZ  (Probable) Branch if positive 
BNP $X,YZ  PBNP $X,YZ  (Probable) Branch if nonpositive 
BOD $X,YZ  PBOD $X,YZ  (Probable) Branch if odd 
BEV $X,YZ  PBEV $X,YZ  (Probable) Branch if even 

Specification:
With RA ← @+4*YZ for forward branches
and RA ← @+4*(YZ2^{16}) 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.

Name:
CSZ $X,$Y,$Z  CSZ $X,$Y,Z  ZSZ $X,$Y,$Z  ZSZ $X,$Y,Z 
CSNZ $X,$Y,$Z  CSNZ $X,$Y,Z  ZSNZ $X,$Y,$Z  ZSNZ $X,$Y,Z 
CSN $X,$Y,$Z  CSN $X,$Y,Z  ZSN $X,$Y,$Z  ZSN $X,$Y,Z 
CSNN $X,$Y,$Z  CSNN $X,$Y,Z  ZSNN $X,$Y,$Z  ZSNN $X,$Y,Z 
CSP $X,$Y,$Z  CSP $X,$Y,Z  ZSP $X,$Y,$Z  ZSP $X,$Y,Z 
CSNP $X,$Y,$Z  CSNP $X,$Y,Z  ZSNP $X,$Y,$Z  ZSNP $X,$Y,Z 
CSOD $X,$Y,$Z  CSOD $X,$Y,Z  ZSOD $X,$Y,$Z  ZSOD $X,$Y,Z 
CSEV $X,$Y,$Z  CSEV $X,$Y,Z  ZSEV $X,$Y,$Z  ZSEV $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:
1υ
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.

PUSHJ and PUSHGO
Name:
PUSHJ $X,YZ
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 $rL1 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  2^{16}) (PUSHJB) or
 @  ← $Y + $Z (PUSHGO) or
 @  ← $Y + Z (PUSHGOI)

The PUSHJOperation 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 16bit 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:
3υ
Description:
The POP instruction undoes the effect of a previous PUSHJ Instruction.
X indicates the number of return values in registers $0 to $(X1),
where $(X1) 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(M_{8}[$Y + $Z]) = rP
then u(M_{8}[$Y + $Z]) ← $X and $X ← 1
otherwise rP ← u(M_{8}[$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.

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

Timing:
1υ
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:
5υ
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:
5υ
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
Timing:
5υ
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(M_{8}[$Y + $Z]) or
 s(M_{8}[$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:
Timing:
1υ
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:
1υ
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:
1υ
Description:
Load virtual translation table. Modifies the
tables used to cache translations from virtual to physical addresses.

SWYM
Name:
SWYM X,Y,Z
Timing:
1υ
Description:
Sympathize with your machinery.
This instruction gives the MMIX CPU a short break.

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:
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:
Segment  Symbol  Start address  Use 
Text Segment   #0 
Program and static data 
Data Segment  Data_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.

