Skip to content

Commit ce2adef

Browse files
committed
fix: add backward compatibility for new instruction schema format
UDB generators were failing when processing instructions using the new schema format. Some instructions now use a 'format' field with 'opcodes' instead of the traditional 'encoding' field with 'match' patterns. Changes: - Added build_match_from_format() function to convert format.opcodes to match strings compatible with existing generator logic - Added support for variable instruction widths (16-bit, 32-bit, 48-bit) based on maximum bit position in opcode fields - Enhanced encoding detection to handle both old and new schema formats - Maintains full backward compatibility with existing instructions Tested with both Go and C header generators - no changes to output format. Signed-off-by: Afonso Oliveira <[email protected]>
1 parent a83d966 commit ce2adef

File tree

1 file changed

+84
-5
lines changed

1 file changed

+84
-5
lines changed

backends/generators/generator.py

Lines changed: 84 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,69 @@ def check_requirement(req, exts):
1717
return False
1818

1919

20+
def build_match_from_format(format_field):
21+
"""
22+
Build a match string from the format field in the new schema.
23+
Supports 16-bit, 32-bit, and 48-bit instructions.
24+
"""
25+
if not format_field or "opcodes" not in format_field:
26+
return None
27+
28+
opcodes = format_field["opcodes"]
29+
30+
# Determine instruction width by finding maximum bit position
31+
valid_locations = []
32+
for field_data in opcodes.values():
33+
if (isinstance(field_data, dict) and
34+
"location" in field_data and
35+
isinstance(field_data["location"], str)):
36+
try:
37+
location = field_data["location"]
38+
if "-" in location:
39+
high = int(location.split("-")[0])
40+
else:
41+
high = int(location)
42+
valid_locations.append(high)
43+
except (ValueError, IndexError):
44+
continue # Skip invalid location formats
45+
46+
if not valid_locations:
47+
return None
48+
49+
max_bit = max(valid_locations)
50+
51+
# Set instruction width based on maximum bit position
52+
width = 48 if max_bit >= 32 else 32 if max_bit >= 16 else 16
53+
match_bits = ["-"] * width
54+
55+
# Populate match string with opcode bits
56+
for field_data in opcodes.values():
57+
if (isinstance(field_data, dict) and
58+
"location" in field_data and "value" in field_data and
59+
isinstance(field_data["location"], str) and
60+
isinstance(field_data["value"], int)):
61+
62+
try:
63+
location = field_data["location"]
64+
if "-" in location:
65+
high, low = map(int, location.split("-"))
66+
else:
67+
high = low = int(location)
68+
69+
if high < low or high >= width:
70+
continue # Skip invalid bit ranges
71+
72+
binary_value = format(field_data["value"], f"0{high - low + 1}b")
73+
for i, bit in enumerate(binary_value):
74+
pos = high - i
75+
if 0 <= pos < width:
76+
match_bits[width - 1 - pos] = bit
77+
except (ValueError, IndexError):
78+
continue # Skip invalid field data
79+
80+
return "".join(match_bits)
81+
82+
2083
def parse_extension_requirements(extensions_spec):
2184
"""
2285
Parse the extension requirements from the definedBy field.
@@ -177,11 +240,27 @@ def load_instructions(
177240

178241
encoding = data.get("encoding", {})
179242
if not encoding:
180-
logging.error(
181-
f"Missing 'encoding' field in instruction {name} in {path}"
182-
)
183-
encoding_filtered += 1
184-
continue
243+
# Check if this instruction uses the new schema with a 'format' field
244+
format_field = data.get("format")
245+
if format_field:
246+
# Try to build a match string from the format field
247+
match_string = build_match_from_format(format_field)
248+
if match_string:
249+
# Create a synthetic encoding compatible with existing logic
250+
encoding = {"match": match_string, "variables": []}
251+
logging.debug(f"Built encoding from format field for {name}")
252+
else:
253+
logging.error(
254+
f"Could not build encoding from format field in instruction {name} in {path}"
255+
)
256+
encoding_filtered += 1
257+
continue
258+
else:
259+
logging.error(
260+
f"Missing 'encoding' field in instruction {name} in {path}"
261+
)
262+
encoding_filtered += 1
263+
continue
185264

186265
# Check if the instruction specifies a base architecture constraint
187266
base = data.get("base")

0 commit comments

Comments
 (0)