PEP8 formatting.
This commit is contained in:
@@ -6,6 +6,7 @@ don't attempt parfect hashing, but simply generate an open addressed
|
|||||||
quadratically probed hash table.
|
quadratically probed hash table.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def simple_hash(s):
|
def simple_hash(s):
|
||||||
"""
|
"""
|
||||||
Compute a primitive hash of a string.
|
Compute a primitive hash of a string.
|
||||||
@@ -21,6 +22,7 @@ def simple_hash(s):
|
|||||||
h = ((h ^ ord(c)) + ((h >> 6) + (h << 26))) & 0xffffffff
|
h = ((h ^ ord(c)) + ((h >> 6) + (h << 26))) & 0xffffffff
|
||||||
return h
|
return h
|
||||||
|
|
||||||
|
|
||||||
def next_power_of_two(x):
|
def next_power_of_two(x):
|
||||||
"""
|
"""
|
||||||
Compute the next power of two that is greater than `x`:
|
Compute the next power of two that is greater than `x`:
|
||||||
@@ -41,6 +43,7 @@ def next_power_of_two(x):
|
|||||||
s *= 2
|
s *= 2
|
||||||
return x + 1
|
return x + 1
|
||||||
|
|
||||||
|
|
||||||
def compute_quadratic(items, hash_function):
|
def compute_quadratic(items, hash_function):
|
||||||
"""
|
"""
|
||||||
Compute an open addressed, quadratically probed hash table containing
|
Compute an open addressed, quadratically probed hash table containing
|
||||||
|
|||||||
@@ -7,15 +7,20 @@ instructions.
|
|||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
|
||||||
camel_re = re.compile('(^|_)([a-z])')
|
camel_re = re.compile('(^|_)([a-z])')
|
||||||
|
|
||||||
|
|
||||||
def camel_case(s):
|
def camel_case(s):
|
||||||
"""Convert the string s to CamelCase"""
|
"""Convert the string s to CamelCase"""
|
||||||
return camel_re.sub(lambda m: m.group(2).upper(), s)
|
return camel_re.sub(lambda m: m.group(2).upper(), s)
|
||||||
|
|
||||||
|
|
||||||
# Concrete types.
|
# Concrete types.
|
||||||
#
|
#
|
||||||
# Instances (i8, i32, ...) are provided in the cretonne.types module.
|
# Instances (i8, i32, ...) are provided in the cretonne.types module.
|
||||||
|
|
||||||
|
|
||||||
class Type(object):
|
class Type(object):
|
||||||
"""A concrete value type."""
|
"""A concrete value type."""
|
||||||
|
|
||||||
@@ -27,6 +32,7 @@ class Type(object):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
class ScalarType(Type):
|
class ScalarType(Type):
|
||||||
"""
|
"""
|
||||||
A concrete scalar (not vector) type.
|
A concrete scalar (not vector) type.
|
||||||
@@ -55,6 +61,7 @@ class ScalarType(Type):
|
|||||||
self._vectors[lanes] = v
|
self._vectors[lanes] = v
|
||||||
return v
|
return v
|
||||||
|
|
||||||
|
|
||||||
class VectorType(Type):
|
class VectorType(Type):
|
||||||
"""
|
"""
|
||||||
A concrete SIMD vector type.
|
A concrete SIMD vector type.
|
||||||
@@ -75,7 +82,9 @@ class VectorType(Type):
|
|||||||
self.lanes = lanes
|
self.lanes = lanes
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return 'VectorType(base={}, lanes={})'.format(self.base.name, self.lanes)
|
return ('VectorType(base={}, lanes={})'
|
||||||
|
.format(self.base.name, self.lanes))
|
||||||
|
|
||||||
|
|
||||||
class IntType(ScalarType):
|
class IntType(ScalarType):
|
||||||
"""A concrete scalar integer type."""
|
"""A concrete scalar integer type."""
|
||||||
@@ -91,17 +100,20 @@ class IntType(ScalarType):
|
|||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return 'IntType(bits={})'.format(self.bits)
|
return 'IntType(bits={})'.format(self.bits)
|
||||||
|
|
||||||
|
|
||||||
class FloatType(ScalarType):
|
class FloatType(ScalarType):
|
||||||
"""A concrete scalar floating point type."""
|
"""A concrete scalar floating point type."""
|
||||||
|
|
||||||
def __init__(self, bits, doc):
|
def __init__(self, bits, doc):
|
||||||
assert bits > 0, 'FloatType must have positive number of bits'
|
assert bits > 0, 'FloatType must have positive number of bits'
|
||||||
super(FloatType, self).__init__( name='f{:d}'.format(bits), membytes=bits/8, doc=doc)
|
super(FloatType, self).__init__(name='f{:d}'.format(bits),
|
||||||
|
membytes=bits/8, doc=doc)
|
||||||
self.bits = bits
|
self.bits = bits
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return 'FloatType(bits={})'.format(self.bits)
|
return 'FloatType(bits={})'.format(self.bits)
|
||||||
|
|
||||||
|
|
||||||
class BoolType(ScalarType):
|
class BoolType(ScalarType):
|
||||||
"""A concrete scalar boolean type."""
|
"""A concrete scalar boolean type."""
|
||||||
|
|
||||||
@@ -116,9 +128,9 @@ class BoolType(ScalarType):
|
|||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return 'BoolType(bits={})'.format(self.bits)
|
return 'BoolType(bits={})'.format(self.bits)
|
||||||
|
|
||||||
#
|
|
||||||
# Parametric polymorphism.
|
# Parametric polymorphism.
|
||||||
#
|
|
||||||
|
|
||||||
class TypeVar(object):
|
class TypeVar(object):
|
||||||
"""
|
"""
|
||||||
@@ -132,12 +144,13 @@ class TypeVar(object):
|
|||||||
self.name = name
|
self.name = name
|
||||||
self.__doc__ = doc
|
self.__doc__ = doc
|
||||||
|
|
||||||
#
|
|
||||||
# Immediate operands.
|
# Immediate operands.
|
||||||
#
|
#
|
||||||
# Instances of immediate operand types are provided in the cretonne.immediates
|
# Instances of immediate operand types are provided in the cretonne.immediates
|
||||||
# module.
|
# module.
|
||||||
|
|
||||||
|
|
||||||
class ImmediateType(object):
|
class ImmediateType(object):
|
||||||
"""
|
"""
|
||||||
The type of an immediate instruction operand.
|
The type of an immediate instruction operand.
|
||||||
@@ -153,9 +166,9 @@ class ImmediateType(object):
|
|||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return 'ImmediateType({})'.format(self.name)
|
return 'ImmediateType({})'.format(self.name)
|
||||||
|
|
||||||
#
|
|
||||||
# Defining instructions.
|
# Defining instructions.
|
||||||
#
|
|
||||||
|
|
||||||
class InstructionGroup(object):
|
class InstructionGroup(object):
|
||||||
"""
|
"""
|
||||||
@@ -178,7 +191,8 @@ class InstructionGroup(object):
|
|||||||
added to this group.
|
added to this group.
|
||||||
"""
|
"""
|
||||||
assert InstructionGroup._current is None, (
|
assert InstructionGroup._current is None, (
|
||||||
"Can't open {} since {} is already open".format(self, _current))
|
"Can't open {} since {} is already open"
|
||||||
|
.format(self, InstructionGroup._current))
|
||||||
InstructionGroup._current = self
|
InstructionGroup._current = self
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
@@ -187,7 +201,8 @@ class InstructionGroup(object):
|
|||||||
opening another instruction group.
|
opening another instruction group.
|
||||||
"""
|
"""
|
||||||
assert InstructionGroup._current is self, (
|
assert InstructionGroup._current is self, (
|
||||||
"Can't close {}, the open instuction group is {}".format(self, _current))
|
"Can't close {}, the open instuction group is {}"
|
||||||
|
.format(self, InstructionGroup._current))
|
||||||
InstructionGroup._current = None
|
InstructionGroup._current = None
|
||||||
|
|
||||||
def __init__(self, name, doc):
|
def __init__(self, name, doc):
|
||||||
@@ -198,9 +213,11 @@ class InstructionGroup(object):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def append(inst):
|
def append(inst):
|
||||||
assert InstructionGroup._current, "Open an instruction group before defining instructions."
|
assert InstructionGroup._current, \
|
||||||
|
"Open an instruction group before defining instructions."
|
||||||
InstructionGroup._current.instructions.append(inst)
|
InstructionGroup._current.instructions.append(inst)
|
||||||
|
|
||||||
|
|
||||||
class Operand(object):
|
class Operand(object):
|
||||||
"""
|
"""
|
||||||
An instruction operand.
|
An instruction operand.
|
||||||
@@ -212,12 +229,12 @@ class Operand(object):
|
|||||||
concrete type.
|
concrete type.
|
||||||
|
|
||||||
2. A :py:class:`TypeVar` instance indicates an SSA value operand, and the
|
2. A :py:class:`TypeVar` instance indicates an SSA value operand, and the
|
||||||
instruction is polymorphic over the possible concrete types that the type
|
instruction is polymorphic over the possible concrete types that the
|
||||||
variable can assume.
|
type variable can assume.
|
||||||
|
|
||||||
3. An :py:class:`ImmediateType` instance indicates an immediate operand
|
3. An :py:class:`ImmediateType` instance indicates an immediate operand
|
||||||
whose value is encoded in the instruction itself rather than being passed
|
whose value is encoded in the instruction itself rather than being
|
||||||
as an SSA value.
|
passed as an SSA value.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def __init__(self, name, typ, doc=''):
|
def __init__(self, name, typ, doc=''):
|
||||||
@@ -231,19 +248,20 @@ class Operand(object):
|
|||||||
else:
|
else:
|
||||||
return self.typ.__doc__
|
return self.typ.__doc__
|
||||||
|
|
||||||
|
|
||||||
class Instruction(object):
|
class Instruction(object):
|
||||||
"""
|
"""
|
||||||
An instruction.
|
An instruction.
|
||||||
|
|
||||||
The operands to the instruction are specified as two tuples: ``ins`` and
|
The operands to the instruction are specified as two tuples: ``ins`` and
|
||||||
``outs``. Since the Python singleton tuple syntax is a bit awkward, it is
|
``outs``. Since the Python singleton tuple syntax is a bit awkward, it is
|
||||||
allowed to specify a singleton as just the operand itself, i.e., `ins=x` and
|
allowed to specify a singleton as just the operand itself, i.e., `ins=x`
|
||||||
`ins=(x,)` are both allowed and mean the same thing.
|
and `ins=(x,)` are both allowed and mean the same thing.
|
||||||
|
|
||||||
:param name: Instruction mnemonic, also becomes opcode name.
|
:param name: Instruction mnemonic, also becomes opcode name.
|
||||||
:param doc: Documentation string.
|
:param doc: Documentation string.
|
||||||
:param ins: Tuple of input operands. This can be a mix of SSA value operands
|
:param ins: Tuple of input operands. This can be a mix of SSA value
|
||||||
and immediate operands.
|
operands and immediate operands.
|
||||||
:param outs: Tuple of output operands. The output operands can't be
|
:param outs: Tuple of output operands. The output operands can't be
|
||||||
immediates.
|
immediates.
|
||||||
"""
|
"""
|
||||||
@@ -258,8 +276,8 @@ class Instruction(object):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _to_operand_tuple(x):
|
def _to_operand_tuple(x):
|
||||||
# Allow a single Operand instance instead of the awkward singleton tuple
|
# Allow a single Operand instance instead of the awkward singleton
|
||||||
# syntax.
|
# tuple syntax.
|
||||||
if isinstance(x, Operand):
|
if isinstance(x, Operand):
|
||||||
x = (x,)
|
x = (x,)
|
||||||
else:
|
else:
|
||||||
@@ -268,9 +286,10 @@ class Instruction(object):
|
|||||||
assert isinstance(op, Operand)
|
assert isinstance(op, Operand)
|
||||||
return x
|
return x
|
||||||
|
|
||||||
#
|
|
||||||
# Defining targets
|
# Defining targets
|
||||||
#
|
|
||||||
|
|
||||||
class Target(object):
|
class Target(object):
|
||||||
"""
|
"""
|
||||||
A target instruction set architecture.
|
A target instruction set architecture.
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
"""
|
"""
|
||||||
Cretonne base instruction set.
|
Cretonne base instruction set.
|
||||||
|
|
||||||
This module defines the basic Cretonne instruction set that all targets support.
|
This module defines the basic Cretonne instruction set that all targets
|
||||||
|
support.
|
||||||
"""
|
"""
|
||||||
from . import TypeVar, Operand, Instruction, InstructionGroup
|
from . import TypeVar, Operand, Instruction, InstructionGroup
|
||||||
from types import i8, f32, f64
|
from types import i8, f32, f64
|
||||||
@@ -19,17 +20,19 @@ TxN = TypeVar('%Tx%N', 'A SIMD vector type')
|
|||||||
|
|
||||||
N = Operand('N', imm64)
|
N = Operand('N', imm64)
|
||||||
a = Operand('a', Int, doc='A constant integer scalar or vector value')
|
a = Operand('a', Int, doc='A constant integer scalar or vector value')
|
||||||
iconst = Instruction('iconst', r"""
|
iconst = Instruction(
|
||||||
|
'iconst', r"""
|
||||||
Integer constant.
|
Integer constant.
|
||||||
|
|
||||||
Create a scalar integer SSA value with an immediate constant value, or an
|
Create a scalar integer SSA value with an immediate constant value, or
|
||||||
integer vector where all the lanes have the same value.
|
an integer vector where all the lanes have the same value.
|
||||||
""",
|
""",
|
||||||
ins=N, outs=a)
|
ins=N, outs=a)
|
||||||
|
|
||||||
N = Operand('N', ieee32)
|
N = Operand('N', ieee32)
|
||||||
a = Operand('a', f32, doc='A constant integer scalar or vector value')
|
a = Operand('a', f32, doc='A constant integer scalar or vector value')
|
||||||
f32const = Instruction('f32const', r"""
|
f32const = Instruction(
|
||||||
|
'f32const', r"""
|
||||||
Floating point constant.
|
Floating point constant.
|
||||||
|
|
||||||
Create a :type:`f32` SSA value with an immediate constant value, or a
|
Create a :type:`f32` SSA value with an immediate constant value, or a
|
||||||
@@ -39,7 +42,8 @@ f32const = Instruction('f32const', r"""
|
|||||||
|
|
||||||
N = Operand('N', ieee64)
|
N = Operand('N', ieee64)
|
||||||
a = Operand('a', f64, doc='A constant integer scalar or vector value')
|
a = Operand('a', f64, doc='A constant integer scalar or vector value')
|
||||||
f64const = Instruction('f64const', r"""
|
f64const = Instruction(
|
||||||
|
'f64const', r"""
|
||||||
Floating point constant.
|
Floating point constant.
|
||||||
|
|
||||||
Create a :type:`f64` SSA value with an immediate constant value, or a
|
Create a :type:`f64` SSA value with an immediate constant value, or a
|
||||||
@@ -49,7 +53,8 @@ f64const = Instruction('f64const', r"""
|
|||||||
|
|
||||||
N = Operand('N', immvector)
|
N = Operand('N', immvector)
|
||||||
a = Operand('a', TxN, doc='A constant vector value')
|
a = Operand('a', TxN, doc='A constant vector value')
|
||||||
vconst = Instruction('vconst', r"""
|
vconst = Instruction(
|
||||||
|
'vconst', r"""
|
||||||
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.
|
Create a SIMD vector value where the lanes don't have to be identical.
|
||||||
@@ -64,58 +69,65 @@ a = Operand('a', Int)
|
|||||||
x = Operand('x', Int)
|
x = Operand('x', Int)
|
||||||
y = Operand('y', Int)
|
y = Operand('y', Int)
|
||||||
|
|
||||||
iadd = Instruction('iadd', r"""
|
iadd = Instruction(
|
||||||
|
'iadd', r"""
|
||||||
Wrapping integer addition: :math:`a := x + y \pmod{2^B}`.
|
Wrapping integer addition: :math:`a := x + y \pmod{2^B}`.
|
||||||
|
|
||||||
This instruction does not depend on the signed/unsigned interpretation of
|
This instruction does not depend on the signed/unsigned interpretation
|
||||||
the operands.
|
of the operands.
|
||||||
""",
|
""",
|
||||||
ins=(x, y), outs=a)
|
ins=(x, y), outs=a)
|
||||||
|
|
||||||
isub = Instruction('isub', r"""
|
isub = Instruction(
|
||||||
|
'isub', r"""
|
||||||
Wrapping integer subtraction: :math:`a := x - y \pmod{2^B}`.
|
Wrapping integer subtraction: :math:`a := x - y \pmod{2^B}`.
|
||||||
|
|
||||||
This instruction does not depend on the signed/unsigned interpretation of
|
This instruction does not depend on the signed/unsigned interpretation
|
||||||
the operands.
|
of the operands.
|
||||||
""",
|
""",
|
||||||
ins=(x, y), outs=a)
|
ins=(x, y), outs=a)
|
||||||
|
|
||||||
imul = Instruction('imul', r"""
|
imul = Instruction(
|
||||||
|
'imul', r"""
|
||||||
Wrapping integer multiplication: :math:`a := x y \pmod{2^B}`.
|
Wrapping integer multiplication: :math:`a := x y \pmod{2^B}`.
|
||||||
|
|
||||||
This instruction does not depend on the signed/unsigned interpretation of
|
This instruction does not depend on the signed/unsigned interpretation
|
||||||
the
|
of the
|
||||||
operands.
|
operands.
|
||||||
|
|
||||||
Polymorphic over all integer types (vector and scalar).
|
Polymorphic over all integer types (vector and scalar).
|
||||||
""",
|
""",
|
||||||
ins=(x, y), outs=a)
|
ins=(x, y), outs=a)
|
||||||
|
|
||||||
udiv = Instruction('udiv', r"""
|
udiv = Instruction(
|
||||||
|
'udiv', r"""
|
||||||
Unsigned integer division: :math:`a := \lfloor {x \over y} \rfloor`.
|
Unsigned integer division: :math:`a := \lfloor {x \over y} \rfloor`.
|
||||||
|
|
||||||
This operation traps if the divisor is zero.
|
This operation traps if the divisor is zero.
|
||||||
""",
|
""",
|
||||||
ins=(x, y), outs=a)
|
ins=(x, y), outs=a)
|
||||||
|
|
||||||
sdiv = Instruction('sdiv', r"""
|
sdiv = Instruction(
|
||||||
Signed integer division rounded toward zero: :math:`a := sign(xy) \lfloor
|
'sdiv', r"""
|
||||||
{|x| \over |y|}\rfloor`.
|
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
|
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
|
representable in :math:`B` bits two's complement. This only happens
|
||||||
:math:`x = -2^{B-1}, y = -1`.
|
when :math:`x = -2^{B-1}, y = -1`.
|
||||||
""",
|
""",
|
||||||
ins=(x, y), outs=a)
|
ins=(x, y), outs=a)
|
||||||
|
|
||||||
urem = Instruction('urem', """
|
urem = Instruction(
|
||||||
|
'urem', """
|
||||||
Unsigned integer remainder.
|
Unsigned integer remainder.
|
||||||
|
|
||||||
This operation traps if the divisor is zero.
|
This operation traps if the divisor is zero.
|
||||||
""",
|
""",
|
||||||
ins=(x, y), outs=a)
|
ins=(x, y), outs=a)
|
||||||
|
|
||||||
srem = Instruction('srem', """
|
srem = Instruction(
|
||||||
|
'srem', """
|
||||||
Signed integer remainder.
|
Signed integer remainder.
|
||||||
|
|
||||||
This operation traps if the divisor is zero.
|
This operation traps if the divisor is zero.
|
||||||
@@ -132,7 +144,8 @@ a = Operand('a', iB)
|
|||||||
x = Operand('x', iB)
|
x = Operand('x', iB)
|
||||||
Y = Operand('Y', imm64)
|
Y = Operand('Y', imm64)
|
||||||
|
|
||||||
iadd_imm = Instruction('iadd_imm', """
|
iadd_imm = Instruction(
|
||||||
|
'iadd_imm', """
|
||||||
Add immediate integer.
|
Add immediate integer.
|
||||||
|
|
||||||
Same as :inst:`iadd`, but one operand is an immediate constant.
|
Same as :inst:`iadd`, but one operand is an immediate constant.
|
||||||
@@ -142,50 +155,57 @@ iadd_imm = Instruction('iadd_imm', """
|
|||||||
""",
|
""",
|
||||||
ins=(x, Y), outs=a)
|
ins=(x, Y), outs=a)
|
||||||
|
|
||||||
imul_imm = Instruction('imul_imm', """
|
imul_imm = Instruction(
|
||||||
|
'imul_imm', """
|
||||||
Integer multiplication by immediate constant.
|
Integer multiplication by immediate constant.
|
||||||
|
|
||||||
Polymorphic over all scalar integer types.
|
Polymorphic over all scalar integer types.
|
||||||
""",
|
""",
|
||||||
ins=(x, Y), outs=a)
|
ins=(x, Y), outs=a)
|
||||||
|
|
||||||
udiv_imm = Instruction('udiv_imm', """
|
udiv_imm = Instruction(
|
||||||
|
'udiv_imm', """
|
||||||
Unsigned integer division by an immediate constant.
|
Unsigned integer division by an immediate constant.
|
||||||
|
|
||||||
This instruction never traps because a divisor of zero is not allowed.
|
This instruction never traps because a divisor of zero is not allowed.
|
||||||
""",
|
""",
|
||||||
ins=(x, Y), outs=a)
|
ins=(x, Y), outs=a)
|
||||||
|
|
||||||
sdiv_imm = Instruction('sdiv_imm', """
|
sdiv_imm = Instruction(
|
||||||
|
'sdiv_imm', """
|
||||||
Signed integer division by an immediate constant.
|
Signed integer division by an immediate constant.
|
||||||
|
|
||||||
This instruction never traps because a divisor of -1 or 0 is not allowed.
|
This instruction never traps because a divisor of -1 or 0 is not
|
||||||
""",
|
allowed. """,
|
||||||
ins=(x, Y), outs=a)
|
ins=(x, Y), outs=a)
|
||||||
|
|
||||||
urem_imm = Instruction('urem_imm', """
|
urem_imm = Instruction(
|
||||||
|
'urem_imm', """
|
||||||
Unsigned integer remainder with immediate divisor.
|
Unsigned integer remainder with immediate divisor.
|
||||||
|
|
||||||
This instruction never traps because a divisor of zero is not allowed.
|
This instruction never traps because a divisor of zero is not allowed.
|
||||||
""",
|
""",
|
||||||
ins=(x, Y), outs=a)
|
ins=(x, Y), outs=a)
|
||||||
|
|
||||||
srem_imm = Instruction('srem_imm', """
|
srem_imm = Instruction(
|
||||||
|
'srem_imm', """
|
||||||
Signed integer remainder with immediate divisor.
|
Signed integer remainder with immediate divisor.
|
||||||
|
|
||||||
This instruction never traps because a divisor of 0 or -1 is not allowed.
|
This instruction never traps because a divisor of 0 or -1 is not
|
||||||
""",
|
allowed. """,
|
||||||
ins=(x, Y), outs=a)
|
ins=(x, Y), outs=a)
|
||||||
|
|
||||||
# Swap x and y for isub_imm.
|
# Swap x and y for isub_imm.
|
||||||
X = Operand('X', imm64)
|
X = Operand('X', imm64)
|
||||||
y = Operand('y', iB)
|
y = Operand('y', iB)
|
||||||
|
|
||||||
isub_imm = Instruction('isub_imm', """
|
isub_imm = Instruction(
|
||||||
|
'isub_imm', """
|
||||||
Immediate wrapping subtraction: :math:`a := X - y \pmod{2^B}`.
|
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
|
Also works as integer negation when :math:`X = 0`. Use :inst:`iadd_imm`
|
||||||
negative immediate operand for the reverse immediate subtraction.
|
with a negative immediate operand for the reverse immediate
|
||||||
|
subtraction.
|
||||||
|
|
||||||
Polymorphic over all scalar integer types, but does not support vector
|
Polymorphic over all scalar integer types, but does not support vector
|
||||||
types.
|
types.
|
||||||
@@ -202,22 +222,26 @@ x = Operand('x', bits)
|
|||||||
y = Operand('y', bits)
|
y = Operand('y', bits)
|
||||||
a = Operand('a', bits)
|
a = Operand('a', bits)
|
||||||
|
|
||||||
band = Instruction('band', """
|
band = Instruction(
|
||||||
|
'band', """
|
||||||
Bitwise and.
|
Bitwise and.
|
||||||
""",
|
""",
|
||||||
ins=(x, y), outs=a)
|
ins=(x, y), outs=a)
|
||||||
|
|
||||||
bor = Instruction('bor', """
|
bor = Instruction(
|
||||||
|
'bor', """
|
||||||
Bitwise or.
|
Bitwise or.
|
||||||
""",
|
""",
|
||||||
ins=(x, y), outs=a)
|
ins=(x, y), outs=a)
|
||||||
|
|
||||||
bxor = Instruction('bxor', """
|
bxor = Instruction(
|
||||||
|
'bxor', """
|
||||||
Bitwise xor.
|
Bitwise xor.
|
||||||
""",
|
""",
|
||||||
ins=(x, y), outs=a)
|
ins=(x, y), outs=a)
|
||||||
|
|
||||||
bnot = Instruction('bnot', """
|
bnot = Instruction(
|
||||||
|
'bnot', """
|
||||||
Bitwise not.
|
Bitwise not.
|
||||||
""",
|
""",
|
||||||
ins=x, outs=a)
|
ins=x, outs=a)
|
||||||
@@ -227,21 +251,24 @@ x = Operand('x', Int, doc='Scalar or vector value to shift')
|
|||||||
y = Operand('y', iB, doc='Number of bits to shift')
|
y = Operand('y', iB, doc='Number of bits to shift')
|
||||||
a = Operand('a', Int)
|
a = Operand('a', Int)
|
||||||
|
|
||||||
rotl = Instruction('rotl', r"""
|
rotl = Instruction(
|
||||||
|
'rotl', r"""
|
||||||
Rotate left.
|
Rotate left.
|
||||||
|
|
||||||
Rotate the bits in ``x`` by ``y`` places.
|
Rotate the bits in ``x`` by ``y`` places.
|
||||||
""",
|
""",
|
||||||
ins=(x, y), outs=a)
|
ins=(x, y), outs=a)
|
||||||
|
|
||||||
rotr = Instruction('rotr', r"""
|
rotr = Instruction(
|
||||||
|
'rotr', r"""
|
||||||
Rotate right.
|
Rotate right.
|
||||||
|
|
||||||
Rotate the bits in ``x`` by ``y`` places.
|
Rotate the bits in ``x`` by ``y`` places.
|
||||||
""",
|
""",
|
||||||
ins=(x, y), outs=a)
|
ins=(x, y), outs=a)
|
||||||
|
|
||||||
ishl = Instruction('ishl', r"""
|
ishl = Instruction(
|
||||||
|
'ishl', r"""
|
||||||
Integer shift left. Shift the bits in ``x`` towards the MSB by ``y``
|
Integer shift left. Shift the bits in ``x`` towards the MSB by ``y``
|
||||||
places. Shift in zero bits to the LSB.
|
places. Shift in zero bits to the LSB.
|
||||||
|
|
||||||
@@ -257,9 +284,11 @@ ishl = Instruction('ishl', r"""
|
|||||||
""",
|
""",
|
||||||
ins=(x, y), outs=a)
|
ins=(x, y), outs=a)
|
||||||
|
|
||||||
ushr = Instruction('ushr', r"""
|
ushr = Instruction(
|
||||||
Unsigned shift right. Shift bits in ``x`` towards the LSB by ``y`` places,
|
'ushr', r"""
|
||||||
shifting in zero bits to the MSB. Also called a *logical shift*.
|
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.
|
The shift amount is masked to the size of the register.
|
||||||
|
|
||||||
@@ -273,9 +302,11 @@ ushr = Instruction('ushr', r"""
|
|||||||
""",
|
""",
|
||||||
ins=(x, y), outs=a)
|
ins=(x, y), outs=a)
|
||||||
|
|
||||||
sshr = Instruction('sshr', r"""
|
sshr = Instruction(
|
||||||
Signed shift right. Shift bits in ``x`` towards the LSB by ``y`` places,
|
'sshr', r"""
|
||||||
shifting in sign bits to the MSB. Also called an *arithmetic shift*.
|
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.
|
The shift amount is masked to the size of the register.
|
||||||
|
|
||||||
@@ -290,34 +321,38 @@ sshr = Instruction('sshr', r"""
|
|||||||
x = Operand('x', iB)
|
x = Operand('x', iB)
|
||||||
a = Operand('a', i8)
|
a = Operand('a', i8)
|
||||||
|
|
||||||
clz = Instruction('clz', r"""
|
clz = Instruction(
|
||||||
|
'clz', r"""
|
||||||
Count leading zero bits.
|
Count leading zero bits.
|
||||||
|
|
||||||
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
|
||||||
reaching the first one bit. When ``x`` is zero, returns the size of x in
|
reaching the first one bit. When ``x`` is zero, returns the size of x
|
||||||
bits.
|
in bits.
|
||||||
""",
|
""",
|
||||||
ins=x, outs=a)
|
ins=x, outs=a)
|
||||||
|
|
||||||
cls = Instruction('cls', r"""
|
cls = Instruction(
|
||||||
|
'cls', r"""
|
||||||
Count leading sign bits.
|
Count leading sign bits.
|
||||||
|
|
||||||
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
|
||||||
consecutive bits identical to the sign bit. When ``x`` is 0 or -1, returns
|
consecutive bits identical to the sign bit. When ``x`` is 0 or -1,
|
||||||
one less than the size of x in bits.
|
returns one less than the size of x in bits.
|
||||||
""",
|
""",
|
||||||
ins=x, outs=a)
|
ins=x, outs=a)
|
||||||
|
|
||||||
ctz = Instruction('ctz', r"""
|
ctz = Instruction(
|
||||||
|
'ctz', r"""
|
||||||
Count trailing zeros.
|
Count trailing zeros.
|
||||||
|
|
||||||
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
|
||||||
reaching the first one bit. When ``x`` is zero, returns the size of x in
|
reaching the first one bit. When ``x`` is zero, returns the size of x
|
||||||
bits.
|
in bits.
|
||||||
""",
|
""",
|
||||||
ins=x, outs=a)
|
ins=x, outs=a)
|
||||||
|
|
||||||
popcnt = Instruction('popcnt', r"""
|
popcnt = Instruction(
|
||||||
|
'popcnt', r"""
|
||||||
Population count
|
Population count
|
||||||
|
|
||||||
Count the number of one bits in ``x``.
|
Count the number of one bits in ``x``.
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ The cretonne.types module predefines all the Cretonne scalar types.
|
|||||||
from . import ScalarType, IntType, FloatType, BoolType
|
from . import ScalarType, IntType, FloatType, BoolType
|
||||||
|
|
||||||
#: Boolean.
|
#: Boolean.
|
||||||
b1 = ScalarType('b1', 0,
|
b1 = ScalarType(
|
||||||
|
'b1', 0,
|
||||||
"""
|
"""
|
||||||
A boolean value that is either true or false.
|
A boolean value that is either true or false.
|
||||||
""")
|
""")
|
||||||
@@ -21,17 +22,17 @@ i32 = IntType(32) #: 32-bit int.
|
|||||||
i64 = IntType(64) #: 64-bit int.
|
i64 = IntType(64) #: 64-bit int.
|
||||||
|
|
||||||
#: IEEE single precision.
|
#: IEEE single precision.
|
||||||
f32 = FloatType(32,
|
f32 = FloatType(
|
||||||
"""
|
32, """
|
||||||
A 32-bit floating point type represented in the IEEE 754-2008 *binary32*
|
A 32-bit floating point type represented in the IEEE 754-2008
|
||||||
interchange format. This corresponds to the :c:type:`float` type in most
|
*binary32* interchange format. This corresponds to the :c:type:`float`
|
||||||
C implementations.
|
type in most C implementations.
|
||||||
""")
|
""")
|
||||||
|
|
||||||
#: IEEE double precision.
|
#: IEEE double precision.
|
||||||
f64 = FloatType(64,
|
f64 = FloatType(
|
||||||
"""
|
64, """
|
||||||
A 64-bit floating point type represented in the IEEE 754-2008 *binary64*
|
A 64-bit floating point type represented in the IEEE 754-2008
|
||||||
interchange format. This corresponds to the :c:type:`double` type in
|
*binary64* interchange format. This corresponds to the :c:type:`double`
|
||||||
most C implementations.
|
type in most C implementations.
|
||||||
""")
|
""")
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ Generate sources with instruction info.
|
|||||||
import srcgen
|
import srcgen
|
||||||
import constant_hash
|
import constant_hash
|
||||||
|
|
||||||
|
|
||||||
def collect_instr_groups(targets):
|
def collect_instr_groups(targets):
|
||||||
seen = set()
|
seen = set()
|
||||||
groups = []
|
groups = []
|
||||||
@@ -15,6 +16,7 @@ def collect_instr_groups(targets):
|
|||||||
seen.add(g)
|
seen.add(g)
|
||||||
return groups
|
return groups
|
||||||
|
|
||||||
|
|
||||||
def gen_opcodes(groups, out_dir):
|
def gen_opcodes(groups, out_dir):
|
||||||
"""Generate opcode enumerations."""
|
"""Generate opcode enumerations."""
|
||||||
fmt = srcgen.Formatter()
|
fmt = srcgen.Formatter()
|
||||||
@@ -46,9 +48,12 @@ def gen_opcodes(groups, out_dir):
|
|||||||
fmt.format('Opcode::{} => "{}",', i.camel_name, i.name)
|
fmt.format('Opcode::{} => "{}",', i.camel_name, i.name)
|
||||||
|
|
||||||
# Generate an opcode hash table for looking up opcodes by name.
|
# Generate an opcode hash table for looking up opcodes by name.
|
||||||
hash_table = constant_hash.compute_quadratic(instrs,
|
hash_table = constant_hash.compute_quadratic(
|
||||||
|
instrs,
|
||||||
lambda i: constant_hash.simple_hash(i.name))
|
lambda i: constant_hash.simple_hash(i.name))
|
||||||
with fmt.indented('const OPCODE_HASH_TABLE: [Opcode; {}] = ['.format(len(hash_table)), '];'):
|
with fmt.indented(
|
||||||
|
'const OPCODE_HASH_TABLE: [Opcode; {}] = ['
|
||||||
|
.format(len(hash_table)), '];'):
|
||||||
for i in hash_table:
|
for i in hash_table:
|
||||||
if i is None:
|
if i is None:
|
||||||
fmt.line('Opcode::NotAnOpcode,')
|
fmt.line('Opcode::NotAnOpcode,')
|
||||||
@@ -57,6 +62,7 @@ def gen_opcodes(groups, out_dir):
|
|||||||
|
|
||||||
fmt.update_file('opcodes.rs', out_dir)
|
fmt.update_file('opcodes.rs', out_dir)
|
||||||
|
|
||||||
|
|
||||||
def generate(targets, out_dir):
|
def generate(targets, out_dir):
|
||||||
groups = collect_instr_groups(targets)
|
groups = collect_instr_groups(targets)
|
||||||
gen_opcodes(groups, out_dir)
|
gen_opcodes(groups, out_dir)
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ source code.
|
|||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
||||||
class Formatter(object):
|
class Formatter(object):
|
||||||
"""
|
"""
|
||||||
Source code formatter class.
|
Source code formatter class.
|
||||||
@@ -70,7 +71,7 @@ class Formatter(object):
|
|||||||
self.after = after
|
self.after = after
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
self.fmt.indent_push();
|
self.fmt.indent_push()
|
||||||
|
|
||||||
def __exit__(self, t, v, tb):
|
def __exit__(self, t, v, tb):
|
||||||
self.fmt.indent_pop()
|
self.fmt.indent_pop()
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ set architecture supported by Cretonne.
|
|||||||
|
|
||||||
from . import riscv
|
from . import riscv
|
||||||
|
|
||||||
|
|
||||||
def all_targets():
|
def all_targets():
|
||||||
"""
|
"""
|
||||||
Get a list of all the supported targets. Each target is represented as a
|
Get a list of all the supported targets. Each target is represented as a
|
||||||
|
|||||||
@@ -2,9 +2,10 @@
|
|||||||
RISC-V Target
|
RISC-V Target
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
`RISC-V <http://riscv.org/>`_ is an open instruction set architecture originally
|
`RISC-V <http://riscv.org/>`_ is an open instruction set architecture
|
||||||
developed at UC Berkeley. It is a RISC-style ISA with either a 32-bit (RV32I) or
|
originally developed at UC Berkeley. It is a RISC-style ISA with either a
|
||||||
64-bit (RV32I) base instruction set and a number of optional extensions:
|
32-bit (RV32I) or 64-bit (RV32I) base instruction set and a number of optional
|
||||||
|
extensions:
|
||||||
|
|
||||||
RV32M / RV64M
|
RV32M / RV64M
|
||||||
Integer multiplication and division.
|
Integer multiplication and division.
|
||||||
|
|||||||
Reference in New Issue
Block a user