RandomWOW/doc/isa.md

92 lines
4.3 KiB
Markdown
Raw Normal View History

2018-12-14 11:12:18 +00:00
# RandomX instruction set architecture
2019-02-09 15:09:55 +00:00
RandomX VM is a complex instruction set computer ([CISC](https://en.wikipedia.org/wiki/Complex_instruction_set_computer)). All data are loaded and stored in little-endian byte order. Signed integer numbers are represented using [two's complement](https://en.wikipedia.org/wiki/Two%27s_complement). Floating point numbers are represented using the [IEEE 754 double precision format](https://en.wikipedia.org/wiki/Double-precision_floating-point_format).
2018-12-14 11:12:18 +00:00
## Registers
2018-12-14 11:12:18 +00:00
RandomX has 8 integer registers `r0`-`r7` (group R) and a total of 12 floating point registers split into 3 groups: `a0`-`a3` (group A), `f0`-`f3` (group F) and `e0`-`e3` (group E). Integer registers are 64 bits wide, while floating point registers are 128 bits wide and contain a pair of floating point numbers. The lower and upper half of floating point registers are not separately addressable.
2018-12-14 11:12:18 +00:00
*Table 1: Addressable register groups*
2019-01-11 09:52:12 +00:00
|index|R|A|F|E|F+E|
|--|--|--|--|--|--|
|0|`r0`|`a0`|`f0`|`e0`|`f0`|
|1|`r1`|`a1`|`f1`|`e1`|`f1`|
|2|`r2`|`a2`|`f2`|`e2`|`f2`|
|3|`r3`|`a3`|`f3`|`e3`|`f3`|
|4|`r4`||||`e0`|
|5|`r5`||||`e1`|
|6|`r6`||||`e2`|
|7|`r7`||||`e3`|
2018-12-14 11:12:18 +00:00
Besides the directly addressable registers above, there is a 2-bit `fprc` register for rounding control, which is an implicit destination register of the `CFROUND` instruction, and two architectural 32-bit registers `ma` and `mx`, which are not accessible to any instruction.
2018-12-14 11:12:18 +00:00
Integer registers `r0`-`r7` can be the source or the destination operands of integer instructions or may be used as address registers for loading the source operand from the memory (scratchpad).
2019-01-10 22:36:53 +00:00
Floating point registers `a0`-`a3` are read-only and may not be written to except at the moment a program is loaded into the VM. They can be the source operand of any floating point instruction. The value of these registers is restricted to the interval `[1, 4294967296)`.
2019-01-10 22:36:53 +00:00
Floating point registers `f0`-`f3` are the *additive* registers, which can be the destination of floating point addition and subtraction instructions. The absolute value of these registers will not exceed `1.0e+12`.
2019-01-10 22:36:53 +00:00
Floating point registers `e0`-`e3` are the *multiplicative* registers, which can be the destination of floating point multiplication, division and square root instructions. Their value is always positive.
2019-01-10 22:36:53 +00:00
## Instruction encoding
2019-01-10 22:36:53 +00:00
Each instruction word is 64 bits long and has the following format:
2019-01-10 22:36:53 +00:00
![Imgur](https://i.imgur.com/FtkWRwe.png)
2018-12-14 11:12:18 +00:00
### opcode
2019-02-09 15:09:55 +00:00
There are 256 opcodes, which are distributed between 32 distinct instructions. Each instruction can be encoded using multiple opcodes (the number of opcodes specifies the frequency of the instruction in a random program).
2018-12-14 11:12:18 +00:00
*Table 2: Instruction groups*
2018-12-14 11:12:18 +00:00
|group|# instructions|# opcodes||
|---------|-----------------|----|-|
2019-02-09 15:09:55 +00:00
|integer |19|137|53.5%|
|floating point |9|94|36.7%|
|other |4|25|9.8%|
||**32**|**256**|**100%**
2018-12-14 11:12:18 +00:00
Full description of all instructions: [isa-ops.md](isa-ops.md).
2018-12-31 18:27:31 +00:00
### dst
Destination register. Only bits 0-1 (register groups A, F, E) or 0-2 (groups R, F+E) are used to encode a register according to Table 1.
2018-12-31 18:27:31 +00:00
### src
2018-12-31 18:27:31 +00:00
The `src` flag encodes a source operand register according to Table 1 (only bits 0-1 or 0-2 are used).
2018-12-31 18:27:31 +00:00
Immediate value `imm32` is used as the source operand in cases when `dst` and `src` encode the same register.
2018-12-14 11:12:18 +00:00
For register-memory instructions, the source operand determines the `address_base` value for calculating the memory address (see below).
2018-12-14 11:12:18 +00:00
### mod
2018-12-14 11:12:18 +00:00
The `mod` flag is encoded as:
2018-12-14 11:12:18 +00:00
*Table 3: mod flag encoding*
2018-12-14 11:12:18 +00:00
|`mod`|description|
2019-01-10 22:36:53 +00:00
|----|--------|
|0-1|`mod.mem` flag|
|2-4|`mod.cond` flag|
|5-7|Reserved|
2018-12-14 11:12:18 +00:00
The `mod.mem` flag determines the address mask when reading from or writing to memory:
2018-12-14 11:12:18 +00:00
*Table 3: memory address mask*
2018-12-14 11:12:18 +00:00
|`mod.mem`|`address_mask`|(scratchpad level)|
|---------|-|---|
|0|262136|(L2)|
|1-3|16376|(L1)|
2018-12-14 11:12:18 +00:00
Table 3 applies to all memory accesses except for cases when the source operand is an immediate value. In that case, `address_mask` is equal to 2097144 (L3).
2018-12-31 18:27:31 +00:00
The address for reading/writing is calculated by applying bitwise AND operation to `address_base` and `address_mask`.
2018-12-14 11:12:18 +00:00
The `mod.cond` flag is used only by the `COND` instruction to select a condition to be tested.
2018-12-14 11:12:18 +00:00
### imm32
2019-02-09 15:09:55 +00:00
A 32-bit immediate value that can be used as the source operand. The immediate value is sign-extended to 64 bits unless specified otherwise.