# Additive instructions

Opcode | P/U | Category | Description |

`A` |
user | ALU: additive | add |

`AC` |
user | ALU: additive | add with carry |

`AW` |
user | ALU: additive | add with wrap |

`AWC` |
user | ALU: additive | add with wrap and carry |

`RS` |
user | ALU: additive | reverse subtract |

`RSC` |
user | ALU: additive | reverse subtract with carry |

`RSW` |
user | ALU: additive | reverse subtract with wrap |

`RSWC` |
user | ALU: additive | reverse subtract with wrap and carry |

`S` |
user | ALU: additive | subtract |

`SC` |
user | ALU: additive | subtract with carry |

`SW` |
user | ALU: additive | subtract with wrap |

`SWC` |
user | ALU: additive | subtract with wrap and carry |

## Preface

Unlike in conventional architectures, Dauug|36’s additive instructions are fully **range checked**, irrespective of signage. First, a `T`

(emporal overrange) flag is cleared or set on the basis of whether or not the result fits. Second, a sticky `R`

(ange) flag is set in the event `T`

is set. The `R`

flag remains set until it is cleared by the `CRF`

(clear Range flag) instruction. This precludes the need to check flags after each instruction: checking can be deferred to the end of a long calculation.

Dauug|36 is able to determine whether an additive result fits, because its assembly language requires registers to be declared as unsigned or signed. Based on this, the correct opcode is chosen. For example, there are eight opcodes for `A`

(add). The assembly syntax looks like this:

unsigned a c (a and c are unsigned registers) signed b (b is a signed register) c = a + b (selects the A.usu variant of A)

Conventional architectures don’t need a **reverse subtraction** operation, because using ordinary subtraction with the operands switched would achieve the same effect. Dauug|36 is different, in that a register’s value may be different when used as a left operand vs. a right operand. This is the case today with the `MHL`

series of fast multiplication instructions, and could be the case in the future if a hardware multiplier is added to the architecture.

`A`

Add

Syntax |

`c = a + b` |

Register | Signedness |

Left | unsigned or signed |

Right | unsigned or signed |

Destination | unsigned or signed |

8 opcodes total |

Flag | Set if and only if |

`N` |
`a` + `b` < 0 |

`Z` |
`a` + `b` = 0 |

`T` |
`c` cannot fit `a` + `b` |

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

`A`

(add) is the instruction for ordinary addition of 36-bit numbers. It does not have a carry input or carry output. It is fully range-checked, so the `T`

and `R`

flags will indicate when the sum does not fit in 36 bits.

The 36-bit unsigned and/or signed operand registers are extended into 38-bit signed quantities, which then are added to produce a 38-bit signed sum that will not overflow. The `N`

and `Z`

flags are set based on the original 38-bit sum. The 36 least significant bits of the sum are stored in the destination register, which may be signed or unsigned. Flags `T`

and `R`

are set if the full sum does not fit, otherwise `T`

is cleared and `R`

is left unchanged.

`AC`

Add with carry

Syntax |

`c = a ++ b` |

Register | Signedness |

Left | unsigned or signed |

Right | unsigned or signed |

Destination | unsigned or signed |

8 opcodes total |

Flag | Set if and only if |

`N` |
`a` + `b` + `T` < 0 |

`Z` |
`a` + `b` + `T` = 0 |

`T` |
`c` cannot fit `a` + `b` + `T` |

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

`AC`

(add with carry) is the final instruction for multiple-precision addition of integers larger than 36 bits. It uses the `T`

flag as a carry input, but has no carry output. It is fully range-checked, so the `T`

and `R`

flags will indicate when the multiple-precision sum does not fit.

This instruction is preceded by `AW`

for 72-bit addition, or by `AWC`

for 108-bit and larger addition. It is never preceded by `A`

, because `A`

conflicts for range checking. The 36-bit unsigned and/or signed operand registers are extended into 38-bit signed quantities, which then are added along with the `T`

flag to produce a 38-bit signed sum that will not overflow. The `N`

and `Z`

flags are set based on the original 38-bit sum. The 36 least significant bits of the sum are stored in the destination register, which may be signed or unsigned. Flags `T`

and `R`

are set if the full sum does not fit, otherwise `T`

is cleared and `R`

is left unchanged.

`AW`

Add with wrap

