Skip to content

Commit

Permalink
Correctly detect overlapping encodings
Browse files Browse the repository at this point in the history
A regression introduced a few years ago prevented detecting partially
overlapping encodings; instead, we only detected exact matches.  Now, we
detect the partial cases.

We now need to maintain two allowlists (overlapping_extensions and
overlapping_instructions) for the cases that extensions and/or
instructions overlap by design.
  • Loading branch information
aswaterman committed May 1, 2024
1 parent 09879e6 commit 89d1296
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 11 deletions.
14 changes: 14 additions & 0 deletions constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@
import csv


overlapping_extensions = {
'rv_zcmt': {'rv_c_d'},
'rv_zcmp': {'rv_c_d'},
'rv_c': {'rv_zcmop'},
}

overlapping_instructions = {
'c_addi': {'c_nop'},
'c_lui': {'c_addi16sp'},
'c_mv': {'c_jr'},
'c_jalr': {'c_ebreak'},
'c_add': {'c_ebreak', 'c_jalr'},
}

isa_regex = \
re.compile("^RV(32|64|128)[IE]+[ABCDEFGHJKLMNPQSTUVX]*(Zicsr|Zifencei|Zihintpause|Zam|Ztso|Zkne|Zknd|Zknh|Zkse|Zksh|Zkg|Zkb|Zkr|Zks|Zkn|Zba|Zbc|Zbb|Zbp|Zbr|Zbm|Zbs|Zbe|Zbf|Zbt|Zmmul|Zbpbo|Zca|Zcf|Zcd|Zcb|Zcmp|Zcmt){,1}(_Zicsr){,1}(_Zifencei){,1}(_Zihintpause){,1}(_Zmmul){,1}(_Zam){,1}(_Zba){,1}(_Zbb){,1}(_Zbc){,1}(_Zbe){,1}(_Zbf){,1}(_Zbm){,1}(_Zbp){,1}(_Zbpbo){,1}(_Zbr){,1}(_Zbs){,1}(_Zbt){,1}(_Zkb){,1}(_Zkg){,1}(_Zkr){,1}(_Zks){,1}(_Zkn){,1}(_Zknd){,1}(_Zkne){,1}(_Zknh){,1}(_Zkse){,1}(_Zksh){,1}(_Ztso){,1}(_Zca){,1}(_Zcf){,1}(_Zcd){,1}(_Zcb){,1}(_Zcmp){,1}(_Zcmt){,1}$")

Expand Down
45 changes: 34 additions & 11 deletions parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ def process_enc_line(line, ext):

return (name, single_dict)

def same_base_ext (ext_name, ext_name_list):
def same_base_isa(ext_name, ext_name_list):
type1 = ext_name.split("_")[0]
for ext_name1 in ext_name_list:
type2 = ext_name1.split("_")[0]
Expand All @@ -144,6 +144,26 @@ def same_base_ext (ext_name, ext_name_list):
return True
return False

def overlaps(x, y):
x = x.rjust(len(y), '-')
y = y.rjust(len(x), '-')

for i in range(0, len(x)):
if not (x[i] == '-' or y[i] == '-' or x[i] == y[i]):
return False

return True

def overlap_allowed(a, x, y):
return x in a and y in a[x] or \
y in a and x in a[y]

def extension_overlap_allowed(x, y):
return overlap_allowed(overlapping_extensions, x, y)

def instruction_overlap_allowed(x, y):
return overlap_allowed(overlapping_instructions, x, y)

def create_inst_dict(file_filter, include_pseudo=False, include_pseudo_ops=[]):
'''
This function return a dictionary containing all instructions associated
Expand Down Expand Up @@ -222,29 +242,32 @@ def create_inst_dict(file_filter, include_pseudo=False, include_pseudo_ops=[]):
# instruction is already imported and raise SystemExit
if name in instr_dict:
var = instr_dict[name]["extension"]
if same_base_ext(ext_name, var):
# disable same names on the same base extensions
if same_base_isa(ext_name, var):
# disable same names on the same base ISA
err_msg = f'instruction : {name} from '
err_msg += f'{ext_name} is already '
err_msg += f'added from {var} in same base extensions'
err_msg += f'added from {var} in same base ISA'
logging.error(err_msg)
raise SystemExit(1)
elif instr_dict[name]['encoding'] != single_dict['encoding']:
# disable same names with different encodings on different base extensions
# disable same names with different encodings on different base ISAs
err_msg = f'instruction : {name} from '
err_msg += f'{ext_name} is already '
err_msg += f'added from {var} but each have different encodings in different base extensions'
err_msg += f'added from {var} but each have different encodings in different base ISAs'
logging.error(err_msg)
raise SystemExit(1)
instr_dict[name]['extension'].extend(single_dict['extension'])
else:
for key in instr_dict:
item = instr_dict[key]
if item["encoding"] == single_dict['encoding'] and same_base_ext(ext_name, item["extension"]):
# disable different names with same encodings on the same base extensions
err_msg = f'instruction : {name} from '
err_msg += f'{ext_name} has the same encoding with instruction {key} '
err_msg += f'added from {item["extension"]} in same base extensions'
if overlaps(item['encoding'], single_dict['encoding']) and \
not extension_overlap_allowed(ext_name, item['extension'][0]) and \
not instruction_overlap_allowed(name, key) and \
same_base_isa(ext_name, item['extension']):
# disable different names with overlapping encodings on the same base ISA
err_msg = f'instruction : {name} in extension '
err_msg += f'{ext_name} overlaps instruction {key} '
err_msg += f'in extension {item["extension"]}'
logging.error(err_msg)
raise SystemExit(1)

Expand Down

0 comments on commit 89d1296

Please sign in to comment.