Help for MMIXIDE

The MMIX Integrated Development Environment

Table of Content

  • MMIX
    • The MMIX Instruction Set
    • Debugging
    • Displaying and Editing Memory and Registers
    • The Breakpoint Window
    • The Symbol Table Window
    • The Build system
  • The User Interface
    • Options
    • Find and Replace Dialog
    • Splitter Bars
    • Menus (to be written)
    • Editor (see also: www.scintilla.org)
      • Key Bindings


The MMIX Instruction Set

  • Integer Arithmetic
  • Floating Point Arithmetic
  • Bits and Bytes
  • Address Computations
  • Load and Store
  • Jumps and Branches
  • Subroutines and Processes
  • Special Registers and System Programming
  • Assembler Instructions


Integer Arithmetic

  • Signed Arithmetic
  • Unsigned Arithmetic
  • Negation
  • Comparison


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.

See also:

Unsigned Arithmetic.


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

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,$Z | NEGU $X,Y,Z

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

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 Arithmetic

  • Floating Point Conversion
  • Floating Point Arithmetic
  • Comparing Floating Point Numbers
  • Conversion of Short Floats


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:

4υ

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

4υ

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 Operators
  • Shifting
  • Multiple OR
  • Bytewise Saturated Difference
  • Logical Operations with 16-Bit Immediate Values
  • Sideways Add
  • Bit Multiplexing


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

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

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:

1υ

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:

1υ

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:

1υ

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

  • Load Address
  • Get Address
  • Scaled Index Address
  • Set with 16-Bit Immediate Values
  • Increment with 16-Bit Immediate Values


The Pseudo Instruction LDA

Name:

LDA $X,Label

Specification:

LDA: u($X) ← Label

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 16-bit immediate operands.

See also: ADDU and 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:

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 × 248
SETMH: u($X) | ← YZ × 232
SETML: u($X) | ← YZ × 216
SETL: u($X) | ← YZ

Timing:

1υ

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:

1υ

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
  • Storing Signed Integers
  • Storing Constant Octas
  • Loading Unsigned Data
  • Storing Unsigned Data
  • Storing the High Tetra
  • Loading and Storing Short Floats


Loading Signed Integers

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

See also:

Storing Unsigned Data.


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.


Loading Unsigned Data

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.

See also:

Loading Signed Integers.


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.

See also:

Storing Signed Integers.


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.

See also:

LDHT and STT.


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.

See also:

