-
Notifications
You must be signed in to change notification settings - Fork 4
Introduce ELF CPU extractor and simulator options. #42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
5dce07c
faba84d
d352f28
22e46eb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,236 @@ | ||
#!/usr/bin/env python3 | ||
|
||
import argparse | ||
import sys | ||
import elftools.elf.elffile | ||
import elftools.elf.sections | ||
|
||
CPU_OPTIONS = { | ||
"name": "", | ||
"xlen": "", | ||
} | ||
|
||
nsim_opts = { | ||
"arc600": [ | ||
"-p nsim_isa_family=a600", | ||
"-p nsim_isa_core=6", | ||
"-on nsim_isa_sat", | ||
"-p nsim_isa_bitscan_option=0" | ||
], | ||
"arc700": [ | ||
"-p nsim_isa_family=a700", | ||
"-on nsim_isa_sat", | ||
"-on nsim_isa_mpy32" | ||
], | ||
"arcem": [ | ||
"-p nsim_isa_family=av2em", | ||
"-p nsim_isa_core=3", | ||
"-on nsim_isa_sat", | ||
"-p nsim_isa_code_density_option=2", | ||
"-p nsim_isa_mpy_option=2", | ||
"-p nsim_isa_bitscan_option=0" | ||
], | ||
"archs": [ | ||
"-p nsim_isa_family=av2hs", | ||
"-p nsim_isa_core=3", | ||
"-on nsim_isa_sat", | ||
"-p nsim_isa_atomic_option=1", | ||
"-p nsim_isa_code_density_option=2", | ||
"-p nsim_isa_div_rem_option=2", | ||
"-p nsim_isa_ll64_option=1", | ||
"-p nsim_isa_mpy_option=2" | ||
], | ||
"em": [ | ||
"-p nsim_isa_family=av2em", | ||
"-p nsim_isa_core=3", | ||
"-on nsim_isa_sat", | ||
"-p nsim_isa_shift_option=0", | ||
"-p nsim_isa_bitscan_option=0" | ||
], | ||
"em4_fpuda": [ | ||
"-p nsim_isa_family=av2em", | ||
"-p nsim_isa_core=3", | ||
"-on nsim_isa_sat", | ||
"-p nsim_isa_code_density_option=2", | ||
"-p nsim_isa_div_rem_option=2", | ||
"-p nsim_isa_fpuda_option=1", | ||
"-p nsim_isa_fpus_option=1", | ||
"-p nsim_isa_mpy_option=2" | ||
], | ||
"hs": [ | ||
"-p nsim_isa_family=av2hs", | ||
"-p nsim_isa_core=3", | ||
"-on nsim_isa_sat", | ||
"-p nsim_isa_atomic_option=1", | ||
"-p nsim_isa_code_density_option=2" | ||
], | ||
"hs34": [ | ||
"-p nsim_isa_family=av2hs", | ||
"-p nsim_isa_core=3", | ||
"-on nsim_isa_sat", | ||
"-p nsim_isa_atomic_option=1", | ||
"-p nsim_isa_code_density_option=2", | ||
"-p nsim_isa_mpy_option=2" | ||
], | ||
"hs38_linux": [ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's a very fragile approach. See, what you have here I guess is ARCv2 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure, there are cases where additional options (-mmpy-option, -m{no-}ll64, etc.) affect the generated code and should be reflected in the execution command. The intention of this PR, though, is not to cover every possible configuration detail upfront, but to provide a baseline: a generic execution command per CPU which was extracted from the Jenkins dejagnu logs. This already saves developers from having to manually search CI logs when reproducing regressions. The script can definitely be extended in the future to handle specific feature options or more complex configurations, but even in its current form it significantly reduces the manual effort of local testing. |
||
"-p nsim_isa_family=av2hs", | ||
"-p nsim_isa_core=3", | ||
"-on nsim_isa_sat", | ||
"-p nsim_isa_atomic_option=1", | ||
"-p nsim_isa_code_density_option=2", | ||
"-p nsim_isa_div_rem_option=2", | ||
"-p nsim_isa_fpud_option=1", | ||
"-p nsim_isa_fpud_div_option=1", | ||
"-p nsim_isa_fpus_option=1", | ||
"-p nsim_isa_fpus_div_option=1", | ||
"-p nsim_isa_fpu_mac_option=1", | ||
"-p nsim_isa_ll64_option=1", | ||
"-p nsim_isa_mpy_option=9" | ||
], | ||
"hs4xd": [ | ||
"-p nsim_isa_family=av2hs", | ||
"-p nsim_isa_core=3", | ||
"-on nsim_isa_sat", | ||
"-p nsim_isa_atomic_option=1", | ||
"-p nsim_isa_code_density_option=2", | ||
"-p nsim_isa_div_rem_option=2", | ||
"-p nsim_isa_ll64_option=1", | ||
"-p nsim_isa_mpy_option=9" | ||
], | ||
"hs58": [ | ||
"-prop=nsim_hlink_gnu_io_ext=1", | ||
"-p nsim_isa_family=av3hs", | ||
"-p nsim_isa_pc_size=32", | ||
"-p nsim_isa_addr_size=32", | ||
"-p nsim_isa_swap_option=1", | ||
"-p nsim_isa_div_rem_option=2", | ||
"-p nsim_isa_mpy_option=9", | ||
"-p nsim_isa_unaligned_option=1", | ||
"-p nsim_isa_atomic_option=1", | ||
"-p nsim_isa_ll64_option=1", | ||
"-p nsim_isa_fp_wide_option=1", | ||
"-p nsim_isa_shift_option=0", | ||
"-p nsim_isa_bitscan_option=0" | ||
], | ||
"hs5x": [ | ||
"-prop=nsim_hlink_gnu_io_ext=1", | ||
"-p nsim_isa_family=av3hs", | ||
"-p nsim_isa_pc_size=32", | ||
"-p nsim_isa_addr_size=32", | ||
"-p nsim_isa_swap_option=1", | ||
"-p nsim_isa_div_rem_option=2", | ||
"-p nsim_isa_mpy_option=9", | ||
"-p nsim_isa_unaligned_option=1", | ||
"-p nsim_isa_atomic_option=1", | ||
"-p nsim_isa_fp_wide_option=1", | ||
"-p nsim_isa_shift_option=0", | ||
"-p nsim_isa_bitscan_option=0" | ||
], | ||
"hs68": [ | ||
"-prop=nsim_hlink_gnu_io_ext=1", | ||
"-p nsim_isa_family=arc64", | ||
"-p nsim_isa_div_rem_option=2", | ||
"-p nsim_isa_mpy_option=9", | ||
"-p nsim_isa_mpy64=1", | ||
"-p nsim_isa_div64_option=1", | ||
"-p nsim_isa_has_fp=1", | ||
"-p nsim_isa_fp_vec_option=1", | ||
"-p nsim_isa_fp_hp_option=1", | ||
"-p nsim_isa_fp_dp_option=1", | ||
"-p nsim_isa_fp_div_option=1", | ||
"-p nsim_isa_fp_num_regs=32", | ||
"-p nsim_isa_unaligned_option=1", | ||
"-p nsim_isa_atomic_option=1", | ||
"-p nsim_isa_m128_option=1", | ||
"-p nsim_isa_fp_wide_option=1", | ||
"-p nsim_isa_shift_option=0", | ||
"-p nsim_isa_bitscan_option=0" | ||
], | ||
"hs6x": [ | ||
"-prop=nsim_hlink_gnu_io_ext=1", | ||
"-p nsim_isa_family=arc64", | ||
"-p nsim_isa_div_rem_option=2", | ||
"-p nsim_isa_mpy_option=9", | ||
"-p nsim_isa_mpy64=1", | ||
"-p nsim_isa_div64_option=1", | ||
"-p nsim_isa_has_fp=1", | ||
"-p nsim_isa_fp_vec_option=1", | ||
"-p nsim_isa_fp_hp_option=1", | ||
"-p nsim_isa_fp_dp_option=1", | ||
"-p nsim_isa_fp_div_option=1", | ||
"-p nsim_isa_fp_num_regs=32", | ||
"-p nsim_isa_unaligned_option=1", | ||
"-p nsim_isa_atomic_option=1", | ||
"-p nsim_isa_fp_wide_option=1", | ||
"-p nsim_isa_shift_option=0", | ||
"-p nsim_isa_bitscan_option=0" | ||
] | ||
} | ||
|
||
def print_nsim_opts(): | ||
cpu_name = CPU_OPTIONS["name"] | ||
opts = " ".join(nsim_opts[cpu_name]) | ||
return opts | ||
|
||
def open_elf(path): | ||
try: | ||
elffile = elftools.elf.elffile.ELFFile(open(path, 'rb')) | ||
except elftools.common.exceptions.ELFError: | ||
raise Exception("%s is not ELF file!" % path) | ||
return elffile | ||
|
||
def get_xlen(path): | ||
elffile = open_elf(path) | ||
return elffile.elfclass | ||
|
||
def get_arc_cpu_name_bits(path): | ||
elffile = open_elf(path) | ||
|
||
sec = elffile.get_section_by_name(".ARC.attributes") | ||
if not sec: | ||
raise RuntimeError(".ARC.attributes section not found") | ||
|
||
data = sec.data() | ||
for i, b in enumerate(data): | ||
if b == 0x07: # Tag_ARC_CPU_name | ||
# Extract following null-terminated string | ||
j = i + 1 | ||
while j < len(data) and data[j] != 0: | ||
j += 1 | ||
return data[i+1:j].decode() | ||
|
||
raise RuntimeError("CPU name not found") | ||
|
||
def parse_elf_file(elf_file_path): | ||
xlen = get_xlen(elf_file_path) | ||
cpu_name = get_arc_cpu_name_bits(elf_file_path) | ||
CPU_OPTIONS["name"] = cpu_name | ||
CPU_OPTIONS["xlen"] = xlen | ||
|
||
def parse_opt(argv): | ||
parser = argparse.ArgumentParser() | ||
parser.add_argument('--elf-file-path', type=str) | ||
parser.add_argument('--print-xlen', action='store_true', default=False) | ||
parser.add_argument('--print-cpu', action='store_true', default=False) | ||
parser.add_argument('--print-nsim-opts', action='store_true', default=False) | ||
opt = parser.parse_args() | ||
return opt | ||
|
||
def main(argv): | ||
opt = parse_opt(argv) | ||
|
||
parse_elf_file(opt.elf_file_path) | ||
|
||
if opt.print_xlen: | ||
print(CPU_OPTIONS['xlen']) | ||
return | ||
|
||
if opt.print_cpu: | ||
print(CPU_OPTIONS['name']) | ||
return | ||
|
||
if opt.print_nsim_opts: | ||
print(print_nsim_opts()) | ||
|
||
if __name__ == '__main__': | ||
sys.exit(main(sys.argv)) |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
arc64-elf-run |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
arc64-elf-run |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we handle the 3rd party dependency somehow?
Install in a venv in the makefile? Or at least print an error with instructions if its not found.