Clean up the list of operations somewhat.
This commit is contained in:
@@ -605,23 +605,32 @@ depends on the runtime environment.
|
|||||||
Operations
|
Operations
|
||||||
==========
|
==========
|
||||||
|
|
||||||
|
The remaining instruction set is mostly arithmetic.
|
||||||
|
|
||||||
|
A few instructions have variants that take immediate operands (e.g.,
|
||||||
|
:inst:`and` / :inst:`and_imm`), but in general an instruction is required to
|
||||||
|
load a constant into an SSA value.
|
||||||
|
|
||||||
Special operations
|
.. inst:: a = iconst N
|
||||||
------------------
|
|
||||||
|
|
||||||
.. inst:: a = iconst n
|
|
||||||
|
|
||||||
Integer constant.
|
Integer constant.
|
||||||
|
|
||||||
.. inst:: a = fconst n
|
Create a scalar integer SSA value with an immediate constant value, or an
|
||||||
|
integer vector where all the lanes have the same value.
|
||||||
|
|
||||||
|
.. inst:: a = fconst N
|
||||||
|
|
||||||
Floating point constant.
|
Floating point constant.
|
||||||
|
|
||||||
.. inst:: a = vconst n
|
Create a :type:`f32` or :type:`f64` SSA value with an immediate constant
|
||||||
|
value, or a floating point vector where all the lanes have the same value.
|
||||||
|
|
||||||
|
.. inst:: a = vconst N
|
||||||
|
|
||||||
Vector constant (floating point or integer).
|
Vector constant (floating point or integer).
|
||||||
|
|
||||||
|
Create a SIMD vector value where the lanes don't have to be identical.
|
||||||
|
|
||||||
.. inst:: a = select c, x, y
|
.. inst:: a = select c, x, y
|
||||||
|
|
||||||
Conditional select.
|
Conditional select.
|
||||||
@@ -680,12 +689,13 @@ Vector operations
|
|||||||
Integer operations
|
Integer operations
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
.. inst:: a = icmp cond, x, y
|
.. inst:: a = icmp Cond, x, y
|
||||||
|
|
||||||
Integer comparison.
|
Integer comparison.
|
||||||
|
|
||||||
:param cond: Condition code determining how ``x`` and ``y`` are compared.
|
:arg Cond: Condition code determining how ``x`` and ``y`` are compared.
|
||||||
:param x, y: Integer scalar or vector values of the same type.
|
:arg x: First value to compare.
|
||||||
|
:arg y: Second value to compare.
|
||||||
:rtype: :type:`bool` or :type:`boolxN` with the same number of lanes as
|
:rtype: :type:`bool` or :type:`boolxN` with the same number of lanes as
|
||||||
``x`` and ``y``.
|
``x`` and ``y``.
|
||||||
|
|
||||||
@@ -708,29 +718,59 @@ Integer operations
|
|||||||
Wrapping integer addition: :math:`a := x + y \pmod{2^B}`. This instruction
|
Wrapping integer addition: :math:`a := x + y \pmod{2^B}`. This instruction
|
||||||
does not depend on the signed/unsigned interpretation of the operands.
|
does not depend on the signed/unsigned interpretation of the operands.
|
||||||
|
|
||||||
|
Polymorphic over all integer types (vector and scalar).
|
||||||
|
|
||||||
|
.. inst:: a = iadd_imm x, Imm
|
||||||
|
|
||||||
|
Add immediate integer.
|
||||||
|
|
||||||
|
Same as :inst:`iadd`, but one operand is an immediate constant.
|
||||||
|
|
||||||
|
:arg iN x: Dynamic addend.
|
||||||
|
:arg Imm: Immediate addend.
|
||||||
|
|
||||||
|
Polymorphic over all scalar integer types.
|
||||||
|
|
||||||
.. inst:: a = isub x, y
|
.. inst:: a = isub x, y
|
||||||
|
|
||||||
Wrapping integer subtraction: :math:`a := x - y \pmod{2^B}`. This
|
Wrapping integer subtraction: :math:`a := x - y \pmod{2^B}`. This
|
||||||
instruction does not depend on the signed/unsigned interpretation of the
|
instruction does not depend on the signed/unsigned interpretation of the
|
||||||
operands.
|
operands.
|
||||||
|
|
||||||
.. todo:: Overflow arithmetic
|
Polymorphic over all integer types (vector and scalar).
|
||||||
|
|
||||||
|
.. inst:: a = isub_imm Imm, x
|
||||||
|
|
||||||
|
Immediate subtraction.
|
||||||
|
|
||||||
|
Also works as integer negation when :math:`Imm = 0`. Use :inst:`iadd_imm` with a
|
||||||
|
negative immediate operand for the reverse immediate subtraction.
|
||||||
|
|
||||||
|
:arg Imm: Immediate minuend.
|
||||||
|
:arg iN x: Dynamic subtrahend.
|
||||||
|
|
||||||
|
Polymorphic over all scalar integer types.
|
||||||
|
|
||||||
|
.. todo:: Integer overflow arithmetic
|
||||||
|
|
||||||
Add instructions for add with carry out / carry in and so on. Enough to
|
Add instructions for add with carry out / carry in and so on. Enough to
|
||||||
implement larger integer types efficiently. It should also be possible to
|
implement larger integer types efficiently. It should also be possible to
|
||||||
legalize :type:`i64` arithmetic to terms of :type:`i32` operations.
|
legalize :type:`i64` arithmetic to terms of :type:`i32` operations.
|
||||||
|
|
||||||
.. inst:: a = ineg x
|
|
||||||
|
|
||||||
Wrapping integer negation: :math:`a := -x \pmod{2^B}`. This instruction does
|
|
||||||
not depend on the signed/unsigned interpretation of the operand.
|
|
||||||
|
|
||||||
.. inst:: a = imul x, y
|
.. inst:: a = imul x, y
|
||||||
|
|
||||||
Wrapping integer multiplication: :math:`a := x y \pmod{2^B}`. This
|
Wrapping integer multiplication: :math:`a := x y \pmod{2^B}`. This
|
||||||
instruction does not depend on the signed/unsigned interpretation of the
|
instruction does not depend on the signed/unsigned interpretation of the
|
||||||
operands.
|
operands.
|
||||||
|
|
||||||
|
Polymorphic over all integer types (vector and scalar).
|
||||||
|
|
||||||
|
.. inst:: a = imul_imm x, Imm
|
||||||
|
|
||||||
|
Integer multiplication by immediate constant.
|
||||||
|
|
||||||
|
Polymorphic over all scalar integer types.
|
||||||
|
|
||||||
.. todo:: Larger multiplication results.
|
.. todo:: Larger multiplication results.
|
||||||
|
|
||||||
For example, ``smulx`` which multiplies :type:`i32` operands to produce a
|
For example, ``smulx`` which multiplies :type:`i32` operands to produce a
|
||||||
@@ -741,10 +781,11 @@ Integer operations
|
|||||||
Unsigned integer division: :math:`a := \lfloor {x \over y} \rfloor`. This
|
Unsigned integer division: :math:`a := \lfloor {x \over y} \rfloor`. This
|
||||||
operation traps if the divisor is zero.
|
operation traps if the divisor is zero.
|
||||||
|
|
||||||
.. todo::
|
.. inst:: a = udiv_imm x, Imm
|
||||||
Add a ``udiv_imm`` variant with an immediate divisor greater than 1.
|
|
||||||
This is useful for pattern-matching divide-by-constant, and this
|
Unsigned integer division by an immediate constant.
|
||||||
instruction would be non-trapping.
|
|
||||||
|
This instruction never traps because a divisor of zero is not allowed.
|
||||||
|
|
||||||
.. inst:: a = sdiv x, y
|
.. inst:: a = sdiv x, y
|
||||||
|
|
||||||
@@ -753,37 +794,52 @@ Integer operations
|
|||||||
the result is not representable in :math:`B` bits two's complement. This only
|
the result is not representable in :math:`B` bits two's complement. This only
|
||||||
happens when :math:`x = -2^{B-1}, y = -1`.
|
happens when :math:`x = -2^{B-1}, y = -1`.
|
||||||
|
|
||||||
.. todo::
|
.. inst:: a = sdiv_imm x, Imm
|
||||||
Add a ``sdiv_imm`` variant with an immediate non-zero divisor. This is
|
|
||||||
useful for pattern-matching divide-by-constant, and this instruction
|
Signed integer division by an immediate constant.
|
||||||
would be non-trapping. Don't allow divisors 0, 1, or -1.
|
|
||||||
|
This instruction never traps because a divisor of -1 or 0 is not allowed.
|
||||||
|
|
||||||
.. inst:: a = urem x, y
|
.. inst:: a = urem x, y
|
||||||
|
|
||||||
Unsigned integer remainder. This operation traps if the divisor is zero.
|
Unsigned integer remainder.
|
||||||
|
|
||||||
.. todo::
|
This operation traps if the divisor is zero.
|
||||||
Add a ``urem_imm`` non-trapping variant.
|
|
||||||
|
.. inst:: a = urem_imm x, Imm
|
||||||
|
|
||||||
|
Unsigned integer remainder with immediate divisor.
|
||||||
|
|
||||||
|
This instruction never traps because a divisor of zero is not allowed.
|
||||||
|
|
||||||
.. inst:: a = srem x, y
|
.. inst:: a = srem x, y
|
||||||
|
|
||||||
Signed integer remainder. This operation traps if the divisor is zero.
|
Signed integer remainder.
|
||||||
|
|
||||||
|
This operation traps if the divisor is zero.
|
||||||
|
|
||||||
|
.. todo:: Integer remainder vs modulus.
|
||||||
|
|
||||||
.. todo::
|
|
||||||
Clarify whether the result has the sign of the divisor or the dividend.
|
Clarify whether the result has the sign of the divisor or the dividend.
|
||||||
Should we add a ``smod`` instruction for the case where the result has
|
Should we add a ``smod`` instruction for the case where the result has
|
||||||
the same sign as the divisor?
|
the same sign as the divisor?
|
||||||
|
|
||||||
|
.. inst:: a = srem_imm x, Imm
|
||||||
|
|
||||||
|
Signed integer remainder with immediate divisor.
|
||||||
|
|
||||||
|
This instruction never traps because a divisor of 0 or -1 is not allowed.
|
||||||
|
|
||||||
.. todo:: Minimum / maximum.
|
.. todo:: Minimum / maximum.
|
||||||
|
|
||||||
NEON has ``smin``, ``smax``, ``umin``, and ``umax`` instructions. We should
|
NEON has ``smin``, ``smax``, ``umin``, and ``umax`` instructions. We should
|
||||||
replicate those for both scalar and vector integer types. Even if the
|
replicate those for both scalar and vector integer types. Even if the
|
||||||
target ISA doesn't have scalar operations, these are good pattern mtching
|
target ISA doesn't have scalar operations, these are good pattern matching
|
||||||
targets.
|
targets.
|
||||||
|
|
||||||
.. todo:: Saturating arithmetic.
|
.. todo:: Saturating arithmetic.
|
||||||
|
|
||||||
Mostly for SIMD use, but again these are good paterns to contract.
|
Mostly for SIMD use, but again these are good patterns for contraction.
|
||||||
Something like ``usatadd``, ``usatsub``, ``ssatadd``, and ``ssatsub`` is a
|
Something like ``usatadd``, ``usatsub``, ``ssatadd``, and ``ssatsub`` is a
|
||||||
good start.
|
good start.
|
||||||
|
|
||||||
@@ -825,9 +881,9 @@ Bitwise operations
|
|||||||
|
|
||||||
Rotate the bits in ``x`` by ``y`` places.
|
Rotate the bits in ``x`` by ``y`` places.
|
||||||
|
|
||||||
:param x: Integer value to be rotated.
|
:arg T x: Integer value to be rotated.
|
||||||
:param y: Number of bits to shift. Any integer type, not necessarily the
|
:arg iN y: Number of bits to shift. Any scalar integer type, not necessarily
|
||||||
same type as ``x``.
|
the same type as ``x``.
|
||||||
:rtype: Same type as ``x``.
|
:rtype: Same type as ``x``.
|
||||||
|
|
||||||
.. inst:: a = rotr x, y
|
.. inst:: a = rotr x, y
|
||||||
@@ -836,9 +892,9 @@ Bitwise operations
|
|||||||
|
|
||||||
Rotate the bits in ``x`` by ``y`` places.
|
Rotate the bits in ``x`` by ``y`` places.
|
||||||
|
|
||||||
:param x: Integer value to be rotated.
|
:arg T x: Integer value to be rotated.
|
||||||
:param y: Number of bits to shift. Any integer type, not necessarily the
|
:arg iN y: Number of bits to shift. Any scalar integer type, not necessarily
|
||||||
same type as ``x``.
|
the same type as ``x``.
|
||||||
:rtype: Same type as ``x``.
|
:rtype: Same type as ``x``.
|
||||||
|
|
||||||
.. inst:: a = ishl x, y
|
.. inst:: a = ishl x, y
|
||||||
@@ -848,9 +904,9 @@ Bitwise operations
|
|||||||
|
|
||||||
The shift amount is masked to the size of ``x``.
|
The shift amount is masked to the size of ``x``.
|
||||||
|
|
||||||
:param x: Integer value to be shifted.
|
:arg T x: Integer value to be shifted.
|
||||||
:param y: Number of bits to shift. Any integer type, not necessarily the
|
:arg iN y: Number of bits to shift. Any scalar integer type, not necessarily
|
||||||
same type as ``x``.
|
the same type as ``x``.
|
||||||
:rtype: Same type as ``x``.
|
:rtype: Same type as ``x``.
|
||||||
|
|
||||||
When shifting a B-bits integer type, this instruction computes:
|
When shifting a B-bits integer type, this instruction computes:
|
||||||
@@ -868,9 +924,9 @@ Bitwise operations
|
|||||||
|
|
||||||
The shift amount is masked to the size of the register.
|
The shift amount is masked to the size of the register.
|
||||||
|
|
||||||
:param x: Integer value to be shifted.
|
:arg T x: Integer value to be shifted.
|
||||||
:param y: Number of bits to shift. Can be any integer type, not necessarily
|
:arg iN y: Number of bits to shift. Can be any scalar integer type, not
|
||||||
the same type as ``x``.
|
necessarily the same type as ``x``.
|
||||||
:rtype: Same type as ``x``.
|
:rtype: Same type as ``x``.
|
||||||
|
|
||||||
When shifting a B-bits integer type, this instruction computes:
|
When shifting a B-bits integer type, this instruction computes:
|
||||||
@@ -888,9 +944,9 @@ Bitwise operations
|
|||||||
|
|
||||||
The shift amount is masked to the size of the register.
|
The shift amount is masked to the size of the register.
|
||||||
|
|
||||||
:param x: Integer value to be shifted.
|
:arg T x: Integer value to be shifted.
|
||||||
:param y: Number of bits to shift. Can be any integer type, not necessarily
|
:arg iN y: Number of bits to shift. Can be any scalar integer type, not
|
||||||
the same type as ``x``.
|
necessarily the same type as ``x``.
|
||||||
:rtype: Same type as ``x``.
|
:rtype: Same type as ``x``.
|
||||||
|
|
||||||
.. todo:: Add ``sshr_imm`` variant with an immediate ``y``.
|
.. todo:: Add ``sshr_imm`` variant with an immediate ``y``.
|
||||||
@@ -899,7 +955,7 @@ Bitwise operations
|
|||||||
|
|
||||||
Count leading zero bits.
|
Count leading zero bits.
|
||||||
|
|
||||||
:param x: Integer value.
|
:arg x: Integer value.
|
||||||
:rtype: :type:`i8`
|
:rtype: :type:`i8`
|
||||||
|
|
||||||
Starting from the MSB in ``x``, count the number of zero bits before
|
Starting from the MSB in ``x``, count the number of zero bits before
|
||||||
@@ -910,7 +966,7 @@ Bitwise operations
|
|||||||
|
|
||||||
Count leading sign bits.
|
Count leading sign bits.
|
||||||
|
|
||||||
:param x: Integer value.
|
:arg x: Integer value.
|
||||||
:rtype: :type:`i8`
|
:rtype: :type:`i8`
|
||||||
|
|
||||||
Starting from the MSB after the sign bit in ``x``, count the number of
|
Starting from the MSB after the sign bit in ``x``, count the number of
|
||||||
@@ -921,7 +977,7 @@ Bitwise operations
|
|||||||
|
|
||||||
Count trailing zeros.
|
Count trailing zeros.
|
||||||
|
|
||||||
:param x: Integer value.
|
:arg x: Integer value.
|
||||||
:rtype: :type:`i8`
|
:rtype: :type:`i8`
|
||||||
|
|
||||||
Starting from the LSB in ``x``, count the number of zero bits before
|
Starting from the LSB in ``x``, count the number of zero bits before
|
||||||
@@ -932,7 +988,7 @@ Bitwise operations
|
|||||||
|
|
||||||
Population count
|
Population count
|
||||||
|
|
||||||
:param x: Integer value.
|
:arg x: Integer value.
|
||||||
:rtype: :type:`i8`
|
:rtype: :type:`i8`
|
||||||
|
|
||||||
Count the number of one bits in ``x``.
|
Count the number of one bits in ``x``.
|
||||||
@@ -941,12 +997,14 @@ Bitwise operations
|
|||||||
Floating point operations
|
Floating point operations
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
.. inst:: a = fcmp cond, x, y
|
These operations generally follow IEEE 754-2008 semantics.
|
||||||
|
|
||||||
|
.. inst:: a = fcmp Cond, x, y
|
||||||
|
|
||||||
Floating point comparison.
|
Floating point comparison.
|
||||||
|
|
||||||
:param cond: Condition code determining how ``x`` and ``y`` are compared.
|
:arg Cond: Condition code determining how ``x`` and ``y`` are compared.
|
||||||
:param x, y: Floating point scalar or vector values of the same type.
|
:arg x,y: Floating point scalar or vector values of the same type.
|
||||||
:rtype: :type:`bool` or :type:`boolxN` with the same number of lanes as
|
:rtype: :type:`bool` or :type:`boolxN` with the same number of lanes as
|
||||||
``x`` and ``y``.
|
``x`` and ``y``.
|
||||||
|
|
||||||
@@ -978,7 +1036,7 @@ Floating point operations
|
|||||||
|
|
||||||
Floating point negation.
|
Floating point negation.
|
||||||
|
|
||||||
:returns: ``x`` with its sign bit inverted.
|
:result: ``x`` with its sign bit inverted.
|
||||||
|
|
||||||
Note that this is a pure bitwise operation.
|
Note that this is a pure bitwise operation.
|
||||||
|
|
||||||
@@ -986,7 +1044,7 @@ Floating point operations
|
|||||||
|
|
||||||
Floating point absolute value.
|
Floating point absolute value.
|
||||||
|
|
||||||
:returns: ``x`` with its sign bit cleared.
|
:result: ``x`` with its sign bit cleared.
|
||||||
|
|
||||||
Note that this is a pure bitwise operation.
|
Note that this is a pure bitwise operation.
|
||||||
|
|
||||||
@@ -994,18 +1052,19 @@ Floating point operations
|
|||||||
|
|
||||||
Floating point copy sign.
|
Floating point copy sign.
|
||||||
|
|
||||||
:returns: ``x`` with its sign changed to that of ``y``.
|
:result: ``x`` with its sign changed to that of ``y``.
|
||||||
|
|
||||||
Note that this is a pure bitwise operation. The sign bit from ``y`` is
|
Note that this is a pure bitwise operation. The sign bit from ``y`` is
|
||||||
copied to the sign bit of ``x``.
|
copied to the sign bit of ``x``.
|
||||||
|
|
||||||
.. inst:: fmul x, y
|
.. inst:: a = fmul x, y
|
||||||
.. inst:: fdiv x, y
|
.. inst:: a = fdiv x, y
|
||||||
.. inst:: fmin x, y
|
.. inst:: a = fmin x, y
|
||||||
.. inst:: fminnum x, y
|
.. inst:: a = fminnum x, y
|
||||||
.. inst:: fmax x, y
|
.. inst:: a = fmax x, y
|
||||||
.. inst:: fmaxnum x, y
|
.. inst:: a = fmaxnum x, y
|
||||||
.. inst:: ceil x
|
|
||||||
|
.. inst:: a = ceil x
|
||||||
|
|
||||||
Round floating point round to integral, towards positive infinity.
|
Round floating point round to integral, towards positive infinity.
|
||||||
|
|
||||||
@@ -1053,6 +1112,7 @@ Conversion operations
|
|||||||
.. inst:: a = cvt_utof x
|
.. inst:: a = cvt_utof x
|
||||||
.. inst:: a = cvt_stof x
|
.. inst:: a = cvt_stof x
|
||||||
|
|
||||||
|
|
||||||
Glossary
|
Glossary
|
||||||
========
|
========
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user