Add two new value types: iflags and fflags.
These two value types represent the state of CPU flags after an integer comparison and a floating point comparison respectively. Instructions using these types TBD.
This commit is contained in:
@@ -166,7 +166,7 @@ Concrete value types are represented as instances of :class:`ValueType`. There
|
|||||||
are subclasses to represent scalar and vector types.
|
are subclasses to represent scalar and vector types.
|
||||||
|
|
||||||
.. autoclass:: ValueType
|
.. autoclass:: ValueType
|
||||||
.. inheritance-diagram:: ValueType LaneType VectorType SpecialType IntType FloatType BoolType
|
.. inheritance-diagram:: ValueType LaneType VectorType IntType FloatType BoolType SpecialType FlagsType
|
||||||
:parts: 1
|
:parts: 1
|
||||||
.. autoclass:: LaneType
|
.. autoclass:: LaneType
|
||||||
:members:
|
:members:
|
||||||
@@ -175,6 +175,7 @@ are subclasses to represent scalar and vector types.
|
|||||||
.. autoclass:: IntType
|
.. autoclass:: IntType
|
||||||
.. autoclass:: FloatType
|
.. autoclass:: FloatType
|
||||||
.. autoclass:: BoolType
|
.. autoclass:: BoolType
|
||||||
|
.. autoclass:: FlagsType
|
||||||
|
|
||||||
.. automodule:: base.types
|
.. automodule:: base.types
|
||||||
:members:
|
:members:
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
The base.types module predefines all the Cretonne scalar types.
|
The base.types module predefines all the Cretonne scalar types.
|
||||||
"""
|
"""
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from cdsl.types import IntType, FloatType, BoolType
|
from cdsl.types import IntType, FloatType, BoolType, FlagsType
|
||||||
|
|
||||||
#: Boolean.
|
#: Boolean.
|
||||||
b1 = BoolType(1) #: 1-bit bool. Type is abstract (can't be stored in mem)
|
b1 = BoolType(1) #: 1-bit bool. Type is abstract (can't be stored in mem)
|
||||||
@@ -31,3 +31,16 @@ f64 = FloatType(
|
|||||||
*binary64* interchange format. This corresponds to the :c:type:`double`
|
*binary64* interchange format. This corresponds to the :c:type:`double`
|
||||||
type in most C implementations.
|
type in most C implementations.
|
||||||
""")
|
""")
|
||||||
|
#: CPU flags from an integer comparison.
|
||||||
|
iflags = FlagsType(
|
||||||
|
'iflags', """
|
||||||
|
CPU flags representing the result of an integer comparison. These flags
|
||||||
|
can be tested with an `intcc` condition code.
|
||||||
|
""")
|
||||||
|
|
||||||
|
#: CPU flags from a floating point comparison.
|
||||||
|
fflags = FlagsType(
|
||||||
|
'fflags', """
|
||||||
|
CPU flags representing the result of a floating point comparison. These
|
||||||
|
flags can be tested with a `floatcc` condition code.
|
||||||
|
""")
|
||||||
|
|||||||
@@ -287,6 +287,22 @@ class BoolType(LaneType):
|
|||||||
return self.bits
|
return self.bits
|
||||||
|
|
||||||
|
|
||||||
|
class FlagsType(SpecialType):
|
||||||
|
"""
|
||||||
|
A type representing CPU flags.
|
||||||
|
|
||||||
|
Flags can't be stored in memory.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, name, doc):
|
||||||
|
# type: (str, str) -> None
|
||||||
|
super(FlagsType, self).__init__(name, 0, doc)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
# type: () -> str
|
||||||
|
return 'FlagsType({})'.format(self.name)
|
||||||
|
|
||||||
|
|
||||||
class BVType(ValueType):
|
class BVType(ValueType):
|
||||||
"""A flat bitvector type. Used for semantics description only."""
|
"""A flat bitvector type. Used for semantics description only."""
|
||||||
|
|
||||||
|
|||||||
@@ -163,6 +163,9 @@ class TypeSet(object):
|
|||||||
>>> TypeSet(lanes=True, ints=True)
|
>>> TypeSet(lanes=True, ints=True)
|
||||||
TypeSet(lanes={1, 2, 4, 8, 16, 32, 64, 128, 256}, ints={8, 16, 32, 64})
|
TypeSet(lanes={1, 2, 4, 8, 16, 32, 64, 128, 256}, ints={8, 16, 32, 64})
|
||||||
|
|
||||||
|
Finally, a type set can contain special types (derived from `SpecialType`)
|
||||||
|
which can't appear as lane types.
|
||||||
|
|
||||||
:param lanes: `(min, max)` inclusive range of permitted vector lane counts.
|
:param lanes: `(min, max)` inclusive range of permitted vector lane counts.
|
||||||
:param ints: `(min, max)` inclusive range of permitted scalar integer
|
:param ints: `(min, max)` inclusive range of permitted scalar integer
|
||||||
widths.
|
widths.
|
||||||
@@ -172,11 +175,19 @@ class TypeSet(object):
|
|||||||
widths.
|
widths.
|
||||||
:param bitvecs : `(min, max)` inclusive range of permitted bitvector
|
:param bitvecs : `(min, max)` inclusive range of permitted bitvector
|
||||||
widths.
|
widths.
|
||||||
|
:param specials: Sequence of speical types to appear in the set.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, lanes=None, ints=None, floats=None, bools=None,
|
def __init__(
|
||||||
bitvecs=None):
|
self,
|
||||||
# type: (BoolInterval, BoolInterval, BoolInterval, BoolInterval, BoolInterval) -> None # noqa
|
lanes=None, # type: BoolInterval
|
||||||
|
ints=None, # type: BoolInterval
|
||||||
|
floats=None, # type: BoolInterval
|
||||||
|
bools=None, # type: BoolInterval
|
||||||
|
bitvecs=None, # type: BoolInterval
|
||||||
|
specials=None # type: Iterable[types.SpecialType]
|
||||||
|
):
|
||||||
|
# type: (...) -> None
|
||||||
self.lanes = interval_to_set(decode_interval(lanes, (1, MAX_LANES), 1))
|
self.lanes = interval_to_set(decode_interval(lanes, (1, MAX_LANES), 1))
|
||||||
self.ints = interval_to_set(decode_interval(ints, (8, MAX_BITS)))
|
self.ints = interval_to_set(decode_interval(ints, (8, MAX_BITS)))
|
||||||
self.floats = interval_to_set(decode_interval(floats, (32, 64)))
|
self.floats = interval_to_set(decode_interval(floats, (32, 64)))
|
||||||
@@ -184,6 +195,7 @@ class TypeSet(object):
|
|||||||
self.bools = set(filter(legal_bool, self.bools))
|
self.bools = set(filter(legal_bool, self.bools))
|
||||||
self.bitvecs = interval_to_set(decode_interval(bitvecs,
|
self.bitvecs = interval_to_set(decode_interval(bitvecs,
|
||||||
(1, MAX_BITVEC)))
|
(1, MAX_BITVEC)))
|
||||||
|
self.specials = set(specials) if specials else set()
|
||||||
|
|
||||||
def copy(self):
|
def copy(self):
|
||||||
# type: (TypeSet) -> TypeSet
|
# type: (TypeSet) -> TypeSet
|
||||||
@@ -194,13 +206,14 @@ class TypeSet(object):
|
|||||||
return deepcopy(self)
|
return deepcopy(self)
|
||||||
|
|
||||||
def typeset_key(self):
|
def typeset_key(self):
|
||||||
# type: () -> Tuple[Tuple, Tuple, Tuple, Tuple, Tuple]
|
# type: () -> Tuple[Tuple, Tuple, Tuple, Tuple, Tuple, Tuple]
|
||||||
"""Key tuple used for hashing and equality."""
|
"""Key tuple used for hashing and equality."""
|
||||||
return (tuple(sorted(list(self.lanes))),
|
return (tuple(sorted(list(self.lanes))),
|
||||||
tuple(sorted(list(self.ints))),
|
tuple(sorted(list(self.ints))),
|
||||||
tuple(sorted(list(self.floats))),
|
tuple(sorted(list(self.floats))),
|
||||||
tuple(sorted(list(self.bools))),
|
tuple(sorted(list(self.bools))),
|
||||||
tuple(sorted(list(self.bitvecs))))
|
tuple(sorted(list(self.bitvecs))),
|
||||||
|
tuple(sorted(list(self.specials))))
|
||||||
|
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
# type: () -> int
|
# type: () -> int
|
||||||
@@ -231,6 +244,8 @@ class TypeSet(object):
|
|||||||
s += ', bools={}'.format(pp_set(self.bools))
|
s += ', bools={}'.format(pp_set(self.bools))
|
||||||
if len(self.bitvecs) > 0:
|
if len(self.bitvecs) > 0:
|
||||||
s += ', bitvecs={}'.format(pp_set(self.bitvecs))
|
s += ', bitvecs={}'.format(pp_set(self.bitvecs))
|
||||||
|
if len(self.specials) > 0:
|
||||||
|
s += ', specials=[{}]'.format(pp_set(self.specials))
|
||||||
return s + ')'
|
return s + ')'
|
||||||
|
|
||||||
def emit_fields(self, fmt):
|
def emit_fields(self, fmt):
|
||||||
@@ -273,6 +288,7 @@ class TypeSet(object):
|
|||||||
self.floats.intersection_update(other.floats)
|
self.floats.intersection_update(other.floats)
|
||||||
self.bools.intersection_update(other.bools)
|
self.bools.intersection_update(other.bools)
|
||||||
self.bitvecs.intersection_update(other.bitvecs)
|
self.bitvecs.intersection_update(other.bitvecs)
|
||||||
|
self.specials.intersection_update(other.specials)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
@@ -481,8 +497,9 @@ class TypeSet(object):
|
|||||||
"""
|
"""
|
||||||
Return the number of concrete types represented by this typeset
|
Return the number of concrete types represented by this typeset
|
||||||
"""
|
"""
|
||||||
return len(self.lanes) * (len(self.ints) + len(self.floats) +
|
return (len(self.lanes) * (len(self.ints) + len(self.floats) +
|
||||||
len(self.bools) + len(self.bitvecs))
|
len(self.bools) + len(self.bitvecs)) +
|
||||||
|
len(self.specials))
|
||||||
|
|
||||||
def concrete_types(self):
|
def concrete_types(self):
|
||||||
# type: () -> Iterable[types.ValueType]
|
# type: () -> Iterable[types.ValueType]
|
||||||
@@ -504,6 +521,9 @@ class TypeSet(object):
|
|||||||
assert nlanes == 1
|
assert nlanes == 1
|
||||||
yield types.BVType.with_bits(bits)
|
yield types.BVType.with_bits(bits)
|
||||||
|
|
||||||
|
for spec in self.specials:
|
||||||
|
yield spec
|
||||||
|
|
||||||
def get_singleton(self):
|
def get_singleton(self):
|
||||||
# type: () -> types.ValueType
|
# type: () -> types.ValueType
|
||||||
"""
|
"""
|
||||||
@@ -545,11 +565,20 @@ class TypeVar(object):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self, name, doc,
|
self,
|
||||||
ints=False, floats=False, bools=False,
|
name, # type: str
|
||||||
scalars=True, simd=False, bitvecs=False,
|
doc, # type: str
|
||||||
base=None, derived_func=None):
|
ints=False, # type: BoolInterval
|
||||||
# type: (str, str, BoolInterval, BoolInterval, BoolInterval, bool, BoolInterval, BoolInterval, TypeVar, str) -> None # noqa
|
floats=False, # type: BoolInterval
|
||||||
|
bools=False, # type: BoolInterval
|
||||||
|
scalars=True, # type: bool
|
||||||
|
simd=False, # type: BoolInterval
|
||||||
|
bitvecs=False, # type: BoolInterval
|
||||||
|
base=None, # type: TypeVar
|
||||||
|
derived_func=None, # type: str
|
||||||
|
specials=None # type: Iterable[types.SpecialType]
|
||||||
|
):
|
||||||
|
# type: (...) -> None
|
||||||
self.name = name
|
self.name = name
|
||||||
self.__doc__ = doc
|
self.__doc__ = doc
|
||||||
self.is_derived = isinstance(base, TypeVar)
|
self.is_derived = isinstance(base, TypeVar)
|
||||||
@@ -567,7 +596,8 @@ class TypeVar(object):
|
|||||||
ints=ints,
|
ints=ints,
|
||||||
floats=floats,
|
floats=floats,
|
||||||
bools=bools,
|
bools=bools,
|
||||||
bitvecs=bitvecs)
|
bitvecs=bitvecs,
|
||||||
|
specials=specials)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def singleton(typ):
|
def singleton(typ):
|
||||||
@@ -580,6 +610,8 @@ class TypeVar(object):
|
|||||||
elif isinstance(typ, types.LaneType):
|
elif isinstance(typ, types.LaneType):
|
||||||
scalar = typ
|
scalar = typ
|
||||||
lanes = (1, 1)
|
lanes = (1, 1)
|
||||||
|
elif isinstance(typ, types.SpecialType):
|
||||||
|
return TypeVar(typ.name, typ.__doc__, specials=[typ])
|
||||||
else:
|
else:
|
||||||
assert isinstance(typ, types.BVType)
|
assert isinstance(typ, types.BVType)
|
||||||
scalar = typ
|
scalar = typ
|
||||||
@@ -681,6 +713,8 @@ class TypeVar(object):
|
|||||||
# Safety checks to avoid over/underflows.
|
# Safety checks to avoid over/underflows.
|
||||||
ts = base.get_typeset()
|
ts = base.get_typeset()
|
||||||
|
|
||||||
|
assert len(ts.specials) == 0, "Can't derive from special types"
|
||||||
|
|
||||||
if derived_func == TypeVar.HALFWIDTH:
|
if derived_func == TypeVar.HALFWIDTH:
|
||||||
if len(ts.ints) > 0:
|
if len(ts.ints) > 0:
|
||||||
assert min(ts.ints) > 8, "Can't halve all integer types"
|
assert min(ts.ints) > 8, "Can't halve all integer types"
|
||||||
|
|||||||
@@ -45,6 +45,8 @@ def emit_vectors(bits, fmt):
|
|||||||
|
|
||||||
def emit_types(fmt):
|
def emit_types(fmt):
|
||||||
# type: (srcgen.Formatter) -> None
|
# type: (srcgen.Formatter) -> None
|
||||||
|
for spec in ValueType.all_special_types:
|
||||||
|
emit_type(spec, fmt)
|
||||||
for ty in ValueType.all_lane_types:
|
for ty in ValueType.all_lane_types:
|
||||||
emit_type(ty, fmt)
|
emit_type(ty, fmt)
|
||||||
# Emit vector definitions for common SIMD sizes.
|
# Emit vector definitions for common SIMD sizes.
|
||||||
|
|||||||
@@ -272,9 +272,7 @@ impl Type {
|
|||||||
|
|
||||||
impl Display for Type {
|
impl Display for Type {
|
||||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
if self.is_void() {
|
if self.is_bool() {
|
||||||
write!(f, "void")
|
|
||||||
} else if self.is_bool() {
|
|
||||||
write!(f, "b{}", self.lane_bits())
|
write!(f, "b{}", self.lane_bits())
|
||||||
} else if self.is_int() {
|
} else if self.is_int() {
|
||||||
write!(f, "i{}", self.lane_bits())
|
write!(f, "i{}", self.lane_bits())
|
||||||
@@ -283,16 +281,19 @@ impl Display for Type {
|
|||||||
} else if self.is_vector() {
|
} else if self.is_vector() {
|
||||||
write!(f, "{}x{}", self.lane_type(), self.lane_count())
|
write!(f, "{}x{}", self.lane_type(), self.lane_count())
|
||||||
} else {
|
} else {
|
||||||
panic!("Invalid Type(0x{:x})", self.0)
|
f.write_str(match *self {
|
||||||
|
VOID => "void",
|
||||||
|
IFLAGS => "iflags",
|
||||||
|
FFLAGS => "fflags",
|
||||||
|
_ => panic!("Invalid Type(0x{:x})", self.0),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for Type {
|
impl Debug for Type {
|
||||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
if self.is_void() {
|
if self.is_bool() {
|
||||||
write!(f, "types::VOID")
|
|
||||||
} else if self.is_bool() {
|
|
||||||
write!(f, "types::B{}", self.lane_bits())
|
write!(f, "types::B{}", self.lane_bits())
|
||||||
} else if self.is_int() {
|
} else if self.is_int() {
|
||||||
write!(f, "types::I{}", self.lane_bits())
|
write!(f, "types::I{}", self.lane_bits())
|
||||||
@@ -301,7 +302,12 @@ impl Debug for Type {
|
|||||||
} else if self.is_vector() {
|
} else if self.is_vector() {
|
||||||
write!(f, "{:?}X{}", self.lane_type(), self.lane_count())
|
write!(f, "{:?}X{}", self.lane_type(), self.lane_count())
|
||||||
} else {
|
} else {
|
||||||
write!(f, "Type(0x{:x})", self.0)
|
match *self {
|
||||||
|
VOID => write!(f, "types::VOID"),
|
||||||
|
IFLAGS => write!(f, "types::IFLAGS"),
|
||||||
|
FFLAGS => write!(f, "types::FFLAGS"),
|
||||||
|
_ => write!(f, "Type(0x{:x})", self.0),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -320,6 +326,10 @@ mod tests {
|
|||||||
fn basic_scalars() {
|
fn basic_scalars() {
|
||||||
assert_eq!(VOID, VOID.lane_type());
|
assert_eq!(VOID, VOID.lane_type());
|
||||||
assert_eq!(0, VOID.bits());
|
assert_eq!(0, VOID.bits());
|
||||||
|
assert_eq!(IFLAGS, IFLAGS.lane_type());
|
||||||
|
assert_eq!(0, IFLAGS.bits());
|
||||||
|
assert_eq!(FFLAGS, FFLAGS.lane_type());
|
||||||
|
assert_eq!(0, FFLAGS.bits());
|
||||||
assert_eq!(B1, B1.lane_type());
|
assert_eq!(B1, B1.lane_type());
|
||||||
assert_eq!(B8, B8.lane_type());
|
assert_eq!(B8, B8.lane_type());
|
||||||
assert_eq!(B16, B16.lane_type());
|
assert_eq!(B16, B16.lane_type());
|
||||||
@@ -333,6 +343,8 @@ mod tests {
|
|||||||
assert_eq!(F64, F64.lane_type());
|
assert_eq!(F64, F64.lane_type());
|
||||||
|
|
||||||
assert_eq!(VOID.lane_bits(), 0);
|
assert_eq!(VOID.lane_bits(), 0);
|
||||||
|
assert_eq!(IFLAGS.lane_bits(), 0);
|
||||||
|
assert_eq!(FFLAGS.lane_bits(), 0);
|
||||||
assert_eq!(B1.lane_bits(), 1);
|
assert_eq!(B1.lane_bits(), 1);
|
||||||
assert_eq!(B8.lane_bits(), 8);
|
assert_eq!(B8.lane_bits(), 8);
|
||||||
assert_eq!(B16.lane_bits(), 16);
|
assert_eq!(B16.lane_bits(), 16);
|
||||||
@@ -349,6 +361,8 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn typevar_functions() {
|
fn typevar_functions() {
|
||||||
assert_eq!(VOID.half_width(), None);
|
assert_eq!(VOID.half_width(), None);
|
||||||
|
assert_eq!(IFLAGS.half_width(), None);
|
||||||
|
assert_eq!(FFLAGS.half_width(), None);
|
||||||
assert_eq!(B1.half_width(), None);
|
assert_eq!(B1.half_width(), None);
|
||||||
assert_eq!(B8.half_width(), None);
|
assert_eq!(B8.half_width(), None);
|
||||||
assert_eq!(B16.half_width(), Some(B8));
|
assert_eq!(B16.half_width(), Some(B8));
|
||||||
@@ -363,6 +377,8 @@ mod tests {
|
|||||||
assert_eq!(F64.half_width(), Some(F32));
|
assert_eq!(F64.half_width(), Some(F32));
|
||||||
|
|
||||||
assert_eq!(VOID.double_width(), None);
|
assert_eq!(VOID.double_width(), None);
|
||||||
|
assert_eq!(IFLAGS.double_width(), None);
|
||||||
|
assert_eq!(FFLAGS.double_width(), None);
|
||||||
assert_eq!(B1.double_width(), None);
|
assert_eq!(B1.double_width(), None);
|
||||||
assert_eq!(B8.double_width(), Some(B16));
|
assert_eq!(B8.double_width(), Some(B16));
|
||||||
assert_eq!(B16.double_width(), Some(B32));
|
assert_eq!(B16.double_width(), Some(B32));
|
||||||
@@ -397,6 +413,8 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn format_scalars() {
|
fn format_scalars() {
|
||||||
assert_eq!(VOID.to_string(), "void");
|
assert_eq!(VOID.to_string(), "void");
|
||||||
|
assert_eq!(IFLAGS.to_string(), "iflags");
|
||||||
|
assert_eq!(FFLAGS.to_string(), "fflags");
|
||||||
assert_eq!(B1.to_string(), "b1");
|
assert_eq!(B1.to_string(), "b1");
|
||||||
assert_eq!(B8.to_string(), "b8");
|
assert_eq!(B8.to_string(), "b8");
|
||||||
assert_eq!(B16.to_string(), "b16");
|
assert_eq!(B16.to_string(), "b16");
|
||||||
|
|||||||
@@ -303,7 +303,11 @@ impl<'a> Lexer<'a> {
|
|||||||
Self::value_type(text, prefix, number)
|
Self::value_type(text, prefix, number)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.unwrap_or(Token::Identifier(text)),
|
.unwrap_or_else(|| match text {
|
||||||
|
"iflags" => Token::Type(types::IFLAGS),
|
||||||
|
"fflags" => Token::Type(types::FFLAGS),
|
||||||
|
_ => Token::Identifier(text),
|
||||||
|
}),
|
||||||
loc,
|
loc,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -554,7 +558,8 @@ mod tests {
|
|||||||
fn lex_identifiers() {
|
fn lex_identifiers() {
|
||||||
let mut lex = Lexer::new(
|
let mut lex = Lexer::new(
|
||||||
"v0 v00 vx01 ebb1234567890 ebb5234567890 v1x vx1 vxvx4 \
|
"v0 v00 vx01 ebb1234567890 ebb5234567890 v1x vx1 vxvx4 \
|
||||||
function0 function b1 i32x4 f32x5",
|
function0 function b1 i32x4 f32x5 \
|
||||||
|
iflags fflags iflagss",
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
lex.next(),
|
lex.next(),
|
||||||
@@ -573,8 +578,11 @@ mod tests {
|
|||||||
assert_eq!(lex.next(), token(Token::Identifier("function0"), 1));
|
assert_eq!(lex.next(), token(Token::Identifier("function0"), 1));
|
||||||
assert_eq!(lex.next(), token(Token::Identifier("function"), 1));
|
assert_eq!(lex.next(), token(Token::Identifier("function"), 1));
|
||||||
assert_eq!(lex.next(), token(Token::Type(types::B1), 1));
|
assert_eq!(lex.next(), token(Token::Type(types::B1), 1));
|
||||||
assert_eq!(lex.next(), token(Token::Type(types::I32.by(4).unwrap()), 1));
|
assert_eq!(lex.next(), token(Token::Type(types::I32X4), 1));
|
||||||
assert_eq!(lex.next(), token(Token::Identifier("f32x5"), 1));
|
assert_eq!(lex.next(), token(Token::Identifier("f32x5"), 1));
|
||||||
|
assert_eq!(lex.next(), token(Token::Type(types::IFLAGS), 1));
|
||||||
|
assert_eq!(lex.next(), token(Token::Type(types::FFLAGS), 1));
|
||||||
|
assert_eq!(lex.next(), token(Token::Identifier("iflagss"), 1));
|
||||||
assert_eq!(lex.next(), None);
|
assert_eq!(lex.next(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ syn keyword ctonHeader test isa set
|
|||||||
syn keyword ctonDecl function jump_table incoming_arg outgoing_arg spill_slot local emergency_slot
|
syn keyword ctonDecl function jump_table incoming_arg outgoing_arg spill_slot local emergency_slot
|
||||||
syn keyword ctonFilecheck check sameln nextln unordered not regex contained
|
syn keyword ctonFilecheck check sameln nextln unordered not regex contained
|
||||||
|
|
||||||
syn match ctonType /\<[bif]\d\+\(x\d\+\)\?\>/
|
syn match ctonType /\<\([bif]\d\+\(x\d\+\)\?\)\|[if]flags\>/
|
||||||
syn match ctonEntity /\<\(v\|ss\|jt\|fn\|sig\)\d\+\>/
|
syn match ctonEntity /\<\(v\|ss\|jt\|fn\|sig\)\d\+\>/
|
||||||
syn match ctonLabel /\<ebb\d+\>/
|
syn match ctonLabel /\<ebb\d+\>/
|
||||||
syn match ctonName /%\w\+\>/
|
syn match ctonName /%\w\+\>/
|
||||||
|
|||||||
Reference in New Issue
Block a user