@@ -52,20 +52,27 @@ def load_yaml_encoding(instr_name):
5252
5353 return yaml_match , yaml_vars
5454
55- def compare_yaml_json_encoding (yaml_match , yaml_vars , json_encoding_str ):
55+ def compare_yaml_json_encoding (instr_name , yaml_match , yaml_vars , json_encoding_str ):
5656 """
5757 Compare the YAML encoding (match + vars) with the JSON encoding (binary format).
5858 If the JSON has a variable like vm[?], it should be treated as just vm.
59+
60+ If instr_name starts with 'C_', then treat the instruction as 16 bits long.
61+ Otherwise, treat it as 32 bits long.
62+
5963 Return a list of differences.
6064 """
6165 if not yaml_match :
6266 return ["No YAML match field available for comparison." ]
6367 if not json_encoding_str :
6468 return ["No JSON encoding available for comparison." ]
6569
70+ # Determine expected length based on whether it's a compressed instruction (C_)
71+ expected_length = 16 if instr_name .startswith ('C_' ) else 32
72+
6673 yaml_pattern_str = yaml_match .replace ('-' , '.' )
67- if len (yaml_pattern_str ) != 32 :
68- return [f"YAML match pattern length is { len (yaml_pattern_str )} , expected 32 . Cannot compare properly." ]
74+ if len (yaml_pattern_str ) != expected_length :
75+ return [f"YAML match pattern length is { len (yaml_pattern_str )} , expected { expected_length } . Cannot compare properly." ]
6976
7077 def parse_location (loc_str ):
7178 high , low = loc_str .split ('-' )
@@ -76,16 +83,18 @@ def parse_location(loc_str):
7683 high , low = parse_location (var ["location" ])
7784 yaml_var_positions [var ["name" ]] = (high , low )
7885
86+ # Tokenize the JSON encoding string. We assume it should match the expected_length in bits.
7987 tokens = re .findall (r'(?:[01]|[A-Za-z0-9]+(?:\[\d+\]|\[\?\])?)' , json_encoding_str )
8088 json_bits = []
81- bit_index = 31
89+ bit_index = expected_length - 1
8290 for t in tokens :
8391 json_bits .append ((bit_index , t ))
8492 bit_index -= 1
8593
8694 if bit_index != - 1 :
87- return [f"JSON encoding does not appear to be 32 bits. Ends at bit { bit_index + 1 } ." ]
95+ return [f"JSON encoding does not appear to be { expected_length } bits. Ends at bit { bit_index + 1 } ." ]
8896
97+ # Normalize JSON bits (handle vm[?] etc.)
8998 normalized_json_bits = []
9099 for pos , tt in json_bits :
91100 if re .match (r'vm\[[^\]]*\]' , tt ):
@@ -96,8 +105,8 @@ def parse_location(loc_str):
96105 differences = []
97106
98107 # Check fixed bits
99- for b in range (32 ):
100- yaml_bit = yaml_pattern_str [31 - b ]
108+ for b in range (expected_length ):
109+ yaml_bit = yaml_pattern_str [expected_length - 1 - b ]
101110 token = [tt for (pos , tt ) in json_bits if pos == b ]
102111 if not token :
103112 differences .append (f"Bit { b } : No corresponding JSON bit found." )
@@ -115,6 +124,11 @@ def parse_location(loc_str):
115124
116125 # Check variable fields
117126 for var_name , (high , low ) in yaml_var_positions .items ():
127+ # Ensure the variable range fits within the expected_length
128+ if high >= expected_length or low < 0 :
129+ differences .append (f"Variable { var_name } : location { high } -{ low } is out of range for { expected_length } -bit instruction." )
130+ continue
131+
118132 json_var_fields = []
119133 for bb in range (low , high + 1 ):
120134 token = [tt for (pos , tt ) in json_bits if pos == bb ]
@@ -190,7 +204,7 @@ def safe_print_instruction_details(name: str, data: dict, output_stream):
190204
191205 if yaml_match and encoding :
192206 # Perform comparison
193- differences = compare_yaml_json_encoding (yaml_match , yaml_vars , encoding )
207+ differences = compare_yaml_json_encoding (name , yaml_match , yaml_vars , encoding )
194208 if differences and len (differences ) > 0 :
195209 output_stream .write ("\n Encodings do not match. Differences:\n " )
196210 for d in differences :
0 commit comments