Arithmetic
Overview
Arithmetic verbs perform integer mathematical operations.
All arithmetic operates on 32-bit signed integers unless otherwise noted. Source operands may be registers or literal values. The destination must always be an integer register.
Results use two's-complement 32-bit integer arithmetic. Values that exceed the representable range wrap around.
Unless otherwise specified, arithmetic instructions do not modify any registers other than their destination.
Basic arithmetic
ADD — Add
ADD <dst> <lhs> <rhs>
Adds two integers together and stores the result in the destination register.
Operands
| Position |
Name |
Type |
Range |
Description |
| 1 |
dst |
Integer register |
— |
Destination register. |
| 2 |
lhs |
Integer value |
— |
Left-hand operand. |
| 3 |
rhs |
Integer value |
— |
Right-hand operand. |
Modified registers
| Register |
Description |
dst |
Sum. |
Examples
-- Add two literals.
ADD r0 10 20
-- > r0 = 30
-- Increment a counter.
ADD r1 r1 1
-- > r1 increases by one
-- Add two registers.
ADD r2 r0 r1
-- > r2 = r0 + r1
SUB — Subtract
SUB <dst> <lhs> <rhs>
Subtracts one integer from another and stores the result in the destination register.
Operands
| Position |
Name |
Type |
Range |
Description |
| 1 |
dst |
Integer register |
— |
Destination register. |
| 2 |
lhs |
Integer value |
— |
Left-hand operand. |
| 3 |
rhs |
Integer value |
— |
Right-hand operand. |
Modified registers
| Register |
Description |
dst |
Difference. |
Examples
-- Subtract two literals.
SUB r0 30 20
-- > r0 = 10
-- Decrement a counter.
SUB r1 r1 1
-- > r1 decreases by one
-- Subtract two registers.
SUB r2 r0 r1
-- > r2 = r0 - r1
MUL — Multiply
MUL <dst> <lhs> <rhs>
Multiplies two integers together and stores the result in the destination register.
Operands
| Position |
Name |
Type |
Range |
Description |
| 1 |
dst |
Integer register |
— |
Destination register. |
| 2 |
lhs |
Integer value |
— |
Left-hand operand. |
| 3 |
rhs |
Integer value |
— |
Right-hand operand. |
Modified registers
| Register |
Description |
dst |
Product. |
Examples
-- Double a value.
MUL r0 r0 2
-- > r0 is doubled
-- Calculate the area of a rectangle.
MUL r2 r0 r1
-- > r2 = r0 × r1
DIV — Divide
DIV <dst> <numerator> <denominator>
Divides one integer by another using truncated integer division.
Operands
| Position |
Name |
Type |
Range |
Description |
| 1 |
dst |
Integer register |
— |
Destination register. |
| 2 |
numerator |
Integer value |
— |
Dividend. |
| 3 |
denominator |
Integer value |
≠ 0 |
Divisor. |
Modified registers
| Register |
Description |
dst |
Quotient. |
er |
Set on error. |
Examples
-- Divide two literals.
DIV r0 10 3
-- > r0 = 3
-- Divide two registers.
DIV r2 r0 r1
-- > r2 = r0 / r1
Notes
- Quotients are truncated toward zero.
- Division by zero is an error.
- On failure, the destination register is set to
0.
MOD — Modulo
MOD <dst> <numerator> <denominator>
Divides one integer by another using truncated integer division and stores the remainder.
Operands
| Position |
Name |
Type |
Range |
Description |
| 1 |
dst |
Integer register |
— |
Destination register. |
| 2 |
numerator |
Integer value |
— |
Dividend. |
| 3 |
denominator |
Integer value |
≠ 0 |
Divisor. |
Modified registers
| Register |
Description |
dst |
Remainder. |
er |
Set on error. |
Examples
-- Divide two literals and store the remainder.
MOD r0 10 3
-- > r0 = 1
-- Divide two registers and store the remainder.
MOD r2 r0 r1
-- > r2 = r0 % r1
Notes
- Division by zero is an error.
- On failure, the destination register is set to
0.
Math functions
POW — Power
POW <dst> <base> <exponent>
Raises a value to an integer power and stores the result in the destination register.
Operands
| Position |
Name |
Type |
Range |
Description |
| 1 |
dst |
Integer register |
— |
Destination register. |
| 2 |
base |
Integer value |
— |
Base value. |
| 3 |
exponent |
Integer value |
— |
Exponent. |
Modified registers
| Register |
Description |
dst |
Result. |
Examples
-- Square a value.
POW r0 r1 2
-- > r0 = r1²
-- Calculate a cube.
POW r0 r1 3
-- > r0 = r1³
-- Raise two to the tenth power.
POW r0 2 10
-- > r0 = 1024
-- Zero exponent.
POW r0 42 0
-- > r0 = 1
-- Negative exponents truncate to zero where
-- the reciprocal cannot be represented as an integer.
POW r0 2 -3
-- > r0 = 0
Notes
- Exponents of
0 produce 1.
- Negative exponents produce the integer representation of the reciprocal power. For bases other than
1 and -1, this is 0.
- Powers of
1 always produce 1.
- Powers of
-1 alternate between -1 and 1 according to the exponent.
- Results use 32-bit integer arithmetic and may overflow.
SQRT — Square Root
SQRT <dst> <val>
Calculates the integer square root of a value and stores the result in the destination register.
For negative values, the magnitude of the imaginary root is returned and er is set to MATH_ERROR.
Operands
| Position |
Name |
Type |
Range |
Description |
| 1 |
dst |
Integer register |
— |
Destination register. |
| 2 |
val |
Integer value |
— |
Value to evaluate. |
Modified registers
| Register |
Description |
dst |
Integer magnitude of the square root. |
er |
Set to MATH_ERROR if val is negative. |
Examples
-- Square root of a perfect square.
SQRT r0 25
-- > r0 = 5
-- Non-integer results are rounded down.
SQRT r1 30
-- > r1 = 5
-- Negative values return the magnitude
-- of the imaginary root and set er.
SQRT r0 -25
-- > r0 = 5
-- > er = "MATH_ERROR"
Notes
- Non-integer results are rounded down.
- Negative values set
er to MATH_ERROR, but the destination still receives the integer magnitude of the root.
- For example,
SQRT -25 produces 5 with MATH_ERROR; software supporting complex numbers may interpret the result as 5i.
- Square roots are calculated entirely using integer arithmetic.
NEG — Negate
NEG <dst> <val>
Negates a value and stores the result in the destination register.
Operands
| Position |
Name |
Type |
Range |
Description |
| 1 |
dst |
Integer register |
— |
Destination register. |
| 2 |
val |
Integer value |
— |
Value to negate. |
Modified registers
| Register |
Description |
dst |
Negated value. |
Examples
-- Negate a literal.
NEG r0 42
-- > r0 = -42
-- Negate a negative value.
NEG r1 -5
-- > r1 = 5
-- Reverse a register's sign.
NEG r2 r0
-- > r2 = -r0
ABS — Absolute Value
ABS <dst> <val>
Calculates the absolute value of a value and stores the result in the destination register.
Operands
| Position |
Name |
Type |
Range |
Description |
| 1 |
dst |
Integer register |
— |
Destination register. |
| 2 |
val |
Integer value |
— |
Value to evaluate. |
Modified registers
| Register |
Description |
dst |
Absolute value. |
Examples
-- Absolute value of a positive number.
ABS r0 42
-- > r0 = 42
-- Absolute value of a negative number.
ABS r1 -42
-- > r1 = 42
-- Absolute value of a register.
ABS r2 r0
-- > r2 = |r0|
SIGN — Sign
SIGN <dst> <val>
Determines the sign of a value and stores the result in the destination register.
Operands
| Position |
Name |
Type |
Range |
Description |
| 1 |
dst |
Integer register |
— |
Destination register. |
| 2 |
val |
Integer value |
— |
Value to evaluate. |
Modified registers
| Register |
Description |
dst |
Sign value. |
Examples
-- Sign of a positive number.
SIGN r0 42
-- > r0 = 1
-- Sign of zero.
SIGN r1 0
-- > r1 = 0
-- Sign of a negative number.
SIGN r2 -42
-- > r2 = -1
-- Sign of a register.
SIGN r3 r0
-- > r3 = sign(r0)
Notes
- Positive values produce
1.
- Zero produces
0.
- Negative values produce
-1.
INC — Increment
INC <reg>
Increments a register by one.
Operands
| Position |
Name |
Type |
Range |
Description |
| 1 |
reg |
Integer register |
— |
Register to modify. |
Modified registers
| Register |
Description |
reg |
Incremented value. |
Examples
-- Increment a counter.
INC r0
-- > r0 increases by one
DEC — Decrement
DEC <reg>
Decrements a register by one.
Operands
| Position |
Name |
Type |
Range |
Description |
| 1 |
reg |
Integer register |
— |
Register to modify. |
Modified registers
| Register |
Description |
reg |
Decremented value. |
Examples
-- Decrement a counter.
DEC r0
-- > r0 decreases by one
Range operations
MIN — Minimum
MIN <dst> <lhs> <rhs>
Stores the smaller of two values in the destination register.
Operands
| Position |
Name |
Type |
Range |
Description |
| 1 |
dst |
Integer register |
— |
Destination register. |
| 2 |
lhs |
Integer value |
— |
First value. |
| 3 |
rhs |
Integer value |
— |
Second value. |
Modified registers
| Register |
Description |
dst |
Smaller value. |
Examples
-- Clamp a value to an upper limit.
MIN r0 r0 100
-- > r0 is at most 100
MAX — Maximum
MAX <dst> <lhs> <rhs>
Stores the larger of two values in the destination register.
Operands
| Position |
Name |
Type |
Range |
Description |
| 1 |
dst |
Integer register |
— |
Destination register. |
| 2 |
lhs |
Integer value |
— |
First value. |
| 3 |
rhs |
Integer value |
— |
Second value. |
Modified registers
| Register |
Description |
dst |
Larger value. |
Examples
-- Clamp a value to a lower limit.
MAX r0 r0 0
-- > r0 is at least 0
CLAMP — Clamp Value
CLAMP <dst> <val> <min> <max>
Clamps a value to the specified range and stores the result in the destination register.
Operands
| Position |
Name |
Type |
Range |
Description |
| 1 |
dst |
Integer register |
— |
Destination register. |
| 2 |
val |
Integer value |
— |
Value to clamp. |
| 3 |
min |
Integer value |
— |
Minimum permitted value. |
| 4 |
max |
Integer value |
— |
Maximum permitted value. |
Modified registers
| Register |
Description |
dst |
Clamped value. |
Examples
-- Clamp a player's health.
CLAMP r0 r0 0 100
-- > r0 is between 0 and 100
Notes
- Values below
min are replaced with min.
- Values above
max are replaced with max.
- Values within the range are left unchanged.
min should normally be less than or equal to max.
- If
min is greater than max, the comparisons are still applied in order and no error is raised.
MAP <dst> <val> <in_min> <in_max> <out_min> <out_max>
Maps a value from one range to another and stores the result in the destination register.
Operands
| Position |
Name |
Type |
Range |
Description |
| 1 |
dst |
Integer register |
— |
Destination register. |
| 2 |
val |
Integer value |
— |
Value to map. |
| 3 |
in_min |
Integer value |
— |
Input range minimum. |
| 4 |
in_max |
Integer value |
— |
Input range maximum. |
| 5 |
out_min |
Integer value |
— |
Output range minimum. |
| 6 |
out_max |
Integer value |
— |
Output range maximum. |
Modified registers
| Register |
Description |
dst |
Mapped value, or out_min on error. |
er |
Set to MATH_ERROR on error. |
Examples
-- Convert a percentage to an 8-bit value.
MAP r0 r0 0 100 0 255
-- > 50 becomes 127
-- Extrapolate beyond the input range.
MAP r0 150 0 100 0 255
-- > 150 becomes 382
-- Convert Fahrenheit to Celsius.
MAP r0 r0 32 212 0 100
-- > 122 becomes 50
-- Convert Celsius to Fahrenheit.
MAP r0 r0 0 100 32 212
-- > 50 becomes 122
-- Convert Kelvin to Celsius.
MAP r0 r0 273 373 0 100
-- > 298 becomes 25
-- Convert Celsius to Kelvin.
MAP r0 r0 0 100 273 373
-- > 25 becomes 298
Notes
- Values outside the input range are extrapolated beyond the output range.
- This instruction does not clamp the result.
- If
in_min equals in_max, er is set to MATH_ERROR and dst receives out_min.