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.
|
||||
"""
|
||||
|
||||
|
||||
def simple_hash(s):
|
||||
"""
|
||||
Compute a primitive hash of a string.
|
||||
@@ -21,6 +22,7 @@ def simple_hash(s):
|
||||
h = ((h ^ ord(c)) + ((h >> 6) + (h << 26))) & 0xffffffff
|
||||
return h
|
||||
|
||||
|
||||
def next_power_of_two(x):
|
||||
"""
|
||||
Compute the next power of two that is greater than `x`:
|
||||
@@ -41,6 +43,7 @@ def next_power_of_two(x):
|
||||
s *= 2
|
||||
return x + 1
|
||||
|
||||
|
||||
def compute_quadratic(items, hash_function):
|
||||
"""
|
||||
Compute an open addressed, quadratically probed hash table containing
|
||||
|
||||
@@ -7,15 +7,20 @@ instructions.
|
||||
|
||||
import re
|
||||
|
||||
|
||||
camel_re = re.compile('(^|_)([a-z])')
|
||||
|
||||
|
||||
def camel_case(s):
|
||||
"""Convert the string s to CamelCase"""
|
||||
return camel_re.sub(lambda m: m.group(2).upper(), s)
|
||||
|
||||
|
||||
# Concrete types.
|
||||
#
|
||||
# Instances (i8, i32, ...) are provided in the cretonne.types module.
|
||||
|
||||
|
||||
class Type(object):
|
||||
"""A concrete value type."""
|
||||
|
||||
@@ -27,6 +32,7 @@ class Type(object):
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
class ScalarType(Type):
|
||||
"""
|
||||
A concrete scalar (not vector) type.
|
||||
@@ -55,6 +61,7 @@ class ScalarType(Type):
|
||||
self._vectors[lanes] = v
|
||||
return v
|
||||
|
||||
|
||||
class VectorType(Type):
|
||||
"""
|
||||
A concrete SIMD vector type.
|
||||
@@ -75,7 +82,9 @@ class VectorType(Type):
|
||||
self.lanes = lanes
|
||||
|
||||
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):
|
||||
"""A concrete scalar integer type."""
|
||||
@@ -91,17 +100,20 @@ class IntType(ScalarType):
|
||||
def __repr__(self):
|
||||
return 'IntType(bits={})'.format(self.bits)
|
||||
|
||||
|
||||
class FloatType(ScalarType):
|
||||
"""A concrete scalar floating point type."""
|
||||
|
||||
def __init__(self, bits, doc):
|
||||
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
|
||||
|
||||
def __repr__(self):
|
||||
return 'FloatType(bits={})'.format(self.bits)
|
||||
|
||||
|
||||
class BoolType(ScalarType):
|
||||
"""A concrete scalar boolean type."""
|
||||
|
||||
@@ -116,9 +128,9 @@ class BoolType(ScalarType):
|
||||
def __repr__(self):
|
||||
return 'BoolType(bits={})'.format(self.bits)
|
||||
|
||||
#
|
||||
|
||||
# Parametric polymorphism.
|
||||
#
|
||||
|
||||
|
||||
class TypeVar(object):
|
||||
"""
|
||||
@@ -132,12 +144,13 @@ class TypeVar(object):
|
||||
self.name = name
|
||||
self.__doc__ = doc
|
||||
|
||||
#
|
||||
|
||||
# Immediate operands.
|
||||
#
|
||||
# Instances of immediate operand types are provided in the cretonne.immediates
|
||||
# module.
|
||||
|
||||
|
||||
class ImmediateType(object):
|
||||
"""
|
||||
The type of an immediate instruction operand.
|
||||
@@ -153,9 +166,9 @@ class ImmediateType(object):
|
||||
def __repr__(self):
|
||||
return 'ImmediateType({})'.format(self.name)
|
||||
|
||||
#
|
||||
|
||||
# Defining instructions.
|
||||
#
|
||||
|
||||
|
||||
class InstructionGroup(object):
|
||||
"""
|
||||
@@ -178,7 +191,8 @@ class InstructionGroup(object):
|
||||
added to this group.
|
||||
"""
|
||||
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
|
||||
|
||||
def close(self):
|
||||
@@ -187,7 +201,8 @@ class InstructionGroup(object):
|
||||
opening another instruction group.
|
||||
"""
|
||||
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
|
||||
|
||||
def __init__(self, name, doc):
|
||||
@@ -198,9 +213,11 @@ class InstructionGroup(object):
|
||||
|
||||
@staticmethod
|
||||
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)
|
||||
|
||||
|
||||
class Operand(object):
|
||||
"""
|
||||
An instruction operand.
|
||||
@@ -212,12 +229,12 @@ class Operand(object):
|
||||
concrete type.
|
||||
|
||||
2. A :py:class:`TypeVar` instance indicates an SSA value operand, and the
|
||||
instruction is polymorphic over the possible concrete types that the type
|
||||
variable can assume.
|
||||
instruction is polymorphic over the possible concrete types that the
|
||||
type variable can assume.
|
||||
|
||||
3. An :py:class:`ImmediateType` instance indicates an immediate operand
|
||||
whose value is encoded in the instruction itself rather than being passed
|
||||
as an SSA value.
|
||||
whose value is encoded in the instruction itself rather than being
|
||||
passed as an SSA value.
|
||||
|
||||
"""
|
||||
def __init__(self, name, typ, doc=''):
|
||||
@@ -231,19 +248,20 @@ class Operand(object):
|
||||
else:
|
||||
return self.typ.__doc__
|
||||
|
||||
|
||||
class Instruction(object):
|
||||
"""
|
||||
An instruction.
|
||||
|
||||
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
|
||||
allowed to specify a singleton as just the operand itself, i.e., `ins=x` and
|
||||
`ins=(x,)` are both allowed and mean the same thing.
|
||||
allowed to specify a singleton as just the operand itself, i.e., `ins=x`
|
||||
and `ins=(x,)` are both allowed and mean the same thing.
|
||||
|
||||
:param name: Instruction mnemonic, also becomes opcode name.
|
||||
:param doc: Documentation string.
|
||||
:param ins: Tuple of input operands. This can be a mix of SSA value operands
|
||||
and immediate operands.
|
||||
:param ins: Tuple of input operands. This can be a mix of SSA value
|
||||
operands and immediate operands.
|
||||
:param outs: Tuple of output operands. The output operands can't be
|
||||
immediates.
|
||||
"""
|
||||
@@ -258,8 +276,8 @@ class Instruction(object):
|
||||
|
||||
@staticmethod
|
||||
def _to_operand_tuple(x):
|
||||
# Allow a single Operand instance instead of the awkward singleton tuple
|
||||
# syntax.
|
||||
# Allow a single Operand instance instead of the awkward singleton
|
||||
# tuple syntax.
|
||||
if isinstance(x, Operand):
|
||||
x = (x,)
|
||||
else:
|
||||
@@ -268,9 +286,10 @@ class Instruction(object):
|
||||
assert isinstance(op, Operand)
|
||||
return x
|
||||
|
||||
#
|
||||
|
||||
# Defining targets
|
||||
#
|
||||
|
||||
|
||||
class Target(object):
|
||||
"""
|
||||
A target instruction set architecture.
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
"""
|
||||
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 types import i8, f32, f64
|
||||
@@ -19,17 +20,19 @@ TxN = TypeVar('%Tx%N', 'A SIMD vector type')
|
||||
|
||||
N = Operand('N', imm64)
|
||||
a = Operand('a', Int, doc='A constant integer scalar or vector value')
|
||||
iconst = Instruction('iconst', r"""
|
||||
iconst = Instruction(
|
||||
'iconst', r"""
|
||||
Integer constant.
|
||||
|
||||
Create a scalar integer SSA value with an immediate constant value, or an
|
||||
integer vector where all the lanes have the same value.
|
||||
Create a scalar integer SSA value with an immediate constant value, or
|
||||
an integer vector where all the lanes have the same value.
|
||||
""",
|
||||
ins=N, outs=a)
|
||||
|
||||
N = Operand('N', ieee32)
|
||||
a = Operand('a', f32, doc='A constant integer scalar or vector value')
|
||||
f32const = Instruction('f32const', r"""
|
||||
f32const = Instruction(
|
||||
'f32const', r"""
|
||||
Floating point constant.
|
||||
|
||||
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)
|
||||
a = Operand('a', f64, doc='A constant integer scalar or vector value')
|
||||
f64const = Instruction('f64const', r"""
|
||||
f64const = Instruction(
|
||||
'f64const', r"""
|
||||
Floating point constant.
|
||||
|
||||
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)
|
||||
a = Operand('a', TxN, doc='A constant vector value')
|
||||
vconst = Instruction('vconst', r"""
|
||||
vconst = Instruction(
|
||||
'vconst', r"""
|
||||
Vector constant (floating point or integer).
|
||||
|
||||
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)
|
||||
y = Operand('y', Int)
|
||||
|
||||
iadd = Instruction('iadd', r"""
|
||||
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.
|
||||
This instruction does not depend on the signed/unsigned interpretation
|
||||
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}`.
|
||||
|
||||
This instruction does not depend on the signed/unsigned interpretation of
|
||||
the operands.
|
||||
This instruction does not depend on the signed/unsigned interpretation
|
||||
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}`.
|
||||
|
||||
This instruction does not depend on the signed/unsigned interpretation of
|
||||
the
|
||||
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)
|
||||
ins=(x, y), outs=a)
|
||||
|
||||
udiv = Instruction('udiv', r"""
|
||||
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)
|
||||
ins=(x, y), outs=a)
|
||||
|
||||
sdiv = Instruction('sdiv', r"""
|
||||
Signed integer division rounded toward zero: :math:`a := sign(xy) \lfloor
|
||||
{|x| \over |y|}\rfloor`.
|
||||
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`.
|
||||
representable in :math:`B` bits two's complement. This only happens
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
This operation traps if the divisor is zero.
|
||||
@@ -126,13 +138,14 @@ srem = Instruction('srem', """
|
||||
Should we add a ``smod`` instruction for the case where the result has
|
||||
the same sign as the divisor?
|
||||
""",
|
||||
ins=(x,y), outs=a)
|
||||
ins=(x, y), outs=a)
|
||||
|
||||
a = Operand('a', iB)
|
||||
x = Operand('x', iB)
|
||||
Y = Operand('Y', imm64)
|
||||
|
||||
iadd_imm = Instruction('iadd_imm', """
|
||||
iadd_imm = Instruction(
|
||||
'iadd_imm', """
|
||||
Add immediate integer.
|
||||
|
||||
Same as :inst:`iadd`, but one operand is an immediate constant.
|
||||
@@ -140,57 +153,64 @@ iadd_imm = Instruction('iadd_imm', """
|
||||
Polymorphic over all scalar integer types, but does not support vector
|
||||
types.
|
||||
""",
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
This instruction never traps because a divisor of -1 or 0 is not allowed.
|
||||
""",
|
||||
ins=(x,Y), outs=a)
|
||||
This instruction never traps because a divisor of -1 or 0 is not
|
||||
allowed. """,
|
||||
ins=(x, Y), outs=a)
|
||||
|
||||
urem_imm = Instruction('urem_imm', """
|
||||
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)
|
||||
ins=(x, Y), outs=a)
|
||||
|
||||
srem_imm = Instruction('srem_imm', """
|
||||
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)
|
||||
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', """
|
||||
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.
|
||||
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)
|
||||
ins=(X, y), outs=a)
|
||||
|
||||
#
|
||||
# Bitwise operations.
|
||||
@@ -202,22 +222,26 @@ x = Operand('x', bits)
|
||||
y = Operand('y', bits)
|
||||
a = Operand('a', bits)
|
||||
|
||||
band = Instruction('band', """
|
||||
band = Instruction(
|
||||
'band', """
|
||||
Bitwise and.
|
||||
""",
|
||||
ins=(x,y), outs=a)
|
||||
ins=(x, y), outs=a)
|
||||
|
||||
bor = Instruction('bor', """
|
||||
bor = Instruction(
|
||||
'bor', """
|
||||
Bitwise or.
|
||||
""",
|
||||
ins=(x,y), outs=a)
|
||||
ins=(x, y), outs=a)
|
||||
|
||||
bxor = Instruction('bxor', """
|
||||
bxor = Instruction(
|
||||
'bxor', """
|
||||
Bitwise xor.
|
||||
""",
|
||||
ins=(x,y), outs=a)
|
||||
ins=(x, y), outs=a)
|
||||
|
||||
bnot = Instruction('bnot', """
|
||||
bnot = Instruction(
|
||||
'bnot', """
|
||||
Bitwise not.
|
||||
""",
|
||||
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')
|
||||
a = Operand('a', Int)
|
||||
|
||||
rotl = Instruction('rotl', r"""
|
||||
rotl = Instruction(
|
||||
'rotl', r"""
|
||||
Rotate left.
|
||||
|
||||
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 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``
|
||||
places. Shift in zero bits to the LSB.
|
||||
|
||||
@@ -255,11 +282,13 @@ ishl = Instruction('ishl', r"""
|
||||
|
||||
.. todo:: Add ``ishl_imm`` variant with an immediate ``y``.
|
||||
""",
|
||||
ins=(x,y), outs=a)
|
||||
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*.
|
||||
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.
|
||||
|
||||
@@ -271,17 +300,19 @@ ushr = Instruction('ushr', r"""
|
||||
|
||||
.. todo:: Add ``ushr_imm`` variant with an immediate ``y``.
|
||||
""",
|
||||
ins=(x,y), outs=a)
|
||||
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*.
|
||||
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)
|
||||
ins=(x, y), outs=a)
|
||||
|
||||
#
|
||||
# Bit counting.
|
||||
@@ -290,34 +321,38 @@ sshr = Instruction('sshr', r"""
|
||||
x = Operand('x', iB)
|
||||
a = Operand('a', i8)
|
||||
|
||||
clz = Instruction('clz', r"""
|
||||
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.
|
||||
reaching the first one bit. When ``x`` is zero, returns the size of x
|
||||
in bits.
|
||||
""",
|
||||
ins=x, outs=a)
|
||||
|
||||
cls = Instruction('cls', r"""
|
||||
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.
|
||||
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"""
|
||||
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.
|
||||
reaching the first one bit. When ``x`` is zero, returns the size of x
|
||||
in bits.
|
||||
""",
|
||||
ins=x, outs=a)
|
||||
|
||||
popcnt = Instruction('popcnt', r"""
|
||||
popcnt = Instruction(
|
||||
'popcnt', r"""
|
||||
Population count
|
||||
|
||||
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
|
||||
|
||||
#: Boolean.
|
||||
b1 = ScalarType('b1', 0,
|
||||
b1 = ScalarType(
|
||||
'b1', 0,
|
||||
"""
|
||||
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.
|
||||
|
||||
#: IEEE single precision.
|
||||
f32 = FloatType(32,
|
||||
"""
|
||||
A 32-bit floating point type represented in the IEEE 754-2008 *binary32*
|
||||
interchange format. This corresponds to the :c:type:`float` type in most
|
||||
C implementations.
|
||||
f32 = FloatType(
|
||||
32, """
|
||||
A 32-bit floating point type represented in the IEEE 754-2008
|
||||
*binary32* interchange format. This corresponds to the :c:type:`float`
|
||||
type in most C implementations.
|
||||
""")
|
||||
|
||||
#: IEEE double precision.
|
||||
f64 = FloatType(64,
|
||||
"""
|
||||
A 64-bit floating point type represented in the IEEE 754-2008 *binary64*
|
||||
interchange format. This corresponds to the :c:type:`double` type in
|
||||
most C implementations.
|
||||
f64 = FloatType(
|
||||
64, """
|
||||
A 64-bit floating point type represented in the IEEE 754-2008
|
||||
*binary64* interchange format. This corresponds to the :c:type:`double`
|
||||
type in most C implementations.
|
||||
""")
|
||||
|
||||
@@ -5,6 +5,7 @@ Generate sources with instruction info.
|
||||
import srcgen
|
||||
import constant_hash
|
||||
|
||||
|
||||
def collect_instr_groups(targets):
|
||||
seen = set()
|
||||
groups = []
|
||||
@@ -15,6 +16,7 @@ def collect_instr_groups(targets):
|
||||
seen.add(g)
|
||||
return groups
|
||||
|
||||
|
||||
def gen_opcodes(groups, out_dir):
|
||||
"""Generate opcode enumerations."""
|
||||
fmt = srcgen.Formatter()
|
||||
@@ -46,9 +48,12 @@ def gen_opcodes(groups, out_dir):
|
||||
fmt.format('Opcode::{} => "{}",', i.camel_name, i.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))
|
||||
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:
|
||||
if i is None:
|
||||
fmt.line('Opcode::NotAnOpcode,')
|
||||
@@ -57,6 +62,7 @@ def gen_opcodes(groups, out_dir):
|
||||
|
||||
fmt.update_file('opcodes.rs', out_dir)
|
||||
|
||||
|
||||
def generate(targets, out_dir):
|
||||
groups = collect_instr_groups(targets)
|
||||
gen_opcodes(groups, out_dir)
|
||||
|
||||
@@ -9,6 +9,7 @@ source code.
|
||||
import sys
|
||||
import os
|
||||
|
||||
|
||||
class Formatter(object):
|
||||
"""
|
||||
Source code formatter class.
|
||||
@@ -70,7 +71,7 @@ class Formatter(object):
|
||||
self.after = after
|
||||
|
||||
def __enter__(self):
|
||||
self.fmt.indent_push();
|
||||
self.fmt.indent_push()
|
||||
|
||||
def __exit__(self, t, v, tb):
|
||||
self.fmt.indent_pop()
|
||||
|
||||
@@ -8,6 +8,7 @@ set architecture supported by Cretonne.
|
||||
|
||||
from . import riscv
|
||||
|
||||
|
||||
def all_targets():
|
||||
"""
|
||||
Get a list of all the supported targets. Each target is represented as a
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
RISC-V Target
|
||||
-------------
|
||||
|
||||
`RISC-V <http://riscv.org/>`_ is an open instruction set architecture originally
|
||||
developed at UC Berkeley. It is a RISC-style ISA with either a 32-bit (RV32I) or
|
||||
64-bit (RV32I) base instruction set and a number of optional extensions:
|
||||
`RISC-V <http://riscv.org/>`_ is an open instruction set architecture
|
||||
originally developed at UC Berkeley. It is a RISC-style ISA with either a
|
||||
32-bit (RV32I) or 64-bit (RV32I) base instruction set and a number of optional
|
||||
extensions:
|
||||
|
||||
RV32M / RV64M
|
||||
Integer multiplication and division.
|
||||
|
||||
Reference in New Issue
Block a user