2019-07-28 00:44:53 +03:00
|
|
|
|
|
|
|
def stringify(v):
|
|
|
|
if type(v) == int:
|
2019-08-02 09:10:58 +03:00
|
|
|
if v < 0:
|
|
|
|
return "-" + hex(v)[3:]
|
|
|
|
return hex(v)[2:]
|
2019-07-28 00:44:53 +03:00
|
|
|
return v
|
|
|
|
|
|
|
|
def javascript(obj):
|
|
|
|
if type(obj) == int:
|
|
|
|
return str(obj)
|
|
|
|
if type(obj) == list:
|
|
|
|
return "[ " + ", ".join(javascript(i) for i in obj) + " ]";
|
|
|
|
if type(obj) == dict:
|
|
|
|
return "{ " + ", ".join(map(lambda k: ("%s: %s" % (stringify(k), javascript(obj[k]))), obj.keys())) + " }"
|
|
|
|
print obj
|
|
|
|
raise Exception("unsupported")
|
|
|
|
|
|
|
|
def javascript_table(obj):
|
|
|
|
keys = obj.keys();
|
|
|
|
keys.sort()
|
2019-08-02 09:10:58 +03:00
|
|
|
|
|
|
|
obj = [ [ k, obj[k] ] for k in keys ]
|
|
|
|
|
|
|
|
last = 0
|
|
|
|
for item in obj:
|
|
|
|
item[1] = stringify(item[1])
|
|
|
|
v = item[0]
|
|
|
|
item[0] -= last
|
|
|
|
last = v
|
|
|
|
|
|
|
|
return '"' + ",".join(("%s:%s" % (stringify(i[0]), i[1])) for i in obj) + '"'
|
2019-07-28 00:44:53 +03:00
|
|
|
|
|
|
|
weird = [ ];
|
|
|
|
lines = [ ]
|
|
|
|
for line in file("table.b.2.txt"):
|
|
|
|
comps = [ x.strip() for x in line.split(";") ]
|
|
|
|
if len(comps) != 3: raise Exception("bad line")
|
|
|
|
if len(comps[1].split(" ")) > 1:
|
|
|
|
weird.append(comps)
|
|
|
|
continue
|
|
|
|
lines.append(dict(
|
|
|
|
src = int(comps[0], 16),
|
|
|
|
dst = int(comps[1], 16),
|
|
|
|
reason = comps[2]
|
|
|
|
))
|
|
|
|
|
|
|
|
buckets = dict()
|
|
|
|
|
|
|
|
for p in lines:
|
|
|
|
delta = p["dst"] - p["src"];
|
|
|
|
special = ""
|
|
|
|
if delta not in buckets: buckets[delta] = [ ]
|
|
|
|
buckets[delta].append(p)
|
|
|
|
|
|
|
|
deltas = buckets.keys()
|
|
|
|
deltas.sort()
|
|
|
|
|
|
|
|
simple = dict()
|
|
|
|
simple_relative = dict()
|
2019-08-02 09:10:58 +03:00
|
|
|
debug = dict()
|
2019-07-28 00:44:53 +03:00
|
|
|
|
|
|
|
def add_simple(src, dst):
|
|
|
|
if len(str(dst - src)) < len(str(dst)):
|
|
|
|
simple_relative[src] = dst - src
|
2019-08-02 09:10:58 +03:00
|
|
|
debug[src] = "rel:" + str(dst - src)
|
2019-07-28 00:44:53 +03:00
|
|
|
else:
|
|
|
|
simple[src] = dst
|
2019-08-02 09:10:58 +03:00
|
|
|
debug[src] = "abs:" + str(dst)
|
2019-07-28 00:44:53 +03:00
|
|
|
|
|
|
|
def add_simple_data(data):
|
|
|
|
stride = 1
|
|
|
|
skip = [ ]
|
|
|
|
if "d" in data: stride = data["d"]
|
|
|
|
if "e" in data: skip = data["e"]
|
2019-08-02 09:10:58 +03:00
|
|
|
#print "ADD", data
|
2019-07-28 00:44:53 +03:00
|
|
|
for i in xrange(data["l"], data["l"] + data["h"] + 1, stride):
|
2019-08-02 09:10:58 +03:00
|
|
|
#print " ", i, data
|
|
|
|
if (i - data["l"]) in skip: continue
|
|
|
|
add_simple(i, i + data["s"])
|
2019-07-28 00:44:53 +03:00
|
|
|
|
|
|
|
mappings = [ ]
|
|
|
|
|
|
|
|
for delta in deltas:
|
|
|
|
bucket = buckets[delta]
|
|
|
|
|
|
|
|
if len(bucket) <= 7:
|
|
|
|
for p in bucket:
|
|
|
|
add_simple(p["src"], p["dst"])
|
|
|
|
continue
|
|
|
|
|
|
|
|
last = 0
|
|
|
|
|
2019-08-02 09:10:58 +03:00
|
|
|
# Compute the mode of the delta
|
2019-07-28 00:44:53 +03:00
|
|
|
mode = dict()
|
|
|
|
last = 0xffffffff
|
|
|
|
for p in buckets[delta]:
|
|
|
|
dl = p["src"] - last
|
|
|
|
if dl not in mode: mode[dl] = 0
|
|
|
|
mode[dl] += 1
|
|
|
|
last = p["src"]
|
|
|
|
mode = map(lambda k: (mode[k], k), mode.keys())
|
|
|
|
mode.sort()
|
|
|
|
mode = mode[-1][1]
|
|
|
|
|
|
|
|
data = None
|
|
|
|
|
|
|
|
for p in bucket:
|
|
|
|
leap = ""
|
|
|
|
dl = p["src"] - last
|
2019-08-02 09:10:58 +03:00
|
|
|
|
|
|
|
# Non-standard detla...
|
2019-07-28 00:44:53 +03:00
|
|
|
if dl != mode:
|
2019-08-02 09:10:58 +03:00
|
|
|
|
|
|
|
# But only a small gap; add exceptions
|
2019-07-28 00:44:53 +03:00
|
|
|
if data and (dl % mode) == 0 and (dl - mode) < 5:
|
|
|
|
if "e" not in data: data["e"] = [ ]
|
|
|
|
for i in xrange(last + mode, p["src"], mode):
|
|
|
|
data["e"].append(i - data["l"])
|
2019-08-02 09:10:58 +03:00
|
|
|
|
|
|
|
# Big gap; start a new range
|
2019-07-28 00:44:53 +03:00
|
|
|
else:
|
|
|
|
if data:
|
|
|
|
data["h"] -= data["l"]
|
2019-08-02 09:10:58 +03:00
|
|
|
|
|
|
|
# Small range, use simple LUT instead
|
2019-07-28 00:44:53 +03:00
|
|
|
if data["h"] <= 7:
|
|
|
|
add_simple_data(data)
|
|
|
|
else:
|
2019-08-02 09:10:58 +03:00
|
|
|
mappings.append(data)
|
|
|
|
debug[data["l"]] = "MAP:" + str(data)
|
|
|
|
|
|
|
|
# New range
|
2019-07-28 00:44:53 +03:00
|
|
|
data = dict(l = 0xffffffff, h = 0, s = delta)
|
|
|
|
if mode != 1: data["d"] = mode
|
2019-08-02 09:10:58 +03:00
|
|
|
|
|
|
|
# Indicate a new range started in the debug info
|
2019-07-28 00:44:53 +03:00
|
|
|
leap = "***"
|
2019-08-02 09:10:58 +03:00
|
|
|
|
|
|
|
# Update ranges
|
2019-07-28 00:44:53 +03:00
|
|
|
if p["src"] < data["l"]: data["l"] = p["src"]
|
|
|
|
if p["src"] > data["h"]: data["h"] = p["src"]
|
|
|
|
last = p["src"]
|
|
|
|
|
|
|
|
data["h"] -= data["l"]
|
|
|
|
if data["h"] <= 7:
|
|
|
|
add_simple_data(data)
|
|
|
|
else:
|
2019-08-02 09:10:58 +03:00
|
|
|
mappings.append(data)
|
|
|
|
debug[data["l"]] = "MAP:" + str(data)
|
2019-07-28 00:44:53 +03:00
|
|
|
|
2019-08-03 07:43:22 +03:00
|
|
|
# Create complex table (things that map to more than one byte)
|
2019-07-28 00:44:53 +03:00
|
|
|
complex = { }
|
2019-08-03 07:43:22 +03:00
|
|
|
complex_output = [ ];
|
2019-07-28 00:44:53 +03:00
|
|
|
for (src, dst, reason) in weird:
|
|
|
|
for word in dst.split(" "):
|
2019-08-03 07:43:22 +03:00
|
|
|
complex_output.append(int(word, 16))
|
2019-07-28 00:44:53 +03:00
|
|
|
if len(word) != 4: raise Exception("hmmm")
|
|
|
|
complex[int(src, 16)] = dst.replace(" ", "")
|
2019-08-03 07:43:22 +03:00
|
|
|
|
|
|
|
# Experimenting: We can easily create a LUT for the individual
|
|
|
|
# components, as there is substantial overlap.
|
|
|
|
#complex_output = dict((x, True) for x in complex_output).keys()
|
|
|
|
#complex_output.sort()
|
|
|
|
#print "COM", complex_output, len(complex_output)
|
|
|
|
|
|
|
|
# Sort mappings by lo
|
2019-08-02 09:10:58 +03:00
|
|
|
mappings.sort(lambda a, b: cmp(a["l"], b["l"]))
|
|
|
|
|
2019-08-03 07:43:22 +03:00
|
|
|
#debug_keys = debug.keys()
|
|
|
|
#debug_keys.sort()
|
|
|
|
#for d in debug_keys:
|
|
|
|
# print d, debug[d]
|
2019-08-02 09:10:58 +03:00
|
|
|
|
|
|
|
#print mappings
|
|
|
|
|
|
|
|
last = 0
|
|
|
|
for item in mappings:
|
|
|
|
v = item["l"]
|
|
|
|
item["l"] -= last
|
|
|
|
last = v
|
2019-07-28 00:44:53 +03:00
|
|
|
|
|
|
|
print "const Table_B_2_ranges = ["
|
2019-08-02 09:10:58 +03:00
|
|
|
print ",\n".join((" " + javascript(m)) for m in mappings)
|
2019-07-28 00:44:53 +03:00
|
|
|
print "];"
|
2019-08-02 09:10:58 +03:00
|
|
|
|
|
|
|
print "SS", list(sorted(simple.keys())), simple[120763]
|
|
|
|
print "SS2", list(sorted(simple_relative.keys()))
|
2019-07-28 00:44:53 +03:00
|
|
|
print "const Table_B_2_lut_abs = createTable(" + javascript_table(simple) + ");"
|
|
|
|
print "const Table_B_2_lut_rel = createTable(" + javascript_table(simple_relative) + ");"
|
|
|
|
print "const Table_B_2_complex = createTable(" + javascript_table(complex) + ", bytes2);"
|