take out print-comments from ls012 optable generator
[libreriscv.git] / openpower / sv / rfc / ls012_optable.py
1 #!/usr/bin/env python3
2 # generates markdown tables from CSV files, after doing lovely sorting
3 # by different columns, blah blah...
4 from copy import deepcopy
5 import functools
6
7 def write_mdwn_row(f, row):
8 row = "|".join(row)
9 row = "|%s|\n" % row
10 f.write(row)
11
12 def underlines(header):
13 row = []
14 for col in header:
15 row.append("-" * len(col))
16 return row
17
18 # sorting functions
19 def is_svp64_page(page):
20 return page in ['sv/setvl', 'sv/svstep', 'sv/remap']
21
22 def sort_by_page(p1, p2):
23 p1 = p1['page']
24 p2 = p2['page']
25 if not (is_svp64_page(p1) ^ is_svp64_page(p2)):
26 if p1 < p2: return -1
27 if p1 > p2: return 1
28 return 0
29 if is_svp64_page(p1):
30 return -1
31 if is_svp64_page(p2):
32 return 1
33 return 0
34
35 priorities = ['high', 'med', 'low', 'TBD']
36
37 def sort_by_priority(p1, p2):
38 p1 = priorities.index(p1['priority'])
39 p2 = priorities.index(p2['priority'])
40 if p1 < p2: return -1
41 if p1 > p2: return 1
42 return 0
43
44 def sort_by_cost(p1, p2):
45 p1 = p1['cost']
46 p2 = p2['cost']
47 if not p1.isdigit(): p1 = 0
48 if not p2.isdigit(): p2 = 0
49 p1 = int(p1)
50 p2 = int(p2)
51 if p1 < p2: return -1
52 if p1 > p2: return 1
53 return 0
54
55 def sort_by_cost_priority_page(p1, p2):
56 v = sort_by_cost(p1, p2)
57 if v == 0:
58 v = sort_by_priority(p1, p2)
59 if v == 0:
60 v = sort_by_page(p1, p2)
61 return v
62
63
64 def by_cost_then_priority_then_page(areas):
65 # first blat all columns together (drop area-dict)
66 res = []
67 for row in areas.values():
68 res += row
69 # now sort them
70 res = sorted(res, key=functools.cmp_to_key(sort_by_cost_priority_page))
71 # now split out into a dict again this time by cost-priority
72 costs = {}
73 for row in res:
74 cost = row['cost']
75 if cost not in costs:
76 costs[cost] = []
77 costs[cost].append(row)
78 return costs
79
80
81 def print_table(title, header, areas, sortby):
82 fname = title.lower().replace(" ", "_")
83 with open("ls012/%s.mdwn" % fname, "w") as f:
84 # write out the page header
85 f.write("\\newpage{}\n")
86 f.write("\n")
87 f.write("# %s\n" % title)
88 f.write("\n")
89 # sort everything if required
90 if sortby is not None:
91 areas = sortby(areas)
92 linecount = None
93 # start writing out areas
94 for title, rows in areas.items():
95 # start new page (if not first newpage)
96 if linecount is not None:
97 # allow 60 rows per page
98 linecount += len(rows)
99 if linecount >= 60:
100 linecount = 0
101 if linecount == 0:
102 f.write("\\newpage{}\n")
103 f.write("\n")
104 if linecount is None: # skipped first newpage
105 linecount = 0
106
107 f.write("## %s\n" % title)
108 f.write("\n")
109
110 # work out maximum length of items, and adjust header
111 hdr = deepcopy(header)
112 cols = {}
113 for hd in hdr:
114 cols[hd] = len(hd)
115 for row in rows:
116 for hd, value in row.items():
117 cols[hd] = max(cols[hd], len(value))
118 # adjust header (add spaces)
119 for i, hd in enumerate(hdr):
120 n_spaces = cols[hd] - len(hd)
121 hdr[i] = hdr[i] + " " * n_spaces
122 # write out header
123 write_mdwn_row(f, hdr)
124 write_mdwn_row(f, underlines(hdr))
125 for row in rows:
126 # adjust row (add same spaces as header width)
127 r = []
128 for key in row.keys():
129 col_len, value = cols[key], row[key]
130 if key == 'page':
131 prefix = 'https://libre-soc.org/openpower/'
132 v = value.replace("_", "\_") # latex, duh
133 url = '[%s](%s%s)' % (value, prefix, v)
134 r.append(url)
135 elif key == 'rfc' and value.startswith('ls'):
136 prefix = 'https://libre-soc.org/openpower/sv/rfc/'
137 url = '[%s](%s%s)' % (value, prefix, value)
138 r.append(url)
139 else:
140 value = value.replace("_", "\_") # latex, duh
141 n_spaces = col_len - len(value)
142 r.append(value + " " * n_spaces)
143 # write row
144 write_mdwn_row(f, r)
145 f.write("\n\n")
146
147 # approx 8 lines per header
148 linecount += 9
149
150 if __name__ == '__main__':
151 with open("ls012/optable.csv") as f:
152 l = map(str.strip, f.readlines())
153 areas = {}
154 header = None
155 for line in l:
156 if line.startswith("#"):
157 area = line[1:].strip()
158 areas[area]= []
159 continue
160 # split line by commas, whitespace-strip it
161 line = list(map(str.strip, line.split(',')))
162 # identify header
163 if header is None:
164 header = line
165 continue
166 # create a dictionary by tuple of header+line
167 linedict = dict(zip(header, line))
168 #print (area)
169 #print (linedict)
170 #print ()
171 # store line in area
172 areas[area].append(linedict)
173
174 # exccellent - now have a dictionary of list of dictionaries:
175 # area - list-of-instructions - dictionary-by-heading
176 print_table("Areas", header, areas, None)
177
178 # now sort by cost and then by page
179 print_table("XO cost", header, areas, by_cost_then_priority_then_page)
180