Move instruction definitions into meta.
Use the meta language to define instructions, just insert 'autoinst' references in langref.
This commit is contained in:
275
meta/cretonne/base.py
Normal file
275
meta/cretonne/base.py
Normal file
@@ -0,0 +1,275 @@
|
||||
"""
|
||||
Cretonne base instruction set.
|
||||
|
||||
This module defines the basic Cretonne instruction set that all targets support.
|
||||
"""
|
||||
from . import TypeVar, Operand, Instruction
|
||||
from types import i8
|
||||
from immediates import imm64
|
||||
|
||||
Int = TypeVar('Int', 'A scalar or vector integer type')
|
||||
iB = TypeVar('iB', 'A scalar integer type')
|
||||
|
||||
a = Operand('a', Int)
|
||||
x = Operand('x', Int)
|
||||
y = Operand('y', Int)
|
||||
|
||||
iadd = Instruction('iadd', r"""
|
||||
Wrapping integer addition: :math:`a := x + y \pmod{2^B}`.
|
||||
|
||||
This instruction does not depend on the signed/unsigned interpretation of
|
||||
the operands.
|
||||
""",
|
||||
ins=(x,y), outs=a)
|
||||
|
||||
isub = Instruction('isub', r"""
|
||||
Wrapping integer subtraction: :math:`a := x - y \pmod{2^B}`.
|
||||
|
||||
This instruction does not depend on the signed/unsigned interpretation of
|
||||
the operands.
|
||||
""",
|
||||
ins=(x,y), outs=a)
|
||||
|
||||
imul = Instruction('imul', r"""
|
||||
Wrapping integer multiplication: :math:`a := x y \pmod{2^B}`.
|
||||
|
||||
This instruction does not depend on the signed/unsigned interpretation of
|
||||
the
|
||||
operands.
|
||||
|
||||
Polymorphic over all integer types (vector and scalar).
|
||||
""",
|
||||
ins=(x,y), outs=a)
|
||||
|
||||
udiv = Instruction('udiv', r"""
|
||||
Unsigned integer division: :math:`a := \lfloor {x \over y} \rfloor`.
|
||||
|
||||
This operation traps if the divisor is zero.
|
||||
""",
|
||||
ins=(x,y), outs=a)
|
||||
|
||||
sdiv = Instruction('sdiv', r"""
|
||||
Signed integer division rounded toward zero: :math:`a := sign(xy) \lfloor
|
||||
{|x| \over |y|}\rfloor`.
|
||||
|
||||
This operation traps if the divisor is zero, or if the result is not
|
||||
representable in :math:`B` bits two's complement. This only happens when
|
||||
:math:`x = -2^{B-1}, y = -1`.
|
||||
""",
|
||||
ins=(x,y), outs=a)
|
||||
|
||||
urem = Instruction('urem', """
|
||||
Unsigned integer remainder.
|
||||
|
||||
This operation traps if the divisor is zero.
|
||||
""",
|
||||
ins=(x,y), outs=a)
|
||||
|
||||
srem = Instruction('srem', """
|
||||
Signed integer remainder.
|
||||
|
||||
This operation traps if the divisor is zero.
|
||||
|
||||
.. todo:: Integer remainder vs modulus.
|
||||
|
||||
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
|
||||
the same sign as the divisor?
|
||||
""",
|
||||
ins=(x,y), outs=a)
|
||||
|
||||
a = Operand('a', iB)
|
||||
x = Operand('x', iB)
|
||||
Y = Operand('Y', imm64)
|
||||
|
||||
iadd_imm = Instruction('iadd_imm', """
|
||||
Add immediate integer.
|
||||
|
||||
Same as :inst:`iadd`, but one operand is an immediate constant.
|
||||
|
||||
Polymorphic over all scalar integer types, but does not support vector
|
||||
types.
|
||||
""",
|
||||
ins=(x,Y), outs=a)
|
||||
|
||||
imul_imm = Instruction('imul_imm', """
|
||||
Integer multiplication by immediate constant.
|
||||
|
||||
Polymorphic over all scalar integer types.
|
||||
""",
|
||||
ins=(x,Y), outs=a)
|
||||
|
||||
udiv_imm = Instruction('udiv_imm', """
|
||||
Unsigned integer division by an immediate constant.
|
||||
|
||||
This instruction never traps because a divisor of zero is not allowed.
|
||||
""",
|
||||
ins=(x,Y), outs=a)
|
||||
|
||||
sdiv_imm = Instruction('sdiv_imm', """
|
||||
Signed integer division by an immediate constant.
|
||||
|
||||
This instruction never traps because a divisor of -1 or 0 is not allowed.
|
||||
""",
|
||||
ins=(x,Y), outs=a)
|
||||
|
||||
urem_imm = Instruction('urem_imm', """
|
||||
Unsigned integer remainder with immediate divisor.
|
||||
|
||||
This instruction never traps because a divisor of zero is not allowed.
|
||||
""",
|
||||
ins=(x,Y), outs=a)
|
||||
|
||||
srem_imm = Instruction('srem_imm', """
|
||||
Signed integer remainder with immediate divisor.
|
||||
|
||||
This instruction never traps because a divisor of 0 or -1 is not allowed.
|
||||
""",
|
||||
ins=(x,Y), outs=a)
|
||||
|
||||
# Swap x and y for isub_imm.
|
||||
X = Operand('X', imm64)
|
||||
y = Operand('y', iB)
|
||||
|
||||
isub_imm = Instruction('isub_imm', """
|
||||
Immediate wrapping subtraction: :math:`a := X - y \pmod{2^B}`.
|
||||
|
||||
Also works as integer negation when :math:`X = 0`. Use :inst:`iadd_imm` with a
|
||||
negative immediate operand for the reverse immediate subtraction.
|
||||
|
||||
Polymorphic over all scalar integer types, but does not support vector
|
||||
types.
|
||||
""",
|
||||
ins=(X,y), outs=a)
|
||||
|
||||
#
|
||||
# Bitwise operations.
|
||||
#
|
||||
|
||||
# TODO: Which types should permit boolean operations? Any reason to restrict?
|
||||
bits = TypeVar('bits', 'Any integer, float, or boolean scalar or vector type')
|
||||
x = Operand('x', bits)
|
||||
y = Operand('y', bits)
|
||||
a = Operand('a', bits)
|
||||
|
||||
band = Instruction('band', """
|
||||
Bitwise and.
|
||||
""",
|
||||
ins=(x,y), outs=a)
|
||||
|
||||
bor = Instruction('bor', """
|
||||
Bitwise or.
|
||||
""",
|
||||
ins=(x,y), outs=a)
|
||||
|
||||
bxor = Instruction('bxor', """
|
||||
Bitwise xor.
|
||||
""",
|
||||
ins=(x,y), outs=a)
|
||||
|
||||
bnot = Instruction('bnot', """
|
||||
Bitwise not.
|
||||
""",
|
||||
ins=x, outs=a)
|
||||
|
||||
# Shift/rotate.
|
||||
x = Operand('x', Int, doc='Scalar or vector value to shift')
|
||||
y = Operand('y', iB, doc='Number of bits to shift')
|
||||
a = Operand('a', Int)
|
||||
|
||||
rotl = Instruction('rotl', r"""
|
||||
Rotate left.
|
||||
|
||||
Rotate the bits in ``x`` by ``y`` places.
|
||||
""",
|
||||
ins=(x,y), outs=a)
|
||||
|
||||
rotr = Instruction('rotr', r"""
|
||||
Rotate right.
|
||||
|
||||
Rotate the bits in ``x`` by ``y`` places.
|
||||
""",
|
||||
ins=(x,y), outs=a)
|
||||
|
||||
ishl = Instruction('ishl', r"""
|
||||
Integer shift left. Shift the bits in ``x`` towards the MSB by ``y``
|
||||
places. Shift in zero bits to the LSB.
|
||||
|
||||
The shift amount is masked to the size of ``x``.
|
||||
|
||||
When shifting a B-bits integer type, this instruction computes:
|
||||
|
||||
.. math::
|
||||
s &:= y \pmod B, \\
|
||||
a &:= x \cdot 2^s \pmod{2^B}.
|
||||
|
||||
.. todo:: Add ``ishl_imm`` variant with an immediate ``y``.
|
||||
""",
|
||||
ins=(x,y), outs=a)
|
||||
|
||||
ushr = Instruction('ushr', r"""
|
||||
Unsigned shift right. Shift bits in ``x`` towards the LSB by ``y`` places,
|
||||
shifting in zero bits to the MSB. Also called a *logical shift*.
|
||||
|
||||
The shift amount is masked to the size of the register.
|
||||
|
||||
When shifting a B-bits integer type, this instruction computes:
|
||||
|
||||
.. math::
|
||||
s &:= y \pmod B, \\
|
||||
a &:= \lfloor x \cdot 2^{-s} \rfloor.
|
||||
|
||||
.. todo:: Add ``ushr_imm`` variant with an immediate ``y``.
|
||||
""",
|
||||
ins=(x,y), outs=a)
|
||||
|
||||
sshr = Instruction('sshr', r"""
|
||||
Signed shift right. Shift bits in ``x`` towards the LSB by ``y`` places,
|
||||
shifting in sign bits to the MSB. Also called an *arithmetic shift*.
|
||||
|
||||
The shift amount is masked to the size of the register.
|
||||
|
||||
.. todo:: Add ``sshr_imm`` variant with an immediate ``y``.
|
||||
""",
|
||||
ins=(x,y), outs=a)
|
||||
|
||||
#
|
||||
# Bit counting.
|
||||
#
|
||||
|
||||
x = Operand('x', iB)
|
||||
a = Operand('a', i8)
|
||||
|
||||
clz = Instruction('clz', r"""
|
||||
Count leading zero bits.
|
||||
|
||||
Starting from the MSB in ``x``, count the number of zero bits before
|
||||
reaching the first one bit. When ``x`` is zero, returns the size of x in
|
||||
bits.
|
||||
""",
|
||||
ins=x, outs=a)
|
||||
|
||||
cls = Instruction('cls', r"""
|
||||
Count leading sign bits.
|
||||
|
||||
Starting from the MSB after the sign bit in ``x``, count the number of
|
||||
consecutive bits identical to the sign bit. When ``x`` is 0 or -1, returns
|
||||
one less than the size of x in bits.
|
||||
""",
|
||||
ins=x, outs=a)
|
||||
|
||||
ctz = Instruction('ctz', r"""
|
||||
Count trailing zeros.
|
||||
|
||||
Starting from the LSB in ``x``, count the number of zero bits before
|
||||
reaching the first one bit. When ``x`` is zero, returns the size of x in
|
||||
bits.
|
||||
""",
|
||||
ins=x, outs=a)
|
||||
|
||||
popcnt = Instruction('popcnt', r"""
|
||||
Population count
|
||||
|
||||
Count the number of one bits in ``x``.
|
||||
""",
|
||||
ins=x, outs=a)
|
||||
Reference in New Issue
Block a user