# The MMIX Instruction Set

The descriptions below are translated from the MMIX Buch.

# Integer Arithmetic

## Signed Arithmetic

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.

## 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 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:
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.

## 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))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,\$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:

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,\$Z FLOTU \$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:

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)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 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.

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,\$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:

Description:

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

## 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,\$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:

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.

Name:

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

Timing:

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.

## 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.

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.

Name:

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:

Description:

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

## 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.

## 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.

ORH, ANDNH, and SETH.

Name:

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.

## Storing Signed Integers

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(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.

## The STCO Instruction

Name:
 STCO X,\$Y,\$Z STCO 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.

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(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.

## Storing Unsigned Data

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(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.

## The LDHT Instruction

Name:
 LDHT \$X,\$Y,\$Z LDHT \$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.

STHT and LDT.

## The STHT Instruction

Name:
 STHT \$X,\$Y,\$Z STHT \$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.

LDHT and STT.

Name:
 LDSF \$X,\$Y,\$Z LDSF \$X,\$Y,Z STSF \$X,\$Y,\$Z STSF \$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.

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

# Jumps and Branches

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.

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.

## Branches

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*(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,\$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:

Description:

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

# Subroutines and Processes

## 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 \$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.

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).

## 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.

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.

TRIP and RESUME

## RESUME

RESUME Z

Specification: Incomplete
 @ ←rW-4

Timing:

Description:

Undoes the effect of a previous TRIP or TRAP instruction.

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.

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

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

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

## 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