6.6 KiB
RandomX instruction listing
Integer instructions
For integer instructions, the destination is always an integer register (register group R). Source operand (if applicable) can be either an integer register or memory value. If dst
and src
refer to the same register, most instructions use imm32
as the source operand instead of the register. This is indicated in the 'src == dst' column.
Memory operands are loaded as 8-byte values from the address indicated by src
. This indirect addressing is marked with square brackets: [src]
.
frequency | instruction | dst | src | src == dst ? |
operation |
---|---|---|---|---|---|
12/256 | IADD_R | R | R | src = imm32 |
dst = dst + src |
7/256 | IADD_M | R | mem | src = imm32 |
dst = dst + [src] |
16/256 | IADD_RC | R | R | src = dst |
dst = dst + src + imm32 |
12/256 | ISUB_R | R | R | src = imm32 |
dst = dst - src |
7/256 | ISUB_M | R | mem | src = imm32 |
dst = dst - [src] |
9/256 | IMUL_9C | R | - | - | dst = 9 * dst + imm32 |
16/256 | IMUL_R | R | R | src = imm32 |
dst = dst * src |
4/256 | IMUL_M | R | mem | src = imm32 |
dst = dst * [src] |
4/256 | IMULH_R | R | R | src = dst |
dst = (dst * src) >> 64 |
1/256 | IMULH_M | R | mem | src = imm32 |
dst = (dst * [src]) >> 64 |
4/256 | ISMULH_R | R | R | src = dst |
dst = (dst * src) >> 64 (signed) |
1/256 | ISMULH_M | R | mem | src = imm32 |
dst = (dst * [src]) >> 64 (signed) |
4/256 | IDIV_C | R | - | - | dst = dst + dst / imm32 |
4/256 | ISDIV_C | R | - | - | dst = dst + dst / imm32 (signed) |
2/256 | INEG_R | R | - | - | dst = -dst |
16/256 | IXOR_R | R | R | src = imm32 |
dst = dst ^ src |
4/256 | IXOR_M | R | mem | src = imm32 |
dst = dst ^ [src] |
10/256 | IROR_R | R | R | src = imm32 |
dst = dst >>> src |
4/256 | ISWAP_R | R | R | src = dst |
temp = src; src = dst; dst = temp |
IMULH and ISMULH
These instructions output the high 64 bits of the whole 128-bit multiplication result. The result differs for signed and unsigned multiplication (IMULH
is unsigned, ISMULH
is signed). The variants with a register source operand do not use imm32
(they perform a squaring operation if dst
equals src
).
IDIV_C and ISDIV_C
The division instructions use a constant divisor, so they can be optimized into a multiplication by fixed-point reciprocal. IDIV_C
performs unsigned division (imm32
is zero-extended to 64 bits), while ISDIV_C
performs signed division. In the case of division by zero, the instructions become a no-op. In the very rare case of signed overflow, the destination register is set to zero.
ISWAP_R
This instruction swaps the values of two registers. If source and destination refer to the same register, the result is a no-op.
Floating point instructions
For floating point instructions, the destination can be a group F or group E register. Source operand is either a group A register or a memory value.
Memory operands are loaded as 8-byte values from the address indicated by src
. The 8 byte value is interpreted as two 32-bit signed integers and implicitly converted to floating point format. The lower and upper memory operands are marked as [src][0]
and [src][1]
.
frequency | instruction | dst | src | operation |
---|---|---|---|---|
8/256 | FSWAP_R | F+E | - | (dst0, dst1) = (dst1, dst0) |
20/256 | FADD_R | F | A | (dst0, dst1) = (dst0 + src0, dst1 + src1) |
5/256 | FADD_M | F | mem | (dst0, dst1) = (dst0 + [src][0], dst1 + [src][1]) |
20/256 | FSUB_R | F | A | (dst0, dst1) = (dst0 - src0, dst1 - src1) |
5/256 | FSUB_M | F | mem | (dst0, dst1) = (dst0 - [src][0], dst1 - [src][1]) |
6/256 | FSCAL_R | F | - | (dst0, dst1) = (-2x0 * dst0, -2x1 * dst1) |
20/256 | FMUL_R | E | A | (dst0, dst1) = (dst0 * src0, dst1 * src1) |
4/256 | FDIV_M | E | mem | (dst0, dst1) = (dst0 / [src][0], dst1 / [src][1]) |
6/256 | FSQRT_R | E | - | (dst0, dst1) = (√dst0, √dst1) |
FSCAL_R
This instruction negates the number and multiplies it by 2x
. x
is calculated by taking the 5 least significant digits of the biased exponent and interpreting them as a binary number using the digit set {-1, +1}
as opposed to the traditional {0, 1}
. The possible values of x
are all odd numbers from -31 to +31.
The mathematical operation described above is equivalent to a bitwise XOR of the binary representation with the value of 0x81F0000000000000
.
Denormal and NaN values
Due to restrictions on the values of the floating point registers, no operation results in NaN
.
FDIV_M
can produce a denormal result. In that case, the result is set to DBL_MIN = 2.22507385850720138309e-308
, which is the smallest positive normal number.
Rounding
All floating point instructions give correctly rounded results. The rounding mode depends on the value of the fprc
register:
fprc |
rounding mode |
---|---|
0 | roundTiesToEven |
1 | roundTowardNegative |
2 | roundTowardPositive |
3 | roundTowardZero |
The rounding modes are defined by the IEEE 754 standard.
Other instructions
There are 4 special instructions that have more than one source operand or the destination operand is a memory value.
frequency | instruction | dst | src | operation |
---|---|---|---|---|
7/256 | COND_R | R | R | if(condition(src, imm32)) dst = dst + 1 |
1/256 | COND_M | R | mem | if(condition([src], imm32)) dst = dst + 1 |
1/256 | CFROUND | fprc |
R | fprc = src >>> imm32 |
16/256 | ISTORE | mem | R | [dst] = src |
COND
These instructions conditionally increment the destination register. The condition function depends on the mod.cond
flag and takes the lower 32 bits of the source operand and the value imm32
.
mod.cond |
signed | condition |
probability | x86 | ARM |
---|---|---|---|---|---|
0 | no | src <= imm32 |
0% - 100% | JBE |
BLS |
1 | no | src > imm32 |
0% - 100% | JA |
BHI |
2 | yes | src - imm32 < 0 |
50% | JS |
BMI |
3 | yes | src - imm32 >= 0 |
50% | JNS |
BPL |
4 | yes | src - imm32 overflows |
0% - 50% | JO |
BVS |
5 | yes | src - imm32 doesn't overflow |
50% - 100% | JNO |
BVC |
6 | yes | src < imm32 |
0% - 100% | JL |
BLT |
7 | yes | src >= imm32 |
0% - 100% | JGE |
BGE |
The 'signed' column specifies if the operands are interpreted as signed or unsigned 32-bit numbers. Column 'probability' lists the expected probability the condition is true (range means that the actual value for a specific instruction depends on imm32
). Columns 'x86' and 'ARM' list the corresponding hardware instructions (following a CMP
instruction).
CFROUND
This instruction sets the value of the fprc
register to the 2 least significant bits of the source register rotated right by imm32
. This changes the rounding mode of all subsequent floating point instructions.
ISTORE
The ISTORE
instruction stores the value of the source integer register to the memory at the address specified by the destination register. The src
and dst
register can be the same.