Skip to content

Commit aab7d0f

Browse files
committed
fix: add backward compatibility for new instruction schema format
UDB currently allows for 2 schemas for instructions with the on-going sub-type development. Some instructions now use a 'format' field with 'opcodes' instead of the traditional 'encoding' field with 'match' and 'variables'. This caused generators to fail when processing these instructions as they couldn't extract the bit pattern matching information. Changes: - Added build_match_from_format() function to convert format.opcodes to match strings compatible with existing generator logic - Enhanced encoding detection in load_instruction() to handle both old schema (encoding.match) and new schema (format.opcodes) - Maintains full backward compatibility with existing instructions - No functional changes to generated output format The fix ensures generators can process the complete UDB instruction set regardless of which schema format individual instructions use. Signed-off-by: Afonso Oliveira <[email protected]>
1 parent a83d966 commit aab7d0f

File tree

1 file changed

+70
-5
lines changed

1 file changed

+70
-5
lines changed

backends/generators/generator.py

Lines changed: 70 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,55 @@ 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+
The format field contains opcodes with specific bit fields.
24+
"""
25+
if not format_field or "opcodes" not in format_field:
26+
return None
27+
28+
opcodes = format_field["opcodes"]
29+
30+
# Initialize a 32-bit match string with all variable bits
31+
match_bits = ["-"] * 32
32+
33+
# Process each opcode field
34+
for field_name, field_data in opcodes.items():
35+
if field_name == "$child_of":
36+
continue
37+
38+
if (
39+
isinstance(field_data, dict)
40+
and "location" in field_data
41+
and "value" in field_data
42+
):
43+
location = field_data["location"]
44+
value = field_data["value"]
45+
46+
# Parse the location string (e.g., "31-25" or "7")
47+
if "-" in location:
48+
# Range format like "31-25"
49+
high, low = map(int, location.split("-"))
50+
else:
51+
# Single bit format like "7"
52+
high = low = int(location)
53+
54+
# Convert value to binary and place in the match string
55+
if isinstance(value, int):
56+
# Calculate the number of bits needed
57+
num_bits = high - low + 1
58+
binary_value = format(value, f"0{num_bits}b")
59+
60+
# Place bits in the match string (MSB first)
61+
for i, bit in enumerate(binary_value):
62+
bit_position = high - i
63+
if 0 <= bit_position < 32:
64+
match_bits[31 - bit_position] = bit
65+
66+
return "".join(match_bits)
67+
68+
2069
def parse_extension_requirements(extensions_spec):
2170
"""
2271
Parse the extension requirements from the definedBy field.
@@ -177,11 +226,27 @@ def load_instructions(
177226

178227
encoding = data.get("encoding", {})
179228
if not encoding:
180-
logging.error(
181-
f"Missing 'encoding' field in instruction {name} in {path}"
182-
)
183-
encoding_filtered += 1
184-
continue
229+
# Check if this instruction uses the new schema with a 'format' field
230+
format_field = data.get("format")
231+
if format_field:
232+
# Try to build a match string from the format field
233+
match_string = build_match_from_format(format_field)
234+
if match_string:
235+
# Create a synthetic encoding compatible with existing logic
236+
encoding = {"match": match_string, "variables": []}
237+
logging.debug(f"Built encoding from format field for {name}")
238+
else:
239+
logging.error(
240+
f"Could not build encoding from format field in instruction {name} in {path}"
241+
)
242+
encoding_filtered += 1
243+
continue
244+
else:
245+
logging.error(
246+
f"Missing 'encoding' field in instruction {name} in {path}"
247+
)
248+
encoding_filtered += 1
249+
continue
185250

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

0 commit comments

Comments
 (0)