Remove the number field from the PredNode union type.
Predicate numbers are available in the maps isa.settings.predicate_number and isa.instp_number instead. Like the name field, predicate numbers don't interact well with unique_pred().
This commit is contained in:
@@ -103,23 +103,17 @@ class TargetISA(object):
|
|||||||
"""
|
"""
|
||||||
Collect and number all predicates in use.
|
Collect and number all predicates in use.
|
||||||
|
|
||||||
Sets `instp.number` for all used instruction predicates and places them
|
|
||||||
in `self.all_instps` in numerical order.
|
|
||||||
|
|
||||||
Ensures that all ISA predicates have an assigned bit number in
|
Ensures that all ISA predicates have an assigned bit number in
|
||||||
`self.settings`.
|
`self.settings`.
|
||||||
"""
|
"""
|
||||||
self.all_instps = list() # type: List[PredNode]
|
self.instp_number = OrderedDict() # type: OrderedDict[PredNode, int]
|
||||||
instps = set() # type: Set[PredNode]
|
|
||||||
for cpumode in self.cpumodes:
|
for cpumode in self.cpumodes:
|
||||||
for enc in cpumode.encodings:
|
for enc in cpumode.encodings:
|
||||||
instp = enc.instp
|
instp = enc.instp
|
||||||
if instp and instp not in instps:
|
if instp and instp not in self.instp_number:
|
||||||
# assign predicate number starting from 0.
|
# assign predicate number starting from 0.
|
||||||
assert instp.number is None
|
n = len(self.instp_number)
|
||||||
instp.number = len(instps)
|
self.instp_number[instp] = n
|
||||||
instps.add(instp)
|
|
||||||
self.all_instps.append(instp)
|
|
||||||
|
|
||||||
# All referenced ISA predicates must have a number in
|
# All referenced ISA predicates must have a number in
|
||||||
# `self.settings`. This may cause some parent predicates to be
|
# `self.settings`. This may cause some parent predicates to be
|
||||||
|
|||||||
@@ -80,7 +80,6 @@ class Predicate(object):
|
|||||||
|
|
||||||
def __init__(self, parts):
|
def __init__(self, parts):
|
||||||
# type: (Sequence[PredNode]) -> None
|
# type: (Sequence[PredNode]) -> None
|
||||||
self.number = None # type: int
|
|
||||||
self.parts = parts
|
self.parts = parts
|
||||||
self.context = reduce(
|
self.context = reduce(
|
||||||
_descendant,
|
_descendant,
|
||||||
@@ -210,7 +209,6 @@ class FieldPredicate(object):
|
|||||||
|
|
||||||
def __init__(self, field, function, args):
|
def __init__(self, field, function, args):
|
||||||
# type: (FormatField, str, Sequence[Any]) -> None
|
# type: (FormatField, str, Sequence[Any]) -> None
|
||||||
self.number = None # type: int
|
|
||||||
self.field = field
|
self.field = field
|
||||||
self.function = function
|
self.function = function
|
||||||
self.args = args
|
self.args = args
|
||||||
@@ -330,7 +328,6 @@ class TypePredicate(object):
|
|||||||
assert value_type is not None
|
assert value_type is not None
|
||||||
self.value_arg = value_arg
|
self.value_arg = value_arg
|
||||||
self.value_type = value_type
|
self.value_type = value_type
|
||||||
self.number = None # type: int
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
# type: () -> str
|
# type: () -> str
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ class Setting(object):
|
|||||||
def __init__(self, doc):
|
def __init__(self, doc):
|
||||||
# type: (str) -> None
|
# type: (str) -> None
|
||||||
self.name = None # type: str # Assigned later by `extract_names()`.
|
self.name = None # type: str # Assigned later by `extract_names()`.
|
||||||
self.number = None # type: int
|
|
||||||
self.__doc__ = doc
|
self.__doc__ = doc
|
||||||
# Offset of byte in settings vector containing this setting.
|
# Offset of byte in settings vector containing this setting.
|
||||||
self.byte_offset = None # type: int
|
self.byte_offset = None # type: int
|
||||||
|
|||||||
@@ -124,13 +124,13 @@ def emit_instp(instp, fmt, has_dfg=False):
|
|||||||
|
|
||||||
|
|
||||||
def emit_inst_predicates(instps, fmt):
|
def emit_inst_predicates(instps, fmt):
|
||||||
# type: (Sequence[PredNode], srcgen.Formatter) -> None
|
# type: (OrderedDict[PredNode, int], srcgen.Formatter) -> None
|
||||||
"""
|
"""
|
||||||
Emit private functions for matching instruction predicates as well as a
|
Emit private functions for matching instruction predicates as well as a
|
||||||
static `INST_PREDICATES` array indexed by predicate number.
|
static `INST_PREDICATES` array indexed by predicate number.
|
||||||
"""
|
"""
|
||||||
for instp in instps:
|
for instp, number in instps.items():
|
||||||
name = 'inst_predicate_{}'.format(instp.number)
|
name = 'inst_predicate_{}'.format(number)
|
||||||
with fmt.indented(
|
with fmt.indented(
|
||||||
'fn {}(dfg: &ir::DataFlowGraph, inst: &ir::InstructionData)'
|
'fn {}(dfg: &ir::DataFlowGraph, inst: &ir::InstructionData)'
|
||||||
'-> bool {{'.format(name), '}'):
|
'-> bool {{'.format(name), '}'):
|
||||||
@@ -140,12 +140,12 @@ def emit_inst_predicates(instps, fmt):
|
|||||||
with fmt.indented(
|
with fmt.indented(
|
||||||
'pub static INST_PREDICATES: [InstPredicate; {}] = ['
|
'pub static INST_PREDICATES: [InstPredicate; {}] = ['
|
||||||
.format(len(instps)), '];'):
|
.format(len(instps)), '];'):
|
||||||
for instp in instps:
|
for instp, number in instps.items():
|
||||||
fmt.format('inst_predicate_{},', instp.number)
|
fmt.format('inst_predicate_{},', number)
|
||||||
|
|
||||||
|
|
||||||
def emit_recipe_predicates(recipes, fmt):
|
def emit_recipe_predicates(isa, fmt):
|
||||||
# type: (Sequence[EncRecipe], srcgen.Formatter) -> None
|
# type: (TargetISA, srcgen.Formatter) -> None
|
||||||
"""
|
"""
|
||||||
Emit private functions for checking recipe predicates as well as a static
|
Emit private functions for checking recipe predicates as well as a static
|
||||||
`RECIPE_PREDICATES` array indexed by recipe number.
|
`RECIPE_PREDICATES` array indexed by recipe number.
|
||||||
@@ -158,7 +158,7 @@ def emit_recipe_predicates(recipes, fmt):
|
|||||||
pname = dict() # type: Dict[RecipePred, str]
|
pname = dict() # type: Dict[RecipePred, str]
|
||||||
|
|
||||||
# Generate unique recipe predicates.
|
# Generate unique recipe predicates.
|
||||||
for rcp in recipes:
|
for rcp in isa.all_recipes:
|
||||||
p = rcp.recipe_pred()
|
p = rcp.recipe_pred()
|
||||||
if p is None or p in pname:
|
if p is None or p in pname:
|
||||||
continue
|
continue
|
||||||
@@ -174,17 +174,16 @@ def emit_recipe_predicates(recipes, fmt):
|
|||||||
name,
|
name,
|
||||||
'isap' if isap else '_'), '}'):
|
'isap' if isap else '_'), '}'):
|
||||||
if isap:
|
if isap:
|
||||||
with fmt.indented(
|
n = isa.settings.predicate_number[isap]
|
||||||
'if isap.test({})'.format(isap.number),
|
with fmt.indented('if isap.test({})'.format(n), '}'):
|
||||||
'}'):
|
|
||||||
fmt.line('return false;')
|
fmt.line('return false;')
|
||||||
emit_instp(instp, fmt)
|
emit_instp(instp, fmt)
|
||||||
|
|
||||||
# Generate the static table.
|
# Generate the static table.
|
||||||
with fmt.indented(
|
with fmt.indented(
|
||||||
'pub static RECIPE_PREDICATES: [RecipePredicate; {}] = ['
|
'pub static RECIPE_PREDICATES: [RecipePredicate; {}] = ['
|
||||||
.format(len(recipes)), '];'):
|
.format(len(isa.all_recipes)), '];'):
|
||||||
for rcp in recipes:
|
for rcp in isa.all_recipes:
|
||||||
p = rcp.recipe_pred()
|
p = rcp.recipe_pred()
|
||||||
if p is None:
|
if p is None:
|
||||||
fmt.line('None,')
|
fmt.line('None,')
|
||||||
@@ -229,7 +228,7 @@ class Encoder:
|
|||||||
# type: (TargetISA) -> None
|
# type: (TargetISA) -> None
|
||||||
self.isa = isa
|
self.isa = isa
|
||||||
self.NR = len(isa.all_recipes)
|
self.NR = len(isa.all_recipes)
|
||||||
self.NI = len(isa.all_instps)
|
self.NI = len(isa.instp_number)
|
||||||
# u16 encoding list words.
|
# u16 encoding list words.
|
||||||
self.words = list() # type: List[int]
|
self.words = list() # type: List[int]
|
||||||
# Documentation comments: Index into `words` + comment.
|
# Documentation comments: Index into `words` + comment.
|
||||||
@@ -287,7 +286,8 @@ class Encoder:
|
|||||||
def instp(self, pred, skip):
|
def instp(self, pred, skip):
|
||||||
# type: (PredNode, int) -> None
|
# type: (PredNode, int) -> None
|
||||||
"""Add an instruction predicate entry."""
|
"""Add an instruction predicate entry."""
|
||||||
self._pred(pred, skip, pred.number)
|
number = self.isa.instp_number[pred]
|
||||||
|
self._pred(pred, skip, number)
|
||||||
|
|
||||||
def isap(self, pred, skip):
|
def isap(self, pred, skip):
|
||||||
# type: (PredNode, int) -> None
|
# type: (PredNode, int) -> None
|
||||||
@@ -836,10 +836,10 @@ def gen_isa(isa, fmt):
|
|||||||
# type: (TargetISA, srcgen.Formatter) -> None
|
# type: (TargetISA, srcgen.Formatter) -> None
|
||||||
|
|
||||||
# Make the `RECIPE_PREDICATES` table.
|
# Make the `RECIPE_PREDICATES` table.
|
||||||
emit_recipe_predicates(isa.all_recipes, fmt)
|
emit_recipe_predicates(isa, fmt)
|
||||||
|
|
||||||
# Make the `INST_PREDICATES` table.
|
# Make the `INST_PREDICATES` table.
|
||||||
emit_inst_predicates(isa.all_instps, fmt)
|
emit_inst_predicates(isa.instp_number, fmt)
|
||||||
|
|
||||||
# Level1 tables, one per CPU mode
|
# Level1 tables, one per CPU mode
|
||||||
level1_tables = dict()
|
level1_tables = dict()
|
||||||
|
|||||||
Reference in New Issue
Block a user