Move predicate collection into TargetISA.

Add a TargetISA.finish() method which computes derived data structures after
the ISA definitions have been loaded.
This commit is contained in:
Jakob Stoklund Olesen
2016-08-26 09:31:50 -07:00
parent 7cb975ce63
commit c1ae0c99ed
3 changed files with 44 additions and 26 deletions

View File

@@ -955,6 +955,37 @@ class TargetISA(object):
self.instruction_groups = instruction_groups self.instruction_groups = instruction_groups
self.cpumodes = list() self.cpumodes = list()
def finish(self):
"""
Finish the definition of a target ISA after adding all CPU modes and
settings.
This computes some derived properties that are used in multilple
places.
:returns self:
"""
self._collect_instruction_predicates()
return self
def _collect_instruction_predicates(self):
"""
Collect and number all instruction predicates in use.
Sets `instp.number` for all used instruction predicates and places them
in `self.all_instps` in numerical order.
"""
self.all_instps = list()
instps = set()
for cpumode in self.cpumodes:
for enc in cpumode.encodings:
instp = enc.instp
if instp and instp not in instps:
# assign predicate number starting from 0.
instp.number = len(instps)
instps.add(instp)
self.all_instps.append(instp)
class CPUMode(object): class CPUMode(object):
""" """

View File

@@ -75,10 +75,11 @@ def emit_instp(instp, fmt):
# the field names. # the field names.
fields = ', '.join(sorted(set(p.field.name for p in leafs))) fields = ', '.join(sorted(set(p.field.name for p in leafs)))
with fmt.indented( with fmt.indented('{} => {{'.format(instp.number), '}'):
'if let {} {{ {}, .. }} = *inst {{' with fmt.indented(
.format(iform.name, fields), '}'): 'if let {} {{ {}, .. }} = *inst {{'
fmt.line('return {};'.format(instp.rust_predicate(0))) .format(iform.name, fields), '}'):
fmt.line('return {};'.format(instp.rust_predicate(0)))
def emit_instps(instps, fmt): def emit_instps(instps, fmt):
@@ -90,9 +91,8 @@ def emit_instps(instps, fmt):
'fn check_instp(inst: &InstructionData, instp_idx: u16) -> bool {', 'fn check_instp(inst: &InstructionData, instp_idx: u16) -> bool {',
'}'): '}'):
with fmt.indented('match instp_idx {', '}'): with fmt.indented('match instp_idx {', '}'):
for (instp, idx) in instps.items(): for instp in instps:
with fmt.indented('{} => {{'.format(idx), '}'): emit_instp(instp, fmt)
emit_instp(instp, fmt)
fmt.line('_ => panic!("Invalid instruction predicate")') fmt.line('_ => panic!("Invalid instruction predicate")')
# The match cases will fall through if the instruction format is wrong. # The match cases will fall through if the instruction format is wrong.
@@ -102,17 +102,6 @@ def emit_instps(instps, fmt):
fmt.line(' instp_idx);') fmt.line(' instp_idx);')
def collect_instps(cpumodes):
# Map instp -> number
instps = OrderedDict()
for cpumode in cpumodes:
for enc in cpumode.encodings:
instp = enc.instp
if instp and instp not in instps:
instps[instp] = 1 + len(instps)
return instps
class EncList(object): class EncList(object):
""" """
List of instructions for encoding a given type + opcode pair. List of instructions for encoding a given type + opcode pair.
@@ -192,13 +181,12 @@ def make_tables(cpumode):
return table return table
def gen_isa(cpumodes, fmt): def gen_isa(isa, fmt):
# First assign numbers to relevant instruction predicates and generate the # First assign numbers to relevant instruction predicates and generate the
# check_instp() function.. # check_instp() function..
instps = collect_instps(cpumodes) emit_instps(isa.all_instps, fmt)
emit_instps(instps, fmt)
for cpumode in cpumodes: for cpumode in isa.cpumodes:
level1 = make_tables(cpumode) level1 = make_tables(cpumode)
for level2 in level1: for level2 in level1:
for enclist in level2: for enclist in level2:
@@ -210,5 +198,5 @@ def gen_isa(cpumodes, fmt):
def generate(isas, out_dir): def generate(isas, out_dir):
for isa in isas: for isa in isas:
fmt = srcgen.Formatter() fmt = srcgen.Formatter()
gen_isa(isa.cpumodes, fmt) gen_isa(isa, fmt)
fmt.update_file('encoding-{}.rs'.format(isa.name), out_dir) fmt.update_file('encoding-{}.rs'.format(isa.name), out_dir)

View File

@@ -26,8 +26,7 @@ RV32G / RV64G
""" """
from __future__ import absolute_import from __future__ import absolute_import
from . import defs from . import defs
from . import encodings from . import encodings, settings # noqa
from . import settings
# Re-export the primary target ISA definition. # Re-export the primary target ISA definition.
isa = defs.isa isa = defs.isa.finish()