Syntax |

`<wrap> c = a + b` |

Register | Signedness |

Left | ignored |

Right | ignored |

Destination | ignored |

1 opcode only |

Flag | Set if and only if |

`N` |
never; flag is cleared |

`Z` |
`<unsigned> a` + `<unsigned> b` = 0 |

`T` |
`<unsigned> a` + `<unsigned> b` ≥ 2^{36} |

`R` |
flag does not change |

`AW`

(add with wrap) the first instruction for multiple-precision addition of integers larger than 36 bits. It has no carry input, and uses the `T`

flag as a carry output. It does not require range checking and therefore has no effect on the `R`

flag.

This instruction is followed by `AC`

for 72-bit addition. For 108-bit and larger integers, it is followed by `AWC`

.

The three registers are treated as unsigned without regard to how they are declared. The operands are added, and the 36 least significant bits of the sum are stored in the destination. Flag `N`

is cleared. Flag `Z`

will be set if the left and right operands are both zero, and cleared otherwise because the sum, however truncated, cannot truly be zero. Flag `T`

is set if a carry is generated, and cleared otherwise. Flag `R`

does not change.

`AWC`

Add with wrap and carry

Syntax |

`<wrap> c = a ++ b` |

Register | Signedness |

Left | ignored |

Right | ignored |

Destination | ignored |

1 opcode only |

Flag | Set if and only if |

`N` |
never; flag is cleared |

`Z` |
`<unsigned> a` + `<unsigned> b` + `T` = 0 |

`T` |
`<unsigned> a` + `<unsigned> b` + `T` ≥ 2^{36} |

`R` |
flag does not change |

`AWC`

(add with wrap and carry) is the intermediate instruction for multiple-precision addition of integers larger than 72 bits. It uses the `T`

flag as a carry input and carry output. It does not require range checking and therefore has no effect on the `R`

flag.

In 108-bit addition, this instruction is preceded by `AW`

and followed by `AC`

. For 144-bit and larger integers, it is preceded by `AW`

or `AWC`

and followed by `AWC`

or `AC`

depending on its position.

The three registers are treated as unsigned without regard to how they are declared. The operands are added along with the `T`

flag, and the 36 least significant bits of the sum are stored in the destination. Flag `N`

is cleared. Flag `Z`

will be set if both operands and the incoming `T`

flag are all zero, and cleared otherwise because the sum, however truncated, cannot truly be zero. Flag `T`

is set if a carry is generated, and cleared otherwise. Flag `R`

does not change.

`RS`

Reverse subtract

Syntax |

`c = a ~- b` |

Register | Signedness |

Left | unsigned or signed |

Right | unsigned or signed |

Destination | unsigned or signed |

8 opcodes total |

Flag | Set if and only if |

`N` |
`b` − `a` < 0 |

`Z` |
`b` − `a` = 0 |

`T` |
`c` cannot fit `b` − `a` |

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

`RS`

(reverse subtract) is the instruction for reverse subtraction of 36-bit numbers. It does not have a borrow input or borrow output. It is fully range-checked, so the `T`

and `R`

flags will indicate when the difference does not fit in 36 bits.

The 36-bit unsigned and/or signed operand registers are extended into 38-bit signed quantities. The left operand is subtracted from the right to produce a 38-bit signed difference that will not overflow. The `N`

and `Z`

flags are set based on the original 38-bit difference. The 36 least significant bits of the difference are stored in the destination register, which may be signed or unsigned. Flags `T`

and `R`

are set if the full difference does not fit, otherwise `T`

is cleared and `R`

is left unchanged.

`RSC`

Reverse subtract with carry

Syntax |

`c = a ~-- b` |

The syntax in the dissertation on page 410 is incorrect.

Register | Signedness |

Left | unsigned or signed |

Right | unsigned or signed |

Destination | unsigned or signed |

8 opcodes total |

Flag | Set if and only if |

`N` |
`b` − `a` − `T` < 0 |

`Z` |
`b` − `a` − `T` = 0 |

`T` |
`c` cannot fit `b` − `a` − `T` |

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

`RSC`

(reverse subtract with carry) is the final instruction for multiple-precision reverse subtraction of integers larger than 36 bits. It uses the `T`

flag as a borrow input, but has no borrow output. It is fully range-checked, so the `T`

and `R`