STHT and LDT.


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(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
  • Jumps with Absolute Addresses
  • Branches
  • Conditional Assignments


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:

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:

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

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

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


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:

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.


Subroutines and Processes

  • PUSHJ and PUSHGO
  • POP
  • SAVE and UNSAVE
  • CSWAP


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:

3υ

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
  • TRIP
  • TRAP
  • RESUME
  • Load and Store Uncached
  • Preloading the Cache
  • Synchronize Processes
  • Synchronize Data and Instruction Cache
  • Sychronize Data Cache and Main Memmory
  • Manage Virtual Memory
  • Symathise With Your Machinery


PUT and GET

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

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


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
@ ←rW-4

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

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.


Assembler Instructions

  • Defining Names with IS
  • LOC
  • Assembling Data
  • Allocating Global Registers
  • Namespaces
  • Testing for Local Registers
  • Special Mode


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


The MMIX Debugger

If an MMIX source file is in the editor, you can start the MMIX simulator in debugging mode either by
  • Selecting "Debug" from the "MMIX" menu.
  • Pressing the F5 key.
  • Pressing the Debugg/Continue Button [image] .
If the source file has changed, you will be asked if you want to save your changes. Then you will be asked whether you want to assemble the source file (unless the mmo file on disk is newer than the source file.) Running the assembler will also collect information about connecting the lines and symbols in your source file to locations in memory. This infomation is necessary while debugging. If the assembler has finished without errors, debugging will start.

Once the debugger has started a collection of new buttons is displayed in the button bar. These buttons are a more convenient alternative to the commands that you find in the MMIX menu.

You can further customize the debuggers behaviour through the Debug Options dialog, which you can access through the Options menu.

Running, Stopping, and Stepwise Execution

  • Debugg/Continue
    Continue execution instructions until a breakpoint or the end of the Program is reached. This function can also be invoked by pressing the F5 key.

  • Step Instruction
    Execute one instruction and stop again.

  • Step Over
    Like Step Instruction, unless the current instruction is a PUSHJ or PUSHGO instruction. In this case run the program without stopping until the corresponding POP instruction is executed (unless a breakpoint or the end of the program intervenes).

  • Step Out
    Continue execution until the end of the current subroutine (unless a breakpoint or the end of the program intervenes).

  • Break Execution
    Interrupt a running execution, as if a breakpoint was hit.

  • Halt Execution
    Terminate the debugging session.

Setting Breakpoints and Tracepoints

There are three buttons to toggle (set or unset) breakpoints and one button to toggle a tracepoint. To set a breakpoint move the cursor in the edit window to the line containing the instruction and press the appropriate button.
  • toggle an execute breakpoint. The program will stop after or before executing the first instruction on this line.

    Execute breakpoint exampe:

    You can toggle execute breakpoint also directly by clicking with the mouse in the margin.

  • toggle a read breakpoint. The program will stop after any read access to this memory location.

    Read breakpoint exampe:

  • toggle a write breakpoint. The program will stop after any write access to this memory location.

    Read and write breakpoint exampe:

  • toggle a tracepoint. This instruction will be shown in the trace window each time it is executed.

    Tracepoint exampe:


The MMIX Inspector and Data Editor

The MMIX insprector windows allow the inspection of memory locations and registers.

The Memory Inspector

The memory inspector shows the content of memory locations in various formats.

In the top left corner of the inspector you find an edit box, where you can enter an address. This address is used to position the display of memory locations below at the given address.

Next to it, on the right, there is the format button. Pressing it will change the format used to display the memory content. The choices are

  • Hex, for hexadecimal display.
  • ASCII, for display of ascii codes as characters. Note that only characters in the range from 0x20 to 0x7F are displayed, characters outside this range are displayed as small black rectangles.
  • Unsigned, for displaying the content as unsigned numbers.
  • Signed, for displaying the content as signed numbers assuming two's-complement representation.
  • Float, for displaying the content as floating point numbers assuming a representation that conforms to the IEEE Standard.

Next to the right comes the chunk size button. Pressing it will change the size of the memory chunks that are displayed below. You can choose between

  • Byte (8 bits),
  • Wyde (2 bytes or 16 bits),
  • Tetra (4 bytes or 32 bits), and
  • Octa (8 bytes or 64 bits).

You can combin any chunk size with any format, except that the Float format is available only for Tetra or Octa sized chunks.

Below these Buttons, are several lines showing the content of memory locations.

Each line starts with the address of the first byte shown in this line. Then the memory content is shown using the selected chunk size and format.

Changes

Whenever the program changes the content of a memory location currently visible in the display, the content is shown in red. This should help you spot the point where changes occur in memory.

Alignment

The individual chunks are aligned; that is, an Octa will start at an address that is a multiple of 8, a Tetra will start at an address that is a multiple of 4, and a Wyde will start at an address that is even.

Scrollbar

On the right side of the window is a scrollbar. You can use it to scroll up and down in the displayed memory region. When the scrollbar reaches the bottom of the window, you still can continue to scroll down by using the page down button of the scroll bar. The same is true when you reach the top of the window with the restriction, that you can not scroll past the address given in the top left edit window.

The Register Inspector

The register inspector works is very similar to the memory inspector. There is, however, no edit boy to enter a start address, and each line starts with a register name instead of an address.

Local Registers and Register Stack

The window that shows the local registers will dynamicaly update to show only the current local registers. Registers that become marginal will disappear from the display.

If the display of the register stack is enabled (either automaticaly by selecting the appropriate check box in the Debugger Options, or manualy in the Register submenu of the View menu), also the registers hidden on the register stack are shown. These registers are shown in light gray using the register numbers that they will have once they become accessible again. The register that separates the current local registers from the hidden registers below contains the size of the next stack frame. Instead of the register name, just a hyphen is shown, because this register will never become visible, execpt if overwritten by a return value.

The Data Editor

Memory and register inspectors can be used to inspect data, but you can not use them to alter data. For this purpose you need the Data Editor.

To open the Data Editor, just double-click on any data item on display in an inspector window. If a data editor is not yet open, a new data editor will be created; otherwise, the existing data editor will be repositioned to the data item just double clicked.

The data editor has a format button and a chunk size button just as a memory inspector. In addition it features a Load and a Store button.

  • Pressing the Load button will reload the content from the memory (or register) into the data editor, just as a load instruction of the CPU would do.
  • Pressing the Store button will store the content shown in the data editor back to the memory loaction or register, just as a store instruction of the CPU would do.

Unlike an inspector, the data editor will display just the data selected by the double click; that is, at most one Octa. Of course, the chunk size can be made smaller later on, for example to split an Octa into four Wydes as shown above.

The data is displayed in a number of edit boxes, that can be altered as usual, as long as they conform to the specified format.


Splitter Bars

Splitter bars are used to split a window into several window panes, each with its own content. Using the mouse on the splitter bar, you can manipulate the size and location of these window panes or you can close an adjacent window pane completely. To achive these operations, the splitter bar has serveral different regions:

There are two end regions that look like this [image], containing each a move button ( [image]) and a close button ( [image]). Between the two end regions is the main region of the the splitter bar and in the center of the main region is the turn button ( [image])

Draging a splitter bar

This is the simplest and most common operation. You can drag a horizontal splitter bar up or down and a vertical splitter bar right or left.

To do so:

  • Move the mouse to the main region (including the turn button) of the splitter bar.
  • Observe how the cursor will change to a left/right (or up/down) arrow.
  • Press the left mouse button,
  • drag the splitter bar to its new position, and
  • release the mouse button.

Turning the splitter bar

You can turn the splitter bar counter clock wise by 90 degree. Doing this four times will bring the splitter bar back to its initial position.

To do so:

  • Move the mouse to the turn button in the center of the main region.
  • Observe how the cursor will change to a left/right (or up/down) arrow.
  • Double click the left mouse button.

Moving a window pane

You can move a window pane to any position inside the window using one of the move buttons in the end regions. The move button is a small triangle pointing to one of the adjacent window panes; using the move button will change the position of the the window pane it points to.

To do so:

  • Move the mouse to the correct move button.
  • Observe how the cursor will change to a left/right/up/down arrow.
  • Press the left mouse button.
  • The adjacent window pane will disapear, and
  • instead a grey rectangle will be displayed.
  • Drag the rectangle to the desired position.

    Note how the rectangle is always part of a window pane or a group of window panes.

    • Drag the grey rectangle to the upper border of the enclosing window pane to relocate the window in the top part of the enclosing window pane.
    • Drag the grey rectangle to the lower border of the enclosing window pane to relocate the window in the bottom part of the enclosing window pane.
    • Drag the grey rectangle to the right border of the enclosing window pane to relocate the window in the right part of the enclosing window pane.
    • Drag the grey rectangle to the left border of the enclosing window pane to relocate the window in the left part of the enclosing window pane.
    • Two window panes or groups of window panes separated by a splitter bar form a group of window panes. Grouping window panes organizes the window panes as a binary tree.
    • If you drag the rectangle closer to the border, the grey rectangle moves towards the root of this binary tree. That is, the window pane will be relocated to the top, bottom, left, or right of the entire window group. (This sounds complicated but is quite intuitive to use. Just try it!)
  • Release the mouse button.

Closing one of the adjacent window panes

You can close either of the adjacent window panes by using one of the close buttons. The move button next to the close button points to the affected window pane.

To close an adjacent window pane:

  • Move the mouse to one of the close button in the end region.
  • Observe that the move button next to it points to an adjacent window pane.
  • Double click the left mouse button to close this adjacent window pane.


The MMIX Breakpoint Window

This window lets you manage breakpoints.

When the window is opended, it displays a listbox with all currently set breakpoints. For example on the right you see four breakpoints: an execute breakpoint at address #144, a read and write breakpoint in file hello.mms, line 6, an execute breakpoint in the same file at line 10, and finaly again in the same file a trace point in line 13.

Before you can modify one of these breakpoints, you must select it by clicking on it. The breakpoint is the shown higlighted (with a blue background).

You can the remove the breakpoint by pressing the Remove button.

You can add an execute, read, write, or trace breakpoint for the selected breakpoint by pressing the blue, green, red, or black button respectively. Pressing the button a second time will remove it again.

When you double click on a breakpoint showing a file and a line number, the cursor in the edit window will move to the specified line.

There are two types of breakpoints shown in this list: breakpoints that are bound to a specific line in a sourcefile and breakpoints that are bound to a specific address. You must add breakpoints of the first kind using the editor. You can add breakpoints of the second kind by entering the address in hexadecimal notation in the editbox shown left of the Add button and then pressing the Add button.

When you edit the file, the editor will move around the breakpoints in the text together with the text. These changes are not shown in breakpoint list. However when you start the debugger, the list will be updated.

If you change the source file while the program is running, neither the breakpoints in the running program nor the breakpoints in the list will be updated. This is not a good idea. You should stop debugging, edit the file, then assemble it again, and finaly restart the debugger.


The MMIX Symbol Table Window

This window lets you see the symbol table.

You can open or close the symbol table window by selecting the "Symbol table" Entry in the View Menu.

When the window is opended, it displays a listbox with the symbols defined in the assembled program.

Hint: If the listbox is empty, assemble the program (press F7) and you will see the symbols defined in the program.

You can use the symbol table to move around in your program. If you double click a symbol in the list the cursor will be repositioned in the source file to the line where this symbol is defined.

You can specify which symbols get listed in the symbol table list using the symbol table options dialog. To do so open the Options Menu and select "Symbol table ...".


Options

The Options Menu contains these entries:

  • Editor ...
  • Assembler ...
  • Debug ...
  • Run ...
  • Symbol table ...
  • Sources ...
  • Encoding
    There are two choices for Encoding:
    • UTF-8 and
    • ASCII.


Find and Replace

You reach the Find and Replace Dialog

  • through the Edit menu, or
  • by clicking the Find/Replace button
  • by typing Ctrl-F.

Find

Enter the string you want to find in the `Find´ edit box and click the `Find Next´ Button to find the next occurence of the string in the text; click the `Find Previous´ Button to search backwards for a previous occurence of the search string.

You can repeat the last search operation using `Find Again´ or simply by typing Ctrl-G.

Replace

To replace a string, enter a replacement text in the `Replace´ edit box; then click the `Find´ Butten one or more times to move the selection in the editor to an occurrence of the find string; and finally press the `Replace´ Button. Pressing the `Replace´ Button will replace the selected occurrence of the find string and automatically advance the selection to the next occurrence of the find string. This is the interactive mode of replacing. If you click the `Replace All´ button, all occurrences of the find string will be replaced immediately.

Instead of clicking the `Replace´ Button, you can use the `Replace Again´ entry in the Edit menu or simply type Ctrl-H.

Match case

If this box is checked, the assembler will produce a listing file. The name of the listing file is the name of the source file with the extension `.mms´ replaced by `.mml´.

Match whole word

If this box is checked, the search will find an occurence of the find string only, if it delimited in the text by non-word characters. Non-word characters are all characters, except alpha-numeric characters, the underscore character and characters with ASCII codes above 0x7F (these are considered characters of foreign alphabets).

Use \t, \n, \r, \xFF

If you check this box, the backslash character `\´ is used as an escape character. But why do you need an escape character?

Non printing characters are difficult or impossible to enter as part of a search or replacement string. For instance you can not type a TAB character in the `Find´ edit box, because when you hit the TAB key, the cursor will just leave the edit box and jump to the next user interface item. To make it possible to enter and see these special characters, the backslash character can be used as an escape character.

When the backslash character is an escape character, you can type

\t for the TAB character (ASCII code 0x08)

\n for the NL (newline) character (ASCII code 0x0A)

\r for the CR (cariage return) character (ASCII code 0x0D)

\xFF where FF are two hexadecimal digits (`0´ to `9´ and `A´ to `F´ or `a´ to `f´) for the character with the given ASCII code.

\\ for the backslash character itself.

If any other character follows a backslash, the backslash is simply ignored.

Wrap around

If this box is checked, a forward search that reaches the end of the text will start searching at the beginning of the text; similarly, a backward search that reaches the beginning of the text will continue searching from the end of the text.


The MMIX Editor Key Bindings

The MMIX editor is implemented using the free scintilla source code editing component. See www.scintilla.org for further details. Therefore the MMIX editor inherits most key bindings from scintilla.

Most of the key bindings are obvious, for example the "Page Down" key will move one page down, and we do not need to list them here. Further, we do not list key bindings here that are very uncommon. The following table lists only the "common unusual" key bindings, that is: key bindings that involve pressing the Shift, Control, or Alt key and are used frequently when editing MMIX source code.

Scroll and Position

Key | Modifier | Binding
Arrow Down | Ctrl | Scroll down one line
Arrow Up | Ctrl | Scroll up one line
Home | Ctrl | Go to document start
End | Ctrl | Go to document end

Cut, Copy, Paste, Delete, and Move

Key | Modifier | Binding
X | Ctrl | Cut Selection
C | Ctrl | Copy Selection
V | Ctrl | Paste Selection
Del | Shift | Delete current line
Del | Ctrl | Delete to end of current line
Backspace | Ctrl | Delete to beginn of current line
Arrow Down | Shift+Ctrl | Move current line (or all lines selected) down
Arrow Up | Shift+Ctrl | Move current line (or all lines selected) up
T | Ctrl | Interchange this and the previous line

Selections

Key | Modifier | Binding
A | Ctrl | Select All
Arrow Down | Shift | Extend selection downward one line
Arrow Up | Shift | Extend selection upward one line
Arrow Left | Shift | Extend selection left by one character
Arrow Right | Shift | Extend selection right by one character

Do and Undo

Key | Modifier | Binding
Z | Ctrl | Undo
Y | Ctrl | Redo

Zoom In and Out

Key | Modifier | Binding
+ | Ctrl | Zoom in
- | Ctrl | Zoom out
/ | Ctrl | Zoom to 100% (Only on numeric keypad)

Indentation and Pretty Printing

Key | Modifier | Binding
I | Ctrl | Automatically adjust indentation


The MMIX Symbol Table Options

You reach the MMIX symbols options through the Options menu.

Even mid-sized MMIX programs contain large numbers of symbols, that can be shown in the symbol table window. To select which symbols you want to see here, there are three check boxes. Symbol table support is currently not yet perfect. But you can open a symbol table view and scroll any symbol into the edit window by clicking on it.

Show Locals

A simple heuristic is used to determine what is a local smbol: global symbols contain only a single colon as the first character. This first caracter is usually not shown.

If this box is checked, local symbols (containing more than one colon) are shown.

Show Registers

If this box is checked, symbols that name registers are shown.

Show small values

Symbols are mainly used for code and data locations. Code locations are typically at #100 and above, data locations are typically above #2000 0000 0000 0000. Symbols that name small values are often not of interest; they are shown only if this box is checked.


The MMIX Editor Options

You reach the MMIX editor options through the Options menu.

Allways save changed files

If this box is checked, changed files will be saved before starting the assembler or running the program automatically without asking. This can be convenient but can also be dangerous becouse it will overwrite files without asking.

Show line numbers

If this box is checked, the edit window will display line numbers (in black) in the left margin.

Show profile

If this box is checked, the edit window will display a Profile in the left margin. The profile shows (in blue) for each line how often it was executed .

Layout and Pretty Printing

Tabulator width

With this control you can set size of the tabulator. For example, setting it to eight means that one tabulator takes up the same space as eight ordinary characters.

Use tabulators for indentation

If this box is checked, the Indent command from the Edit Menu will use Tabulators to achieve indentation. Otherwise, space characters are used.

Maximum label width

The Indent command from the Edit Menu will first measure the size of all the labels. It will then adjust the indentation of all opcodes (and indented comments) to be just one space or tabulator character larger than the largest label. Since this might lead to an unreasonable large indentation, this control can be used to set a maximum width for the this indentation. Labels that are longer will then extend into the opcode column and will be seaprated from the opcode by a single space or tabulator character.

Maximum opcode width

This control has the same effect on the opcode column as the previous control has on the label column (see above).

Maximum argument width

This control has the same effect on the argument column as the two previous controls hae on the label and opcode columns (see above).

Use CR LF for line ends

If this box is checked, the Indent command from the Edit Menu will use the combination of a Carriage Return (CR) and Line Feed (LF) character to terminate lines. This is the usual way to end lines under DOS or Windows. Otherwise, the Indent command will use a single Line Feed (LF) character which is the usual way to end a line under UNIX. Removing the CR characters is then just part of the Indent commands removal of white space at the end of a line.


The MMIX Assembler Options

You reach the MMIX assembler options through the Options menu.

Buffer size

This edit control determines the assemblers buffer size for source lines (the -b command line option of mmixal). Longer lines in the source file will be truncated with a warning showing up in the assembler output window.

Expanden address calculations

If this box is checked, the MMIX assembler will use four instructions to load any required address into register $255. This will make `GREG @´ instructions unnecessary but yields larger and slower code.

Create listing file

If this box is checked, the assembler will produce a listing file. The name of the listing file is the name of the source file with the extension `.mms´ replaced by `.mml´.

Auto assemble

Whenever the debugger starts, it will check whether there is an object file and whether it is newer than the source file. If this is not the case, it might be appropriate to assemble the source file.

If this check box is checked, the source file will be assembled aoutomatically.

If the box is not checked, a message box will pop up and ask he user whether the source file should be assembled before starting the debugger.


The MMIX Debugger Options

You reach the MMIX debugger options through the Options menu.

Inspecting Registers and Memory

In the two boxes on top of the dialog, you can select windows that should open automatically when you start the debugger. In the example above, the window showing the local registers and the register stack will open; further a windows showing the Data Segment. All the other windows, for example one for the global registers, can be opened manually when needed.

Choosing Special Registers for display

Next to the checkbox for the special registers is a Choose button. Pressing it opens a dialog where you can choose which registers to display in the special register window. Depending on the problem you are trying to debug, some registers may be relevant and others not at all. Only the registers selected here will be shown in the special register window.

Customizing Tracing

  • Show Trace:
    If the checkbox is selected, the trace window will open and a detailed trace of the instructions is printed when the program stops or hits a tracepoint. Otherwise, the program will run silent.

  • Break at Main:
    If this checkbox is selected, a breakpoint is added automaticaly at Main. So the program will stop as soon as it enters the Main program.

  • Break after instruction: or
  • Break before instruction:
    Here you can select whether the program stops before or after executing the instruction. This applies to breakpoints as well as to single stepping.

    The "classic" behaviour of the MMIX debuger is to stop after the instruction, so that you can see in the trace what the instruction just has done.

    Other source code debuggers (for example gdb) usualy stop before executing the instruction. This has the advantage, that you can inspect registers and memory before the instruction, that advance the program to the next instruction and see the changes. It can also be convenient to stop at a branch instruction before it gets executet and then see where it will take the machine.

  • Enable stack tracing:
    If this box is checked, the trace will show details of the hidden register stack while tracing. This is equivalent to the -r option of the mmix simulator.

  • Trace exceptions:
    If this boy is checked, all instructions that cause an arithmetic exception will be shown in the trace. This is equivalent to the -e option of the mmix simulator.

    If this box is unchecked, no such information is given.

    If the box is shaded, a subset of the eight possible arithmetic exceptions has be selected for tracing. To change the set of traced exceptions press the Choose button to the right. A window will open that lets you select or deselect the various arithmetic exceptions for tracing.

  • Warn if no application:
    If this box is checked, the debugger will issue a warning message when you try to start a program, but no file is selected for loading into memory. To select a file for loading, or change this selection use the Sources Dialog Box.

  • The Auto-Close feature for the debug windows is not yet implemented.


The MMIX Run Options

You reach the MMIX run options through the Options menu.

Command line

When an MMIX program enters the `Main´ routine, the resisters $0 and $1 will contain the argument count and the location of the argument vector, respectively.

The argument count is the number of arguments given on the command line. The argument vector is an array of octabytes located at the beginning of the pool segment; these octabytes contain the addresses of the arguments. The arguments are stored as zero terminated ASCII strings in the pool segment as well. Note that the first octabyte in the pool segment contains the address of the first free octabyte in the pool segement.

As an example, if the program starts with the above command line ``hello world´´, you can see in the local register window:

In register $0 is the value 2 (two arguments) and in register $1 is the value #4000 0000 0000 0008, pointing to the second octabyte in the pool segment.

Looking at the pool segement using the pool segment window you can see:

The first octabyte give the address of the free space in the pool segment. The argument vector starts with the second octabyte. The value #4000 0000 0000 0020 is the address of the first argument string; the value of the next octabyte #4000 0000 0000 0028 is the address of the second argument string; and the argument vector is terminated by a zero octabyte. The argument strings are best seen in ASCII format:

Fake StdIn

When an MMIX program reads from Standard Input (handle 0), it usualy reads input characters interactively from the trace window. It is, however, sometimes convenient to use a file to simulate standard input. If a filename is given in this edit box, the data from this file will be used instead of interactive input. It is equivalent to the -f option of the command line MMIX simulator).


The MMIX Sources Options

You reach the MMIX sources options through the Options menu.

Load single file

In a typical MMIX setting, the complete MMIX program is contained in a single source file. If this box is checked, the check boxes below will be set automatically in such a way, that only one source file will be assembled and loaded. If this box is unchecked you are free to assemble and load as many files you want (even none at all). You should then know what you do. Note that programs are loaded into memory using the XOR operation.

Add file

Pressing the Add File button will allow you to browse your disk and add files to the editor.

File Tabs

For each file open in the editor, the tab contoll below will contain one page. Files that are loaded when the debugger starts are marked by a red dot next to the file name.

Full File Name

The first entry on each page shows the full file name,

Assemble and read symbol table

If this box is checked, the source file will be assembled and its symbols will be read into the symbol table.

Execute command

If this box is checked, the following edit box is enabled. You can type any command here. The command will be executed after the source file has been assembled. You man define here some postprocessing.

Load mmo file

If this box is checked, the obejct file produced by the assembler will be loaded into memory.

Checking this box while the ``Load single file´´ is checked will cause the same check box for all other files to be unchecked.