33import re
44import sys
55from collections import defaultdict
6- import yaml
6+ import yaml
77
8- REPO_INSTRUCTIONS = {}
8+ REPO_INSTRUCTIONS = {}
99REPO_DIRECTORY = None
1010
1111def safe_get (data , key , default = "" ):
@@ -123,7 +123,7 @@ def parse_location(loc_str):
123123 else :
124124 json_var_fields .append ('?' )
125125
126- # Extract field names from something like varName[index]. After normalizing, vm and others won't have indices.
126+ # Extract field names
127127 field_names = set (re .findall (r'([A-Za-z0-9]+)(?:\[\d+\]|\[\?\])?' , ' ' .join (json_var_fields )))
128128 if len (field_names ) == 0 :
129129 differences .append (f"Variable { var_name } : No corresponding field found in JSON bits { high } -{ low } " )
@@ -162,27 +162,6 @@ def safe_print_instruction_details(name: str, data: dict, output_stream):
162162 except :
163163 output_stream .write ("Outputs: N/A\n " )
164164
165- # # Instruction Properties
166- # output_stream.write("\nInstruction Properties:\n")
167- # output_stream.write("-" * 20 + "\n")
168- # output_stream.write(f"Commutable: {'Yes' if safe_get(data, 'isCommutable', 0) else 'No'}\n")
169- # output_stream.write(f"Memory Load: {'Yes' if safe_get(data, 'mayLoad', 0) else 'No'}\n")
170- # output_stream.write(f"Memory Store: {'Yes' if safe_get(data, 'mayStore', 0) else 'No'}\n")
171- # output_stream.write(f"Side Effects: {'Yes' if safe_get(data, 'hasSideEffects', 0) else 'No'}\n")
172-
173- # # Scheduling Info
174- # sched = safe_get(data, 'SchedRW', [])
175- # if sched:
176- # output_stream.write("\nScheduling Information:\n")
177- # output_stream.write("-" * 20 + "\n")
178- # output_stream.write("Operations:\n")
179- # try:
180- # for op in sched:
181- # if isinstance(op, dict):
182- # output_stream.write(f" - {op.get('printable', 'N/A')}\n")
183- # except:
184- # output_stream.write(" - Unable to parse scheduling information\n")
185-
186165 # Encoding
187166 output_stream .write ("\n Encoding Pattern:\n " )
188167 output_stream .write ("-" * 20 + "\n " )
@@ -234,18 +213,11 @@ def get_repo_instructions(repo_directory):
234213 """
235214 repo_instructions = {}
236215 for root , _ , files in os .walk (repo_directory ):
237- rel_path = os .path .relpath (root , repo_directory )
238- if rel_path == '.' :
239- category = "Other"
240- else :
241- parts = rel_path .split (os .sep )
242- category = parts [0 ] if parts else "Other"
243-
244216 for file in files :
245217 if file .endswith (".yaml" ):
246218 instr_name = os .path .splitext (file )[0 ]
247- # Store lowercase key for easy lookup
248- repo_instructions [instr_name .lower ()] = category
219+ relative_path = os . path . relpath ( root , repo_directory )
220+ repo_instructions [instr_name .lower ()] = relative_path
249221 return repo_instructions
250222
251223def find_json_key (instr_name , json_data ):
@@ -269,29 +241,29 @@ def find_json_key(instr_name, json_data):
269241 return v
270242 return None
271243
272- def main ():
244+ def run_parser (json_file , repo_directory , output_file = "output.txt" ):
245+ """
246+ Run the parser logic:
247+ 1. Get instructions from the repo directory.
248+ 2. Parse the JSON file and match instructions.
249+ 3. Generate output.txt with instruction details.
250+ """
273251 global REPO_INSTRUCTIONS , REPO_DIRECTORY
274-
275- if len (sys .argv ) != 3 :
276- print ("Usage: python riscv_parser.py <tablegen_json_file> <arch_inst_directory>" )
277- sys .exit (1 )
278-
279- json_file = sys .argv [1 ]
280- REPO_DIRECTORY = sys .argv [2 ]
252+ REPO_DIRECTORY = repo_directory
281253
282254 # Get instructions and categories from the repository structure
283255 REPO_INSTRUCTIONS = get_repo_instructions (REPO_DIRECTORY )
284256 if not REPO_INSTRUCTIONS :
285257 print ("No instructions found in the provided repository directory." )
286- sys . exit ( 1 )
258+ return None
287259
288260 try :
289261 # Read and parse JSON
290262 with open (json_file , 'r' ) as f :
291263 data = json .loads (f .read ())
292264 except Exception as e :
293265 print (f"Error reading file: { str (e )} " )
294- sys . exit ( 1 )
266+ return None
295267
296268 all_instructions = []
297269
@@ -313,7 +285,7 @@ def main():
313285 # Sort all instructions by name
314286 all_instructions .sort (key = lambda x : x [0 ].lower ())
315287
316- with open ("output.txt" , "w" ) as outfile :
288+ with open (output_file , "w" ) as outfile :
317289 outfile .write ("RISC-V Instruction Summary\n " )
318290 outfile .write ("=" * 50 + "\n " )
319291 total = len (all_instructions )
@@ -324,11 +296,24 @@ def main():
324296 outfile .write ("\n DETAILED INSTRUCTION INFORMATION\n " )
325297 outfile .write ("=" * 80 + "\n " )
326298
327- # Print details for each instruction directly, no category splitting
299+ # Print details for each instruction directly
328300 for name , instr_data in all_instructions :
329301 safe_print_instruction_details (name , instr_data , outfile )
330302
331- print ("Output has been written to output.txt" )
303+ print (f"Output has been written to { output_file } " )
304+ return output_file
305+
306+ def main ():
307+ if len (sys .argv ) != 3 :
308+ print ("Usage: python riscv_parser.py <tablegen_json_file> <arch_inst_directory>" )
309+ sys .exit (1 )
310+
311+ json_file = sys .argv [1 ]
312+ repo_directory = sys .argv [2 ]
313+
314+ result = run_parser (json_file , repo_directory , output_file = "output.txt" )
315+ if result is None :
316+ sys .exit (1 )
332317
333318if __name__ == '__main__' :
334319 main ()
0 commit comments