Generate level 2 hashtables.
All of the level 2 hashtables are concatenated into one constant array per ISA.
This commit is contained in:
@@ -51,6 +51,7 @@ instructions with different types for secondary type variables.
|
|||||||
"""
|
"""
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
import srcgen
|
import srcgen
|
||||||
|
from constant_hash import compute_quadratic
|
||||||
from unique_table import UniqueSeqTable
|
from unique_table import UniqueSeqTable
|
||||||
from collections import OrderedDict, defaultdict
|
from collections import OrderedDict, defaultdict
|
||||||
|
|
||||||
@@ -215,6 +216,21 @@ class Level2Table(object):
|
|||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
return iter(self.lists.values())
|
return iter(self.lists.values())
|
||||||
|
|
||||||
|
def layout_hashtable(self, level2_hashtables):
|
||||||
|
"""
|
||||||
|
Compute the hash table mapping opcode -> enclist.
|
||||||
|
|
||||||
|
Append the hash table to `level2_hashtables` and record the offset.
|
||||||
|
"""
|
||||||
|
hash_table = compute_quadratic(
|
||||||
|
self.lists.values(),
|
||||||
|
lambda enclist: enclist.inst.number)
|
||||||
|
|
||||||
|
self.hash_table_offset = len(level2_hashtables)
|
||||||
|
self.hash_table_len = len(hash_table)
|
||||||
|
|
||||||
|
level2_hashtables.extend(hash_table)
|
||||||
|
|
||||||
|
|
||||||
class Level1Table(object):
|
class Level1Table(object):
|
||||||
"""
|
"""
|
||||||
@@ -273,6 +289,28 @@ def emit_enclists(seq_table, doc_table, fmt):
|
|||||||
fmt.line(line)
|
fmt.line(line)
|
||||||
|
|
||||||
|
|
||||||
|
def encode_level2_hashtables(level1, level2_hashtables):
|
||||||
|
for level2 in level1:
|
||||||
|
level2.layout_hashtable(level2_hashtables)
|
||||||
|
|
||||||
|
|
||||||
|
def emit_level2_hashtables(level2_hashtables, fmt):
|
||||||
|
"""
|
||||||
|
Emit the big concatenation of level 2 hash tables.
|
||||||
|
"""
|
||||||
|
with fmt.indented(
|
||||||
|
'const LEVEL2: [(Opcode, u32); {}] = ['
|
||||||
|
.format(len(level2_hashtables)),
|
||||||
|
'];'):
|
||||||
|
for entry in level2_hashtables:
|
||||||
|
if entry:
|
||||||
|
fmt.line(
|
||||||
|
'(Opcode::{}, {:#08x}),'
|
||||||
|
.format(entry.inst.camel_name, entry.offset))
|
||||||
|
else:
|
||||||
|
fmt.line('(Opcode::NotAnOpcode, 0),')
|
||||||
|
|
||||||
|
|
||||||
def gen_isa(isa, 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..
|
||||||
@@ -282,11 +320,16 @@ def gen_isa(isa, fmt):
|
|||||||
seq_table = UniqueSeqTable()
|
seq_table = UniqueSeqTable()
|
||||||
doc_table = defaultdict(list)
|
doc_table = defaultdict(list)
|
||||||
|
|
||||||
|
# Single table containing all the level2 hash tables.
|
||||||
|
level2_hashtables = list()
|
||||||
|
|
||||||
for cpumode in isa.cpumodes:
|
for cpumode in isa.cpumodes:
|
||||||
level1 = make_tables(cpumode)
|
level1 = make_tables(cpumode)
|
||||||
encode_enclists(level1, seq_table, doc_table)
|
encode_enclists(level1, seq_table, doc_table)
|
||||||
|
encode_level2_hashtables(level1, level2_hashtables)
|
||||||
|
|
||||||
emit_enclists(seq_table, doc_table, fmt)
|
emit_enclists(seq_table, doc_table, fmt)
|
||||||
|
emit_level2_hashtables(level2_hashtables, fmt)
|
||||||
|
|
||||||
|
|
||||||
def generate(isas, out_dir):
|
def generate(isas, out_dir):
|
||||||
|
|||||||
@@ -191,6 +191,7 @@ def gen_opcodes(groups, fmt):
|
|||||||
for g in groups:
|
for g in groups:
|
||||||
for i in g.instructions:
|
for i in g.instructions:
|
||||||
instrs.append(i)
|
instrs.append(i)
|
||||||
|
i.number = len(instrs)
|
||||||
# Build a doc comment.
|
# Build a doc comment.
|
||||||
prefix = ', '.join(o.name for o in i.outs)
|
prefix = ', '.join(o.name for o in i.outs)
|
||||||
if prefix:
|
if prefix:
|
||||||
|
|||||||
Reference in New Issue
Block a user