# Immediate instructions

Opcode | P/U | Category | Description |

`IMB` |
user | ALU: immediate | immediate both |

`IMH` |
user | ALU: immediate | immediate high |

`IMN` |
user | ALU: immediate | immediate negative |

`IMP` |
user | ALU: immediate | immediate positive |

Immediate instructions permit loading a numeric constant into a register in a single instruction. Because registers and instructions are both 36 bits, but instructions require 9 bits each for the destination register and opcode, only 18 bits of constant information can be supplied per instruction. This means that most 36-bit constants cannot be transferred by a single immediate instruction, although most commonly-written constants can.

When the assembler encounters a statement like

pi = 3_1415926535

it automatically tries to encode the value as a single immediate instruction by trying `IMP`

, `IMN`

, `IMH`

, and `IMB`

in that order. In the case of `pi`

, which in binary is

011101_010000_100010_001111_111100_000111

none of the immediate instructions can encode the constant as one instruction. Instead, the assembler will generate a three-instruction sequence of `IMH`

, `IMP`

, and `OR`

to provide the constant.

**WARNING**

As presently implemented, ** the immediate instructions are semantically broken** and cause one of the regression tests to fail. What is documented here is the immediate instructions

*should work*and

*will work*in the near future. But at present, opcodes for the immediate instructions are not stratified by signage, causing flags to sometimes be misset. This notice was written 14 June 2023 and will be removed upon correction.

`IMB`

Immediate both

Syntax examples |

`u = 64_778_913_095 ; u and s both have binary representation` |

`s = −3_940_563_641 ; 111100_010101_000111_111100_010101_000111` |

`unsigned u` |

`signed s` |

Register | Signedness |

Dest. | unsigned or signed |

(constant) | non-negative or negative |

4 opcodes total |

Flag | Set if and only if |

`N` |
supplied numeric constant is negative |

`Z` |
supplied numeric constant is zero |

`T` |
supplied numeric constant does not fit in destination |

`R` |
`T` is set or `R` is already set |

`IMB`

(immediate both) sets a register to a 36-bit constant taken from the instruction word. Because only 18 bits of constant storage is available within the instruction word, `IMB`

is only applicable to 36-bit constants where their upper 18 bits are identical to their lower 18 bits.

The `N`

flag is solely determined by whether the constant is negative as supplied, and is not affected by the signage of the destination register or whether the constant is able to fit. The `Z`

flag is solely determined by whether the constant is zero; however, this will not occur when using the cross assembler. The `T`

flag will be set if bit 35 of the destination will be set *and* there is a conflict in signage between the destination and the constant as supplied. If `T`

is set, `R`

will also be set, otherwise `R`

will not change.

Although the all-zero and all-one constants are supported by the firmware for `IMB`

, the cross assembler will instead encode these constants using `IMP`

and `IMN`

respectively. This decision is to facilitate easier understanding of disassembler listings.

`IMH`

Immediate high

Syntax examples |

`u = 34_359_738_368 ; u and s both have binary representation` |

`s = −34_359_738_368 ; 100000_000000_000000_000000_000000_000000` |

`unsigned u` |

`signed s` |

Register | Signedness |

Dest. | unsigned or signed |

(constant) | non-negative or negative |

4 opcodes total |

Flag | Set if and only if |

`N` |
supplied numeric constant is negative |

`Z` |
supplied numeric constant is zero |

`T` |
supplied numeric constant does not fit in destination |

`R` |
`T` is set or `R` is already set |

`IMH`

(immediate high) sets a register to a 36-bit constant taken from the instruction word. Because only 18 bits of constant storage is available within the instruction word, `IMH`

is only applicable to 36-bit constants where their lower 18 bits are all zeros.

The `N`

flag is solely determined by whether the constant is negative as supplied, and is not affected by the signage of the destination register or whether the constant is able to fit. The `Z`

flag is solely determined by whether the constant is zero; however, this will not occur when using the cross assembler. The `T`

flag will be set if bit 35 of the destination will be set *and* there is a conflict in signage between the destination and the constant as supplied. If `T`

is set, `R`

will also be set, otherwise `R`

will not change.

Although the constant `0`

is supported by the firmware for `IMH`

, the cross assembler will instead encode `0`

using `IMP`

. This decision is to facilitate easier understanding of disassembler listings.

`IMN`

Immediate negative

Syntax examples |

`u = 68_719_476_734 ; u and s both have binary representation` |

`s = −2 ; 111111_111111_111111_111111_111111_111110` |

`unsigned u` |

`signed s` |

Register | Signedness |

Dest. | unsigned or signed |

(constant) | non-negative or negative |

4 opcodes total |

Flag | Set if and only if |

`N` |
supplied numeric constant is negative |

`Z` |
always cleared |

`T` |
supplied numeric constant does not fit in destination |

`R` |
`T` is set or `R` is already set |

`IMN`

(immediate negative) sets a register to a 36-bit constant taken from the instruction word. Because only 18 bits of constant storage is available within the instruction word, `IMN`

is only applicable to 36-bit constants where their upper 18 bits are all ones.

Although `IMN`

’s name implies that it is for negative constants (and is in fact used for *most* negative constants), it is also used to encode the highest unsigned constants.

The `N`

flag is solely determined by whether the constant is negative as supplied, and is not affected by the signage of the destination register or whether the constant is able to fit. The `Z`

flag is solely determined by whether the constant is zero; however, this will not occur when using the cross assembler. The `T`

flag will be set if bit 35 of the destination will be set *and* there is a conflict in signage between the destination and the constant as supplied. If `T`

is set, `R`

will also be set, otherwise `R`

will not change.

`IMN`

will be used by the cross assembler to encode the all-one constants −1 and 2**36 − 1, even though `IMB`

could be used instead. This decision is to facilitate easier understanding of disassembler listings.

`IMP`

Immediate positive

Syntax examples |

`u = 262_143 ; u and s both have binary representation` |

`s = 262_143 ; 000000_000000_000000_111111_111111_111111` |

`unsigned u` |

`signed s` |

Register | Signedness |

Dest. | ignored |

(constant) | 18-bit unsigned |

1 opcode only |

Flag | Set if and only if |

`N` |
always cleared |

`Z` |
supplied numeric constant is zero |

`T` |
always cleared |

`R` |
`R` is already set |

`IMP`

(immediate positive) sets a register to a 36-bit constant taken from the instruction word. Because only 18 bits of constant storage is available within the instruction word, `IMP`

is only applicable to 36-bit constants where their upper 18 bits are all zeros.

`IMP`

always clears the `N`

and `T`

flags. The `Z`

flag is solely determined by whether the constant is zero. The `R`

flag does not change.

`IMP`

will be used by the cross assembler to encode the constant `0`

, even though `IMB`

could be used instead. This decision is to facilitate easier understanding of disassembler listings.