Skip to content

The MMIX Instruction Set#

Instructions in the MMIX architecture are always 32 bits wide. These bits are divided into four groups of 8 bits.

MMIX Instruction Structure

The opcode bits uniquely identify each instruction, while the other three groups specify the operands with which the instruction is to be executed.

When a general-purpose register `n is used as an operand, the corresponding bits are just the n in unsigned integer representation.

When a special register, it is represented in binary according to the following table:

Special Register Binary Representation
rB 0x00
rD 0x01
rE 0x02
rH 0x03
rJ 0x04
rM 0x05
rR 0x06
rBB 0x07
rC 0x08
rN 0x09
r0 0x0A
rS 0x0B
rI 0x0C
rT 0x0D
rTT 0x0E
rK 0x0F
rQ 0x10
rU 0x11
rV 0x12
rG 0x13
rL 0x14
rA 0x15
rF 0x16
rP 0x17
rW 0x18
rX 0x19
rY 0x1A
rZ 0x1B
rWW 0x1C
rXX 0x1D
rYY 0x1E
rZZ 0x1F

These representations overlap with those of general-purpose register. This ambiguity is resolved by allowing only certain registers, either general-purpose or special, to be used with a given instruction.

The instructions themselves and their representations can be found in the following table:

MMIX Instruction Representations
0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7
0x0 TRAP FCMP FUN FEQL FADD FIX FSUB FIXU 0x0
FLOT[I] FLOTU[I] SFLOT[I] SFLOTU[I]
0x1 FMUL FCMPE FUNE FEQLE FDIV FSQRT FREM FINT 0x1
MUL[I] MULU[I] DIV[I] DIVU[I]
0x2 ADD[I] ADDU[I] SUB[I] SUBU[I] 0x2
2ADDU[I] 4ADDU[I] 8ADDU[I] 16ADDU[I]
0x3 CMP[I] CMPU[I] NEG[I] NEGU[I] 0x3
SL[I] SLU[I] SR[I] SRU[I]
0x4 BN[B] BZ[B] BP[B] BOD[B] 0x4
BNN[B] BNZ[B] BNP[B] BEV[B]
0x5 PBN[B] PBZ[B] PBP[B] PBOD[B] 0x5
PBNN[B] PBNZ[B] PBNP[B] PBEV[B]
0x6 CSN[I] CSZ[I] CSP[I] CSOD[I] 0x6
CSNN[I] CSNZ[I] CSNP[I] CSEV[I]
0x7 ZSN[I] ZSZ[I] ZSP[I] ZSOD[I] 0x7
ZSNN[I] ZSNZ[I] ZSNP[I] ZSEV[I]
0x8 LDB[I] LDBU[I] LDW[I] LDWU[I] 0x8
LDT[I] LDTU[I] LDO[I] LDOU[I]
0x9 LDSF[I] LDHT[I] CSWAP[I] LDUNC[I] 0x9
LDVTS[I] PRELD[I] PREGO[I] GO[I]
0xA STB[I] STBU[I] STW[I] STWU[I] 0xA
STT[I] STTU[I] STO[I] STOU[I]
0xB STSF[I] STHT[I] STCO[I] STUNC[I] 0xB
SYNCD[I] PREST[I] SYNCID[I] PUSHGO[I]
0xC OR[I] ORN[I] NOR[I] XOR[I] 0xC
AND[I] ANDN[I] NAND[I] NXOR[I]
0xD BDIF[I] WDIF[I] TDIF[I] ODIF[I] 0xD
MUX[I] SADD[I] MOR[I] MXOR[I]
0xE SETH SETMH SETML SETL INCH INCMH INCML INCL 0xE
ORH ORMH ORML ORL ANDNH ANDNMH ANDNML ANDNL
0xF JMP[B] PUSHJ[B] GETA[B] PUT[I] 0xF
POP RESUME SAVE UNSAVE SYNC SWYM GET TRIP
0x8 0x9 0xA 0xB 0xC 0xD 0xE 0xF

Each row corresponds to the hexadecimal value of the most-significant nibble of the cells in it:

  • If a cell is in the top sub-row of its row, then the top row of the table is used for finding its least-significant nibble.
  • If a cell is in the bottom sub-row of its row, then the bottom row of the table is used for finding its least-significant nibble.

Each column corresponds to the least-significant nibble of the cells under it. When a cell spans two columns:

  • Use the left column for the normal variant.
  • Use the right column for the [I] / [B] variant.

The row of a cell corresponds to the hexadecimal value of its most-significant nibble.