flags will indicate when the multiple-precision difference does not fit.

This instruction is preceded by `RSW`

for 72-bit reverse subtraction, or by `RSWC`

for 108-bit and larger reverse subtraction. It is never preceded by `RS`

, because `RS`

conflicts for range checking.

The 36-bit unsigned and/or signed operand registers are extended into 38-bit signed quantities. The `T`

flag and left operand are subtracted from the right to produce a 38-bit signed difference that will not overflow. The `N`

and `Z`

flags are set based on the original 38-bit difference. The 36 least significant bits of the difference are stored in the destination register, which may be signed or unsigned. Flags `T`

and `R`

are set if the full difference does not fit, otherwise `T`

is cleared and `R`

is left unchanged.

`RSW`

Reverse subtract with wrap

Syntax |

`<wrap> c = a ~- b` |

Register | Signedness |

Left | ignored |

Right | ignored |

Destination | ignored |

1 opcode only |

Flag | Set if and only if |

`N` |
`<unsigned> b` − `<unsigned> a` < 0 |

`Z` |
`<unsigned> b` − `<unsigned> a` = 0 |

`T` |
`<unsigned> b` − `<unsigned> a` < 0 |

`R` |
flag does not change |

`RSW`

(reverse subtract with wrap) is the first instruction for multiple-precision reverse subtraction of integers larger than 36 bits. It has no borrow input, and uses the `T`

flag as a borrow output.

It does not require range checking and therefore has no effect on the `R`

flag. This instruction is followed by `RSC`

for 72-bit reverse subtraction. For 108-bit and larger integers, it is followed by `RSWC`

.

The three registers are treated as unsigned without regard to how they are declared. The left operand is subtracted from the right, and the 36-bit difference is stored in the destination. Flag `Z`

will be set if the left and right operands are equal, and cleared otherwise. Flags `N`

and `T`

are set if a borrow is generated, and cleared otherwise. Flag `R`

does not change.

The dissertation incorrectly states on page 411 that the T flag is also subtracted.

`RSWC`

Reverse subtract with wrap and carry

Syntax |

`<wrap> c = a ~-- b` |

The syntax in the dissertation on page 412 is incorrect.

Register | Signedness |

Left | unsigned or signed |

Right | unsigned or signed |

Destination | unsigned or signed |

8 opcodes total |

Flag | Set if and only if |

`N` |
`<unsigned> b` − `<unsigned> a` − `T` < 0 |

`Z` |
`<unsigned> b` − `<unsigned> a` − `T` = 0 |

`T` |
`<unsigned> b` − `<unsigned> a` − `T` < 0 |

`R` |
flag does not change |

`RSWC`

(reverse subtract with wrap and carry) is the intermediate instruction for multiple-precision reverse subtraction of integers larger than 72 bits. It uses the `T`

flag as a borrow input and borrow output. It does not require range checking and therefore has no effect on the `R`

flag.

In 108-bit reverse subtraction, this instruction is preceded by `RSW`

and followed by `RSC`

. For 144-bit and larger integers, it is preceded by `RSW`

or `RSWC`

and followed by `RSWC`

or `RSC`

depending on its position.

The three registers are treated as unsigned without regard to how they are declared. The `T`

flag and left operand are subtracted from the right, and the 36-bit difference is stored in the destination. Flag `Z`

will be set if the 36-bit difference is zero and no borrow is generated. Flags `N`

and `T`

are set if a borrow is generated, and cleared otherwise. Flag `R`

does not change.

`S`

Subtract

Syntax |

`c = a - b` |

Register | Signedness |

Left | unsigned or signed |

Right | unsigned or signed |

Destination | unsigned or signed |

8 opcodes total |

Flag | Set if and only if |

`N` |
`a` − `b` < 0 |

`Z` |
`a` − `b` = 0 |

`T` |
`c` cannot fit `a` − `b` |

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

`S`

(subtract) is the instruction for ordinary subtraction of 36-bit numbers. It does not have a borrow input or borrow output. It is fully range-checked, so the `T`

and `R`

flags will indicate when the difference does not fit in 36 bits.

The 36-bit unsigned and/or signed operand registers are extended into 38-bit signed quantities. The right operand is subtracted from the left to produce a 38-bit signed difference that will not overflow. The `N`

and `Z`

