sorting, remove cmp= comparison functions, using key functions.

* some required several key functions relying on stable sorting

Change-Id: Id8008db21377b7c3c3f2d4425c05e4b018e85d45
(cherry picked from commit 6833101d18a2ae1564a7d96c95ecc6918d86fa54)
This commit is contained in:
Mark Charney
2017-06-10 21:11:38 -04:00
parent 99e3abea6d
commit cce7707c80
5 changed files with 84 additions and 30 deletions

View File

@@ -3122,8 +3122,11 @@ def write_instruction_data(odir,idata_dict):
attributes)
f.write(s)
f.close()
def attr_dict_keyfn(a):
return a[0]
def attr_dict_cmp(a,b):
def attr_dict_cmp(a,b): # FIXME:2017-06-10:PY3 port, now unused
av = a[0]
bv = b[0]
if av == bv:
@@ -3148,7 +3151,7 @@ def write_attributes_table(agi, odir):
t = []
for s,v in agi.attributes_dict.items():
t.append((v,s))
t.sort(cmp=attr_dict_cmp)
t.sort(key=attr_dict_keyfn)
if vattr():
msgb("Sorted Unique attributes", len(t))
agi.attributes_ordered = t
@@ -3239,8 +3242,15 @@ def add_invalid(lst):
lst[0:0] = ['INVALID']
############################################################################
def cmp_invalid(t1,t2):
def key_invalid_first(x):
# make 'INVALID' sort to be first.
if x == 'INVALID':
# space is first printable character in ascii table and should
# not show up in our usage.
return ' '
return x
def cmp_invalid(t1,t2): # FIXME:2017-06-10:PY3 port, no longer used
"""Special sort-comparison function that makes sure the INVALID
entry is first"""
if t1 == t2:
@@ -3254,7 +3264,12 @@ def cmp_invalid(t1,t2):
return -1
def cmp_invalid_vtuple(vt1,vt2):
def key_invalid_tuple_element_0(x):
return key_invalid_first(x[0])
def key_tuple_element_1(x):
return x[1]
def cmp_invalid_vtuple(vt1,vt2): #FIXME:2017-06-10:PY3 port. No longer used
"""Special sort-comparison function that makes sure the INVALID
entry is first"""
t1 = vt1[0]
@@ -3445,7 +3460,7 @@ def emit_iclass_enum_info(agi):
iclasses = uniqueify(iclasses)
# sort each to make sure INVALID is first
iclasses.sort(cmp=cmp_invalid)
iclasses.sort(key=key_invalid_first)
gendir = agi.common.options.gendir
xeddir = agi.common.options.xeddir
agi.iclasses_enum_order = iclasses
@@ -3523,7 +3538,7 @@ def emit_enum_info(agi):
xeddir = agi.common.options.xeddir
nonterminals.sort(cmp=cmp_invalid)
nonterminals.sort(key=key_invalid_first)
nt_enum = enum_txt_writer.enum_info_t(nonterminals, xeddir, gendir,
'xed-nonterminal',
'xed_nonterminal_enum_t',
@@ -3556,14 +3571,14 @@ def emit_enum_info(agi):
#operand_enum order
agi.xed3_operand_names = operand_names
operand_types.sort(cmp=cmp_invalid)
operand_types.sort(key=key_invalid_first)
ot_enum = enum_txt_writer.enum_info_t(operand_types, xeddir, gendir,
'xed-operand-type',
'xed_operand_type_enum_t',
'XED_OPERAND_TYPE_',
cplusplus=False)
attributes.sort(cmp=cmp_invalid)
attributes.sort(key=key_invalid_first)
lena = len(attributes)
attributes_list = ['INVALID']
if lena > 0:
@@ -3587,14 +3602,14 @@ def emit_enum_info(agi):
cplusplus=False)
categories.sort(cmp=cmp_invalid)
categories.sort(key=key_invalid_first)
c_enum = enum_txt_writer.enum_info_t(categories, xeddir, gendir,
'xed-category',
'xed_category_enum_t',
'XED_CATEGORY_',
cplusplus=False)
extensions.sort(cmp=cmp_invalid)
extensions.sort(key=key_invalid_first)
e_enum = enum_txt_writer.enum_info_t(extensions, xeddir, gendir,
'xed-extension',
'xed_extension_enum_t',
@@ -4435,7 +4450,11 @@ def collect_and_emit_iforms(agi,options):
vtuples.extend(vsub)
#msge("VTUPLES %s" % (str(vtuples)))
vtuples.sort(cmp=cmp_invalid_vtuple)
# Relying on stable sorting. sort first by 2nd field (#1), then
# sort by iclass, making sure "INVALID" is first.
vtuples.sort(key=key_tuple_element_1)
vtuples.sort(key=key_invalid_tuple_element_0)
agi.iform_tuples = vtuples
@@ -6229,7 +6248,7 @@ def emit_exception_enum(agi):
if 'INVALID' not in agi.exception_types:
agi.exception_types.append('INVALID')
agi.exception_types = uniqueify(agi.exception_types)
agi.exception_types.sort(cmp=cmp_invalid)
agi.exception_types.sort(key=key_invalid_first)
enum = enum_txt_writer.enum_info_t( agi.exception_types,
agi.common.options.xeddir,
agi.common.options.gendir,
@@ -6269,7 +6288,7 @@ def decorate_instructions_with_exception_types(agi):
def emit_ctypes_enum(options, ctypes_dict):
ctypes_dict['INVALID']=True
type_names = list(ctypes_dict.keys())
type_names.sort(cmp=cmp_invalid)
type_names.sort(key=key_invalid_first)
ctypes_enum = enum_txt_writer.enum_info_t(type_names,
options.xeddir, options.gendir,
'xed-operand-ctype',

View File

@@ -34,6 +34,10 @@ legacy_maps = {'map0':'XED_ILD_MAP0',
'map3':'XED_ILD_MAP3',
'3dnow':'XED_ILD_MAPAMD' }
def key_field_binding_lower(x):
return x.field_name.lower()
def sort_field_bindings(a,b):
''' sort action_t of type emit '''
@@ -43,14 +47,22 @@ def sort_field_bindings(a,b):
return -1
return 0
def cmp_iforms_by_bind_ptrn(a,b):
def key_iform_by_bind_ptrn(x):
return x.bind_ptrn
def cmp_iforms_by_bind_ptrn(a,b): # FIXME:2017-06-10: PY3 port, no longer used
if a.bind_ptrn > b.bind_ptrn:
return 1
elif a.bind_ptrn < b.bind_ptrn:
return -1
return 0
def cmp_iform_len(a,b):
def key_priority(x):
return x.priority
def key_rule_length(x):
return len(x.rule.get_all_emits() + x.rule.get_all_nts())
def cmp_iform_len(a,b): # FIXME:2017-06-10: PY3 port, no longer used
if a.priority > b.priority:
return 1
elif a.priority < b.priority:
@@ -143,7 +155,7 @@ class instructions_group_t(object):
groups = []
#1. generate the groups
for iclass,iforms in list(iarray.items()):
iforms.sort(cmp=cmp_iforms_by_bind_ptrn)
iforms.sort(key=key_iforms_by_bind_ptrn)
self._put_iclass_in_group(groups,iclass,iforms)
# 2. generate the iclass to group Id mapping
@@ -225,7 +237,11 @@ class ins_group_t(object):
for iclass in iclasses:
values = ''
iforms_sorted_by_length = self.iclass2iforms[iclass]
iforms_sorted_by_length.sort(cmp=cmp_iform_len)
iforms_sorted_by_length.sort(key=key_iform_by_bind_ptrn)
iforms_sorted_by_length.sort(key=key_rule_length)
iforms_sorted_by_length.sort(key=key_priority)
for iform in iforms_sorted_by_length:
values += '%4d,' % iform.rule.iform_id
line = "/*%10s*/ {%s}," % (iclass,values)
@@ -605,7 +621,7 @@ class instruction_codegen_t():
for iform in self.iform_list:
# collect all the actions that set fields
iform.fbs = iform.rule.get_all_fbs()
iform.fbs.sort(cmp=sort_field_bindings)
iform.fbs.sort(key=key_field_binding_lower)
# create a list of int values
fbs_values = [ x.int_value for x in iform.fbs]

View File

@@ -86,14 +86,19 @@ class operand_field_t(object):
return True
return False
def cmp_operands_name(a,b):
def key_operand_name(a):
return a.name
def key_bitwidth(a):
return a.bitwidth
def cmp_operands_name(a,b): # FIXME:2017-06-10:PY3 port, no longer used
if a.name > b.name:
return 1
if a.name < b.name:
return -1
return 0
def cmp_operands(a,b):
def cmp_operands(a,b): # FIXME:2017-06-10:PY3 port, no longer used
''' comparing the operands on based on their bit width
larger width first.
if width are the same compare the names, lower name first '''
@@ -105,7 +110,11 @@ def cmp_operands(a,b):
if w1 < w2:
return 1
return cmp_operands_name(a,b)
def sort_cmp_operands(a):
b = sorted(a, key=key_operand_name)
c = sorted(b, key=key_bitwidth)
return c
class operands_storage_t(object):
"""This is where we build up the storage for the fields that hold
@@ -389,7 +398,7 @@ class operands_storage_t(object):
operands = list(self.operand_fields.values())
un_compressed = list(filter(lambda x: x.compressed == False, operands ))
un_compressed.sort(cmp=cmp_operands)
un_compressed = sort_cmp_operands(un_compressed)
# first emit all the operands that does not use bit fields
for op in un_compressed:
@@ -404,7 +413,7 @@ class operands_storage_t(object):
else:
operands_sorted = list(self.operand_fields.values())
operands_sorted.sort(cmp=cmp_operands)
operands_sorted = sort_cmp_operands(operands_sorted)
for op in operands_sorted:
cgen.add_var(op.name.lower(), op.storage_type,
accessors='none')
@@ -485,7 +494,7 @@ class operands_storage_t(object):
using First Fit Decreasing(FFD) strategy '''
operands = self._get_candidates_for_compression()
operands.sort(cmp=cmp_operands)
operands = sort_cmp_operands(operands)
bins = self._partition_to_bins(operands)
return bins

View File

@@ -1248,7 +1248,11 @@ class iform_t(object):
s.append("\t%s" % str(a))
return '\n'.join(s)
def rule_tuple_sort(a,b):
def key_rule_tuple(x):
(a1,a2) = x
return a1
def rule_tuple_sort(a,b): # FIXME:2017-06-10:PY3 port, no longer used
(a1,a2) = a
(b1,b2) = b
if a1 > b1:
@@ -1332,7 +1336,7 @@ class nonterminal_t(object):
weight = len(rule.actions) # try to get shortest form first...
_vmsgb("RULE WEIGHT %d" % (weight), str(rule))
tups.append((weight,rule))
tups.sort(cmp=rule_tuple_sort)
tups.sort(key=key_rule_tuple)
newrules = []
for (x,y) in tups:
newrules.append(y)
@@ -2429,7 +2433,10 @@ class encoder_configuration_t(object):
fo.add_code_eol(code)
# FIXME: 2014-04-17: copy to sorted_iforms still sorts ins_group.iforms
sorted_iforms = ins_group.iforms
sorted_iforms.sort(cmp=ins_emit.cmp_iform_len)
sorted_iforms.sort(key=ins_emit.key_iform_by_bind_ptrn)
sorted_iforms.sort(key=ins_emit.key_rule_length)
sorted_iforms.sort(key=ins_emit.key_priority)
for i,iform in enumerate(sorted_iforms):
# FIXME:2007-07-05 emit the iform.operand_order check of
# the xed_encode_order[][] array

View File

@@ -151,7 +151,10 @@ def refine_regs_input(lines):
return regs_list
def _reg_cmp(a,b):
def _key_reg_ordinal(x):
return x.ordinal
def _reg_cmp(a,b): # FIXME:2017-06-10: PY3 port, no longer used
if a.ordinal < b.ordinal:
return -1
elif a.ordinal > b.ordinal:
@@ -166,7 +169,7 @@ def rearrange_regs(regs_list):
enumvals = []
for g in groups:
k = list(filter(lambda x: x.rtype == g, regs_list))
k.sort(cmp=_reg_cmp)
k.sort(key=_key_reg_ordinal)
first = '%s_FIRST' % (g)
last = '%s_LAST' % (g)