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.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):
"""

View File

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

View File

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