Auto-generated documentation of the ULM ISA
If you have have a full tex-live installation a documentation can be generated from your isa.txt description. With additional comments the documentation can be further enhanced.
Here some auto-generated Documentation of the ULM Instruction Set.
Installing Tex-Live
ULM generator will create TeX files for the reference manual. You therefor need need a TeX installation. We tested TeX installations on the following platforms:
-
On WSL with sudo apt-get install texlive-full.
-
On MacOS download and install MaxTeX.
How to Generate the Documentation
In the ulm-generator directory run make refman.
Additional Comments for the Instruction Set
Additional comments in isa.txt can enhance the documentation but can enhance it. The above linked documentation was generated from this ISA specification:
RRR (OP u 8) (X u 8) (Y u 8) (Z u 8)
J26 (OP u 8) (XYZ j 24)
U16R (OP u 8) (XY u 16) (Z u 8)
0x01 RRR
# Halt with exit code %X
: halt %X
ulm_halt(ulm_regVal(X));
0x02 RRR
# Read character into %X
: getc %X
ulm_setReg(ulm_readChar() & 0xFF, X);
0x03 RRR
# Print character from %X
: putc %X
ulm_printChar(ulm_regVal(X) & 0xFF);
0x04 J26
# Jump forward or backward
: jmp XYZ
ulm_unconditionalRelJump(XYZ);
0x05 RRR
# Subtract immediate value X from register %Y. Store result in %Z
: subq X, %Y, %Z
ulm_sub64(X, ulm_regVal(Y), Z);
0x06 J26
: jnz XYZ
: jne XYZ
ulm_conditionalRelJump(ulm_statusReg[ULM_ZF] == 0, XYZ);
0x07 J26
: jz XYZ
: je XYZ
ulm_conditionalRelJump(ulm_statusReg[ULM_ZF] == 1, XYZ);
0x08 U16R
: ldzwq XY, %Z
ulm_setReg(XY, Z);
0x09 RRR
: movzbq (%X), %Z
ulm_fetch64(0, X, 0, 0, ULM_ZERO_EXT, 1, Z);
0x0A RRR
# Adds an immediate value X to register %Y. Stores result in register %Z.
: addq X, %Y, %Z
ulm_add64(X, ulm_regVal(Y), Z);
0x0B RRR
: imulq %X, %Y, %Z
ulm_mul64(ulm_regVal(X), ulm_regVal(Y), Z);
0x0C J26
: ja XYZ
ulm_conditionalRelJump(ulm_statusReg[ULM_ZF] == 0
&& ulm_statusReg[ULM_CF] == 0, XYZ);
0x0D J26
: jb XYZ
ulm_conditionalRelJump(ulm_statusReg[ULM_CF] == 1, XYZ);
0x0E RRR
# Adds register %X to register %Y. Stores result in register %Z.
: addq %X, %Y, %Z
ulm_add64(ulm_regVal(X), ulm_regVal(Y), Z);
0x0F RRR
: imulq X, %Y, %Z
ulm_mul64(X, ulm_regVal(Y), Z);
# General meaning of the mnemonics
@addq
# Integer addition.
@getc
# Get character
@halt
# Halt program
@imulq
# 64-bit unsigned and signed integer multiplication.
@ja
# Jump if above (conditional jump).
@jb
# Jump if below (conditional jump).
@je
# Jump if equal (conditional jump).
@jmp
# Jump (unconditional jump).
@jne
# Jump if not equal (conditional jump).
@jnz
# Jump if not zero (conditional jump).
@jz
# Jump if zero (conditional jump).
@ldzwq
# Load zero extended word to quad word register.
@putc
# Put character
@subq
# Integer subtraction.
@movzbq
# Move zero extended byte to quad word register.
If a mnemonic is used for more than one instruction (e.g. addq) it is helpful to provide information what the mnemonic means in general. For example addq in general adds integers:
1 2 3 4 | @addq
# Integer addition
#
# And Maybe you want to write even more about this mnemonic.
|
You see that with @addq the attached comment block is used as such a general description.
For each instruction you can provide after the opcode line a more specific description. For example, in this addq instruction the first operand is an immediate value
1 2 3 4 | 0x0A RRR
# Adds an immediate value X to register %Y. Stores result in register %Z.
: addq X, %Y, %Z
ulm_add64(X, ulm_regVal(Y), Z);
|
Whereas in this addq instruction the first operand is a register. So let's point that out:
1 2 3 4 | 0x0E RRR
# Adds register %X to register %Y. Stores result in register %Z.
: addq %X, %Y, %Z
ulm_add64(ulm_regVal(X), ulm_regVal(Y), Z);
|
For Comparison: Other ISA Documentations
Below you see some documentations for architecture of practical relevance. For each of them the complete manual is linked but also a small extract describing just one instruction. You will note that the ULM documentation reflects in simplified form what you actually can find out in the field. Like in the ULM documentation the format of the instruction (including the opcode), the assembly notation and the effect is described.
-
Arm instruction for integer addition (Full: Arm Architecture)
Pretty much every smartphone uses a processor that implements an Arm instruction set architecture. The ARM architecture received big public attention when Apple announced to switch from Intel processors to their own processors (M1 and successors). Apple's processors implement the ARM architecture.
-
RISC-V instruction for integer addition (Full: RISC-V)
Open source standard. Recently it gained lots of momentum. Personal opinion and pure speculation: Might some day challenge ARM for being the dominant RISC architecture.
-
MIPS instruction for integer addition (Full: MIPS)
MIPS is a legendary architecture. Often used in computer science classes to teach computer architecture because of its clean design. Development began in the 80s by MIPS Computer Systems. They announced in 2021 their transition to RISC-V.
-
Intel 64 instruction for integer addition (Full: Intel 64 Architecture)
Because this is a CISC (Complex Instruction Set Architecture) it is no surprise to have more than just one or two instructions for adding integers.