2 # Initial version written by lkcl Oct 2020
3 # This program analyses the Power 9 op codes and looks at in/out register uses
4 # The results are displayed:
5 # https://libre-soc.org/openpower/opcode_regs_deduped/
7 # It finds .csv files in the directory isatables/
11 from os
.path
import dirname
, join
13 from collections
import OrderedDict
15 # Return absolute path (ie $PWD) + isatables + name
16 def find_wiki_file(name
):
17 filedir
= os
.path
.dirname(os
.path
.abspath(__file__
))
18 tabledir
= join(filedir
, 'isatables')
19 file_path
= join(tabledir
, name
)
22 # Return an array of dictionaries from the CSV file name:
24 file_path
= find_wiki_file(name
)
25 with
open(file_path
, 'r') as csvfile
:
26 reader
= csv
.DictReader(csvfile
)
29 # This will return True if all values are true.
30 # Not sure what this is about
32 #for v in row.values():
33 # if 'SPR' in v: # skip all SPRs
35 for v
in row
.values():
40 # General purpose registers have names like: RA, RT, R1, ...
41 # Floating point registers names like: FRT, FRA, FR1, ..., FRTp, ...
42 # Return True if field is a register
44 return field
.startswith('R') or field
.startswith('FR')
47 # These are the attributes of the instructions,
49 keycolumns
= ['unit', 'in1', 'in2', 'in3', 'out', 'CR in', 'CR out',
50 ] # don't think we need these: 'ldst len', 'rc', 'lk']
52 tablecols
= ['unit', 'in', 'outcnt', 'CR in', 'CR out', 'imm'
53 ] # don't think we need these: 'ldst len', 'rc', 'lk']
58 for key
in keycolumns
:
59 # registers IN - special-case: count number of regs RA/RB/RC/RS
60 if key
in ['in1', 'in2', 'in3']:
68 # If upd is 1 then increment the count of outputs
69 if 'outcnt' not in res
:
76 # CRs (Condition Register) (CR0 .. CR7)
77 if key
.startswith('CR'):
78 if row
[key
].startswith('NONE'):
84 if row
[key
] == 'LDST': # we care about LDST units
88 # LDST len (LoadStore length)
89 if key
.startswith('ldst'):
90 if row
[key
].startswith('NONE'):
95 if key
in ['rc', 'lk']:
98 elif row
[key
] == 'NONE':
105 # Convert the numerics 'in' & 'outcnt' to strings
106 res
['in'] = str(res
['in'])
107 res
['outcnt'] = str(res
['outcnt'])
110 if row
['in2'].startswith('CONST_'):
111 res
['imm'] = "1" # row['in2'].split("_")[1]
120 for k
, v
in d
.items():
121 res
.append("%s: %s" % (k
, v
))
125 return ' | '.join(d
) + "|"
129 if row
['unit'] != 'OTHER':
130 res
.append(row
['unit'])
132 res
.append('%sR' % row
['in'])
133 if row
['outcnt'] != '0':
134 res
.append('%sW' % row
['outcnt'])
135 if row
['CR in'] == '1' and row
['CR out'] == '1':
136 #if row['comment'].startswith('cr'):
137 # res.append("CR-2io")
140 elif row
['CR in'] == '1':
142 elif row
['CR out'] == '1':
144 elif 'imm' in row
and row
['imm']:
153 dictkeys
= OrderedDict()
155 # Expand that (all .csv files)
156 pth
= find_wiki_file("*.csv")
158 # Ignore those containing: valid test sprs
159 for fname
in glob(pth
):
168 csvname
= os
.path
.split(fname
)[1]
169 # csvname is something like: minor_59.csv, fname the whole path
175 dkey
= create_key(row
)
176 key
= tuple(dkey
.values())
182 bykey
[key
].append((csvname
, row
['opcode'], row
['comment'],
183 row
['form'].upper() + '-Form'))
185 primarykeys
= list(primarykeys
)
188 # mapping to old SVPrefix "Forms"
189 mapsto
= {'3R-1W-CRio': 'FR4',
203 'LDST-2R-1W-imm': 'S',
204 'LDST-1R-1W-imm': 'I',
205 'LDST-1R-2W-imm': 'I',
207 print ("# map to old SV Prefix")
209 print ('[[!table data="""')
210 for key
in primarykeys
:
211 name
= keyname(dictkeys
[key
])
212 value
= mapsto
.get(name
, "-")
213 print (tformat([name
, value
+ " "]))
219 print ('[[!table data="""')
220 print (tformat(tablecols
) + " name |")
222 for key
in primarykeys
:
223 name
= keyname(dictkeys
[key
])
224 print (tformat(dictkeys
[key
].values()) + " %s |" % name
)
228 for key
in primarykeys
:
229 name
= keyname(dictkeys
[key
])
230 value
= mapsto
.get(name
, "-")
231 print ("## %s (%s)" % (name
, value
))
233 print ('[[!table data="""')
234 print (tformat(['CSV', 'opcode', 'asm', 'form']))
243 for fname
, csv
in csvs
.items():
246 if __name__
== '__main__':