Skip to content

Commit

Permalink
Added correct enconding for immediates that are split
Browse files Browse the repository at this point in the history
Signed-off-by: Afonso Oliveira <Afonso.Oliveira@synopsys.com>
  • Loading branch information
AFOliveira committed Aug 22, 2024
1 parent 4ece3f0 commit dceea29
Showing 1 changed file with 83 additions and 24 deletions.
107 changes: 83 additions & 24 deletions ext/auto-instr/parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -538,31 +538,92 @@ def process_extension(ext):
return [ext.capitalize()] # fallback for unexpected formats

def make_yaml_encoding(instr_name, instr_data):
encoding = instr_data['encoding']
var_fields = instr_data.get('variable_fields', [])

match = ''.join([bit if bit != '-' else '-' for bit in encoding])

variables = []
for field_name in var_fields:
if field_name in arg_lut:
encoding = instr_data['encoding']
var_fields = instr_data.get('variable_fields', [])

match = ''.join([bit if bit != '-' else '-' for bit in encoding])

variables = []
imm_parts = []
imm_locations= []

def parse_imm_location(field_name, imm_str):
parts = imm_str.split('[')[1].split(']')[0].split('|')
start_bit, end_bit = arg_lut[field_name]
current_bit = start_bit
location_parts = []
for part in parts:
if ':' in part:
part_start, part_end = map(int, part.split(':'))
part_bits = part_start - part_end + 1
location_parts.append(f'{current_bit}-{current_bit - part_bits + 1}')
current_bit -= part_bits
else:
location_parts.append(str(current_bit))
current_bit -= 1
parts=[int(part.split(':')[0]) for part in parts]
return (location_parts, parts)

for field_name in var_fields:
if field_name in asciidoc_mapping:
mapped_name = asciidoc_mapping[field_name]
if '[' in mapped_name and ']' in mapped_name and (mapped_name.startswith('imm') or mapped_name.startswith('uimm') or mapped_name.startswith('nzimm')):
# This is an immediate field
new_locations, new_parts = parse_imm_location(field_name, mapped_name)
imm_locations += new_locations
imm_parts += new_parts

else:
# This is a regular field
start_bit, end_bit = arg_lut[field_name]
variables.append({
'name': mapped_name,
'location': f'{start_bit}-{end_bit}'
})
else:
# If not in asciidoc_mapping, use the original field name and bit range
start_bit, end_bit = arg_lut[field_name]
variables.append({
'name': field_name,
'location': f'{start_bit}-{end_bit}'
})


# Add merged immediate field if there are any immediate parts
if imm_parts:
def sort_imm_tuple(imm_sorting):
imm_parts, imm_locations = imm_sorting

# Create a list of tuples, each containing an item from imm_parts and its corresponding item from imm_locations
paired = list(zip(imm_parts, imm_locations))

# Sort the paired list based on the imm_parts values (first element of each tuple) in descending order
sorted_paired = sorted(paired, key=lambda x: x[0], reverse=True)

# Unzip the sorted list back into two separate lists
sorted_parts, sorted_locations = zip(*sorted_paired)

return (list(sorted_locations))

print(instr_name)
imm_sorting = (imm_parts, imm_locations)
print (imm_sorting)
imm_locations= sort_imm_tuple(imm_sorting)

variables.append({
'name': field_name,
'location': f'{start_bit}-{end_bit}',
'start-bit': start_bit,
'end_bit':end_bit
'name': 'imm',
'location': '|'.join(imm_locations)
})
# Sort variables in descending order based on the start of the bit range
variables.sort(key=lambda x: int(x['location'].split('-')[0]), reverse=True)
result = {
'match': match,
'variables': variables
}
return result

# Sort variables in descending order based on the start of the bit range
variables.sort(key=lambda x: int(x['location'].split('-')[0].split('|')[0]), reverse=True)

result = {
'match': match,
'variables': variables
}

return result

def get_yaml_encoding_diff(instr_data_original, pseudo_instructions):
def get_variables(instr_data):
Expand Down Expand Up @@ -710,8 +771,6 @@ def get_yaml_base(instr_data):
'RV32': make_yaml_encoding(rv32_instructions[instr_name], instr_dict[rv32_instructions[instr_name]]),
'RV64': make_yaml_encoding(instr_name, instr_data)
}
else:
yaml_content[instr_name_with_periods]['encoding'] = make_yaml_encoding(instr_name, instr_data)

if yaml_content[instr_name_with_periods]['base'] is None or (instr_name in rv32_instructions):
yaml_content[instr_name_with_periods].pop('base')
Expand Down

0 comments on commit dceea29

Please sign in to comment.