@@ -33,8 +33,6 @@ def parse_header_files(header_files):
3333 # Replace defined constants in the expression with their values
3434 value = evaluate_expression (value_expr , defines )
3535 defines [name ] = value
36- # Debug: Uncomment the following line to see parsed defines
37- # print(f"Parsed Define: {name} = {hex(value)}")
3836 except Exception :
3937 # Skip defines that cannot be evaluated
4038 continue
@@ -95,9 +93,6 @@ def parse_instruction_files(instruction_files):
9593 Returns:
9694 instructions (list of dict): Each dict contains 'name', 'match_expr', 'mask_expr', 'class', 'flags', 'line_num', 'file'.
9795 """
98- # Updated pattern to capture the entire match and mask expressions and the flags
99- # Example line:
100- # {"fence", 0, INSN_CLASS_I, "P,Q", MATCH_FENCE, MASK_FENCE|MASK_RD|MASK_RS1|(MASK_IMM & ~MASK_PRED & ~MASK_SUCC), match_opcode, 0 },
10196 instr_pattern = re .compile (
10297 r'\{\s*"([\w\.]+)",\s*\d+,\s*(INSN_CLASS_\w+),\s*"[^"]*",\s*(MATCH_[^,]+),\s*(MASK_[^,]+),[^,]+,\s*([^}]+)\s*\},'
10398 )
@@ -115,6 +110,15 @@ def parse_instruction_files(instruction_files):
115110 match_expr = instr_match .group (3 ).strip ()
116111 mask_expr = instr_match .group (4 ).strip ()
117112 flags = instr_match .group (5 ).strip ()
113+
114+ # Skip alias entries
115+ if 'INSN_ALIAS' in flags :
116+ continue
117+
118+ # Check if the instruction follows the naming pattern
119+ if not check_match_mask_pattern (instr_name , match_expr , mask_expr ):
120+ continue # Skip instructions that don't follow the pattern
121+
118122 instructions .append ({
119123 'name' : instr_name ,
120124 'class' : instr_class ,
@@ -124,8 +128,6 @@ def parse_instruction_files(instruction_files):
124128 'line_num' : line_num ,
125129 'file' : instr_file
126130 })
127- # Debug: Uncomment the following line to see parsed instructions
128- # print(f"Parsed Instruction: {instr_name} at {instr_file}:{line_num}")
129131 except FileNotFoundError :
130132 print (f"Error: Instruction file '{ instr_file } ' not found." )
131133 sys .exit (1 ) # Exit if an instruction file is missing
@@ -210,32 +212,91 @@ def get_instruction_yaml_files(directory_path):
210212
211213def parse_yaml_encoding (yaml_file_path ):
212214 """
213- Parses the YAML file to extract the 'encoding: match' string.
215+ Parses the YAML file to extract the encoding match string.
216+ Handles the new YAML format with top-level encoding field.
214217
215218 Args:
216219 yaml_file_path (str): Path to the YAML file.
217220
218221 Returns:
219- match_encoding (str): The 32-character match encoding string.
222+ match_encoding (str): The match encoding string.
220223 """
221224 try :
222225 with open (yaml_file_path , 'r' ) as yaml_file :
223226 yaml_content = yaml .safe_load (yaml_file )
224- if not isinstance (yaml_content , dict ) or not yaml_content :
225- print (f"Warning: YAML file '{ yaml_file_path } ' is empty or not properly formatted." )
227+
228+ # Handle case where yaml_content is None
229+ if yaml_content is None :
230+ print (f"Warning: Empty YAML file '{ yaml_file_path } '." )
231+ return ''
232+
233+ if not isinstance (yaml_content , dict ):
234+ print (f"Warning: Unexpected YAML format in '{ yaml_file_path } '. Content type: { type (yaml_content )} " )
226235 return ''
227- instr_name = list (yaml_content .keys ())[0 ]
228- encoding = yaml_content [instr_name ].get ('encoding' , {})
236+
237+ # Get encoding section directly from top level
238+ encoding = yaml_content .get ('encoding' , {})
239+
240+ if not isinstance (encoding , dict ):
241+ print (f"Warning: Encoding is not a dictionary in '{ yaml_file_path } '" )
242+ return ''
243+
244+ # Get match value directly from encoding section
229245 match_encoding = encoding .get ('match' , '' )
246+
230247 if not match_encoding :
231- print (f"Warning: 'encoding.match' not found in YAML file '{ yaml_file_path } '." )
248+ print (f"Warning: No 'encoding.match' found in YAML file '{ yaml_file_path } '." )
249+
250+ # Remove any whitespace in the match encoding
251+ match_encoding = match_encoding .replace (' ' , '' )
252+
232253 return match_encoding
254+
233255 except FileNotFoundError :
234256 print (f"Error: YAML file '{ yaml_file_path } ' not found." )
235257 return ''
236258 except yaml .YAMLError as e :
237259 print (f"Error: Failed to parse YAML file '{ yaml_file_path } ': { e } " )
238260 return ''
261+ except Exception as e :
262+ print (f"Error: Unexpected error processing '{ yaml_file_path } ': { e } " )
263+ return ''
264+
265+
266+ def check_match_mask_pattern (instr_name , match_expr , mask_expr ):
267+ """
268+ Checks if the MATCH and MASK names follow the expected pattern based on instruction name.
269+ Allows both MATCH_NAME and MATCH_NAME_SUFFIX patterns.
270+
271+ Args:
272+ instr_name (str): The instruction name (e.g., "add" or "vfmin.vv")
273+ match_expr (str): The MATCH expression (e.g., "MATCH_ADD" or "MATCH_VFMINVV")
274+ mask_expr (str): The MASK expression (e.g., "MASK_ADD" or "MASK_VFMINVV")
275+
276+ Returns:
277+ bool: True if the pattern matches, False otherwise
278+ """
279+ # Convert instruction name to uppercase and handle special characters
280+ normalized_name = instr_name .replace ('.' , '' )
281+ normalized_name = normalized_name .replace ('_' , '' )
282+ normalized_name = normalized_name .upper ()
283+
284+ # Extract the base MATCH and MASK names (before any '|' operations)
285+ base_match = match_expr .split ('|' )[0 ].strip ()
286+ base_mask = mask_expr .split ('|' )[0 ].strip ()
287+
288+ # Remove MATCH_ and MASK_ prefixes
289+ if base_match .startswith ('MATCH_' ):
290+ base_match = base_match [6 :] # Remove 'MATCH_'
291+ if base_mask .startswith ('MASK_' ):
292+ base_mask = base_mask [5 :] # Remove 'MASK_'
293+
294+ # Remove any remaining underscores for comparison
295+ base_match = base_match .replace ('_' , '' )
296+ base_mask = base_mask .replace ('_' , '' )
297+
298+ # Now compare the normalized strings
299+ return base_match == normalized_name and base_mask == normalized_name
239300
240301def main ():
241302 """
0 commit comments