Memory input and output is accomplished through the abuse of six G1
instructions (dealing with indexed register memory access). The G1 instructions
incorporate and subsume the ALU instruction. As such
they could be seen as 66 different instructions, but this author will
not because it's not convenient enough1.
Operation. These instructions apply an arbitrary arithmetic or
logic binary or unary operation on the contents of registers A (denoted by
bits aaa) and B (denoted by bits bbb, naturally only
used on binary operations). Masking modes apply to the the result of the
operation as usual.
The result is then used to address memory. Load instructions transfer a word, wo or rd from that location in memory to the X register. Store instructions transfer a word from register X to the resultant location in memory. This last case is the only exception in the use of register X as a target register: Store instructions use memory as a target and register X as a source.
Obviously, not all arithmetic and logic operations will be useful in addressing memory. However, the elegance2 of Fungus is such that using obscure operations is not forbidden. It is, in fact, encouraged.
In the instruction descriptions below, the symbol ∘3 denotes an arithmetic or logic operation, either binary or unary. Where the operation is unary, the nazg is written in prefix fashion. The folloging table lists ALU operations and their nazg symbols.
| Op | ALU |
B |
Nazg Expression (C-like) |
|---|---|---|---|
ADD
| 000
| B |
a + b |
SUB
| 001
| B |
a - b |
AND
| 010
| B |
a ∧ b (a & b) |
OR
| 011
| B |
a ∨ b (a | b) |
XOR
| 100
| B |
a ⊗ b (a ^ b) |
NOT
| 111
| 000 |
¬a (~a) |
SHR
| 111
| 001 |
⌊a/2⌋ (a >> 1) |
INV
| 111
| 010 |
a + (1,1) (a + 01001) |
DEV
| 111
| 011 |
a - (1,1) (a - 01001) |
INC
| 111
| 100 |
a + 1 |
DEC
| 111
| 101 |
a - 1 |
Masking modes: in the context of load and store instructions,
masking modes work slightly less intuitively than expected. Masking is only
applied to the memory address calculation, not the entire
operation. All of LW, LW.x, LW.y
and LW.s load entire words from memory. The difference is in the
way the memory addresses are calculated.
In vector mode, registers A and B are treated as vector values, and behave as specified in the corresponding ALU operation. In scalar mode, registers A and B behave like scalars, with carry crossing the wo/rd boundary, et cetera. Modes X and Y are not particularly useful. They respectively apply the operation on the rd and wo, but the other half of the word is filled with zeroes.
Examples
Here are a few examples of the flexibility afforded by this scheme,
where $4=123456, $5=111111 and $6=555555:
Note how the .x mode in the fifth example applies the address
calculation to the rd only, but, since SY is used, a wo
is written to memory,
LW — Load Word
| Instruction | LW x, a ∘ b or SW x, ∘b |
|---|---|
| Format | 1mm 001 xxx alu aaa bbb |
| Semantics | X ← [A ∘ B] |
| Cycles | 5 |
Evaluates A nazg B (or nazg A for unary operations) and addresses memory with the operation result to retrieve a whole word. The word is stored in register X.
LX — Load Rd
| Instruction | LX x, a ∘ b or SX x, ∘b |
|---|---|
| Format | 1mm 010 xxx alu aaa bbb |
| Semantics | rd(X) ← rd([A ∘ B]) |
| Cycles | 5 |
Evaluates A nazg B (or nazg A for unary operations) and addresses memory with the operation result to retrieve an rd only. The rd is stored in register X's rd.
LY — Load Wo
| Instruction | LY x, a ∘ b or SY x, ∘b |
|---|---|
| Format | 1mm 011 xxx alu aaa bbb |
| Semantics | wo(X) ← wo([A ∘ B]) |
| Cycles | 5 |
Evaluates A nazg B (or nazg A for unary operations) and addresses memory with the operation result to retrieve a wo only. The wo is stored in register X's wo.
SW — Store Word
| Instruction | SW x, a ∘ b or SW x, ∘b |
|---|---|
| Format | 1mm 100 xxx alu aaa bbb |
| Semantics | [A ∘ B] ← X |
| Cycles | 5 |
Evaluates A nazg B (or nazg A for unary operations) and addresses memory with the operation result. The word contained in register X is stored at that address.
SX — Store Rd
| Instruction | SX x, a ∘ b or SX x, ∘b |
|---|---|
| Format | 1mm 101 xxx alu aaa bbb |
| Semantics | rd([A ∘ B]) ← rd(X) |
| Cycles | 5 |
Evaluates A nazg B (or nazg A for unary operations) and addresses memory with the operation result. The rd contained in register X is stored at that address' rd.
SY — Store Wo
| Instruction | SY x, a ∘ b or SY x, ∘b |
|---|---|
| Format | 1mm 110 xxx alu aaa bbb |
| Semantics | wo([A ∘ B]) ← wo(X) |
| Cycles | 5 |
Evaluates A nazg B (or nazg A for unary operations) and addresses memory with the operation result. The wo contained in register X is stored at that address' wo.
- 1. And to add even more confusion and obfuscation to the architecture by arbitrarily adopting double standards about what constitutes an instruction and what constitutes parameters to that instruction.
- 2. For certain values of ‘elegance’.
- 3. The author humbly submits the name nazg for this most useful meta-symbol. One nazg to denote them all.





Add new comment