flags are set based on the original 38-bit difference. The 36 least significant bits of the difference are stored in the destination register, which may be signed or unsigned. Flags `T`

and `R`

are set if the full difference does not fit, otherwise `T`

is cleared and `R`

is left unchanged.

`SC`

Subtract with carry

Syntax |

`c = a -- b` |

The syntax in the dissertation on page 414 is incorrect.

Register | Signedness |

Left | unsigned or signed |

Right | unsigned or signed |

Destination | unsigned or signed |

8 opcodes total |

Flag | Set if and only if |

`N` |
`a` − `b` − `T` < 0 |

`Z` |
`a` − `b` − `T` = 0 |

`T` |
`c` cannot fit `a` − `b` − `T` |

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

`SC`

(subtract with carry) is the final instruction for multiple-precision subtraction of integers larger than 36 bits. It uses the `T`

flag as a borrow input, but has no borrow output. It is fully range-checked, so the `T`

and `R`

flags will indicate when the multiple-precision difference does not fit.

This instruction is preceded by `SW`

for 72-bit subtraction, or by `SWC`

for 108-bit and larger subtraction. It is never preceded by `S`

, because `S`

conflicts for range checking.

The 36-bit unsigned and/or signed operand registers are extended into 38-bit signed quantities. The `T`

flag and right operand are subtracted from the left to produce a 38-bit signed difference that will not overflow. The `N`

and `Z`

flags are set based on the original 38-bit difference. The 36 least significant bits of the difference are stored in the destination register, which may be signed or unsigned. Flags `T`

and `R`

are set if the full difference does not fit, otherwise `T`

is cleared and `R`

is left unchanged.

`SW`

Subtract with wrap

Syntax |

`<wrap> c = a - b` |

Register | Signedness |

Left | ignored |

Right | ignored |

Destination | ignored |

1 opcode only |

Flag | Set if and only if |

`N` |
`<unsigned> a` − `<unsigned> b` < 0 |

`Z` |
`<unsigned> a` − `<unsigned> b` = 0 |

`T` |
`<unsigned> a` − `<unsigned> b` < 0 |

`R` |
flag does not change |

`SW`

(subtract with wrap) is the first instruction for multiple-precision subtraction of integers larger than 36 bits. It has no borrow input, and uses the `T`

flag as a borrow output. It does not require range checking and therefore has no effect on the `R`

flag.

This instruction is followed by `SC`

for 72-bit subtraction. For 108-bit and larger integers, it is followed by `SWC`

.

The three registers are treated as unsigned without regard to how they are declared. The right operand is subtracted from the left, and the 36-bit difference is stored in the destination. Flag `Z`

will be set if the left and right operands are equal, and cleared otherwise. Flags `N`

and `T`

are set if a borrow is generated, and cleared otherwise. Flag `R`

does not change.

The dissertation incorrectly states on page 415 that the T flag is also subtracted.

`SWC`

Subtract with wrap and carry

Syntax |

`<wrap> c = a -- b` |

The syntax in the dissertation on page 416 is incorrect.

Register | Signedness |

Left | unsigned or signed |

Right | unsigned or signed |

Destination | unsigned or signed |

8 opcodes total |

Flag | Set if and only if |

`N` |
`<unsigned> a` − `<unsigned> b` − `T` < 0 |

`Z` |
`<unsigned> a` − `<unsigned> b` − `T` = 0 |

`T` |
`<unsigned> a` − `<unsigned> b` − `T` < 0 |

`R` |
flag does not change |

`SWC`

(subtract with wrap and carry) is the intermediate instruction for multiple-precision subtraction of integers larger than 72 bits. It uses the `T`

flag as a borrow input and borrow output. It does not require range checking and therefore has no effect on the `R`

flag.

In 108-bit subtraction, this instruction is preceded by `SW`

and followed by `SC`

. For 144-bit and larger integers, it is preceded by `SW`

or `SWC`

and followed by `SWC`

or `SC`

depending on its position.

The three registers are treated as unsigned without regard to how they are declared. The `T`

flag and right operand are subtracted from the left, and the 36-bit difference is stored in the destination. Flag `Z`

will be set if the 36-bit difference is zero and no borrow is generated. Flags `N`

and `T`

are set if a borrow is generated, and cleared otherwise. Flag `R`

does not change.