Skip to content

Commit 95863b1

Browse files
committed
Introduce ELF CPU extractor and simulator options.
Add a python script that extracts the ARC CPU name and XLEN from an ELF file by parsing the .ARC.attributes section. The script maps CPU names to simulator options. Currently only NSIM options are supported, but the design allows for future expansion to other simulators. Signed-off-by: Luis Silva <luiss@synopsys.com>
1 parent 72de729 commit 95863b1

File tree

2 files changed

+241
-2
lines changed

2 files changed

+241
-2
lines changed

Makefile.in

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ endif
145145
ifeq ($(SIM),qemu)
146146
# Using qemu simulator.
147147
SIM_STAMP:= stamps/build-qemu
148-
SIM_PATH:=$(srcdir)/scripts/wrapper/$(SIM)
148+
SIM_PATH:=$(srcdir)/scripts/wrapper/$(SIM):$(srcdir)/scripts
149149
SIM_PREPARE:=PATH="$(SIM_PATH):$(INSTALL_DIR)/bin:$(PATH)" ARC_SYSROOT="$(SYSROOT)" DEJAGNU="$(srcdir)/dejagnu/site.exp" QEMU_CPU="$(QEMU_CPU)"
150150
ifeq (@default_target@,baremetal)
151151
SIM_PREPARE:=$(SIM_PREPARE) DEJAGNU_SIM_OPTIONS="-Wq,-semihosting"
@@ -157,7 +157,7 @@ ifeq ($(SIM),nsim)
157157
$(error nSIM not supported)
158158
endif
159159
SIM_STAMP:= nsim-validation
160-
SIM_PATH:=$(srcdir)/scripts/wrapper/$(SIM)
160+
SIM_PATH:=$(srcdir)/scripts/wrapper/$(SIM):$(srcdir)/scripts
161161
SIM_PREPARE:=PATH="$(SIM_PATH):$(INSTALL_DIR)/bin:$(PATH)" ARC_SYSROOT="$(SYSROOT)" DEJAGNU="$(srcdir)/dejagnu/site.exp" QEMU_CPU="$(QEMU_CPU)"
162162
else
163163
$(error Only support SIM=nsim, or SIM=qemu (default))

scripts/mcpu-to-cpu-opts

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
#!/usr/bin/env python3
2+
3+
import argparse
4+
import sys
5+
import elftools.elf.elffile
6+
import elftools.elf.sections
7+
8+
CPU_OPTIONS = {
9+
"name": "",
10+
"xlen": "",
11+
}
12+
13+
nsim_opts = {
14+
"arc600": [
15+
"-p nsim_isa_family=a600",
16+
"-p nsim_isa_core=6",
17+
"-on nsim_isa_sat",
18+
"-p nsim_isa_bitscan_option=0"
19+
],
20+
"arc700": [
21+
"-p nsim_isa_family=a700",
22+
"-on nsim_isa_sat",
23+
"-on nsim_isa_mpy32"
24+
],
25+
"arcem": [
26+
"-p nsim_isa_family=av2em",
27+
"-p nsim_isa_core=3",
28+
"-on nsim_isa_sat",
29+
"-p nsim_isa_code_density_option=2",
30+
"-p nsim_isa_mpy_option=2",
31+
"-p nsim_isa_bitscan_option=0"
32+
],
33+
"archs": [
34+
"-p nsim_isa_family=av2hs",
35+
"-p nsim_isa_core=3",
36+
"-on nsim_isa_sat",
37+
"-p nsim_isa_atomic_option=1",
38+
"-p nsim_isa_code_density_option=2",
39+
"-p nsim_isa_div_rem_option=2",
40+
"-p nsim_isa_ll64_option=1",
41+
"-p nsim_isa_mpy_option=2"
42+
],
43+
"em": [
44+
"-p nsim_isa_family=av2em",
45+
"-p nsim_isa_core=3",
46+
"-on nsim_isa_sat",
47+
"-p nsim_isa_shift_option=0",
48+
"-p nsim_isa_bitscan_option=0"
49+
],
50+
"em4_fpuda": [
51+
"-p nsim_isa_family=av2em",
52+
"-p nsim_isa_core=3",
53+
"-on nsim_isa_sat",
54+
"-p nsim_isa_code_density_option=2",
55+
"-p nsim_isa_div_rem_option=2",
56+
"-p nsim_isa_fpuda_option=1",
57+
"-p nsim_isa_fpus_option=1",
58+
"-p nsim_isa_mpy_option=2"
59+
],
60+
"hs": [
61+
"-p nsim_isa_family=av2hs",
62+
"-p nsim_isa_core=3",
63+
"-on nsim_isa_sat",
64+
"-p nsim_isa_atomic_option=1",
65+
"-p nsim_isa_code_density_option=2"
66+
],
67+
"hs34": [
68+
"-p nsim_isa_family=av2hs",
69+
"-p nsim_isa_core=3",
70+
"-on nsim_isa_sat",
71+
"-p nsim_isa_atomic_option=1",
72+
"-p nsim_isa_code_density_option=2",
73+
"-p nsim_isa_mpy_option=2"
74+
],
75+
"hs38_linux": [
76+
"-p nsim_isa_family=av2hs",
77+
"-p nsim_isa_core=3",
78+
"-on nsim_isa_sat",
79+
"-p nsim_isa_atomic_option=1",
80+
"-p nsim_isa_code_density_option=2",
81+
"-p nsim_isa_div_rem_option=2",
82+
"-p nsim_isa_fpud_option=1",
83+
"-p nsim_isa_fpud_div_option=1",
84+
"-p nsim_isa_fpu_mac_option=1",
85+
"-p nsim_isa_fpus_option=1",
86+
"-p nsim_isa_fpus_div_option=1",
87+
"-p nsim_isa_fpu_mac_option=1",
88+
"-p nsim_isa_ll64_option=1",
89+
"-p nsim_isa_mpy_option=9"
90+
],
91+
"hs4xd": [
92+
"-p nsim_isa_family=av2hs",
93+
"-p nsim_isa_core=3",
94+
"-on nsim_isa_sat",
95+
"-p nsim_isa_atomic_option=1",
96+
"-p nsim_isa_code_density_option=2",
97+
"-p nsim_isa_div_rem_option=2",
98+
"-p nsim_isa_ll64_option=1",
99+
"-p nsim_isa_mpy_option=9"
100+
],
101+
"hs58": [
102+
"-prop=nsim_hlink_gnu_io_ext=1",
103+
"-p nsim_isa_family=av3hs",
104+
"-p nsim_isa_pc_size=32",
105+
"-p nsim_isa_addr_size=32",
106+
"-p nsim_isa_swap_option=1",
107+
"-p nsim_isa_bitscan_option=1",
108+
"-p nsim_isa_div_rem_option=2",
109+
"-p nsim_isa_mpy_option=9",
110+
"-p nsim_isa_unaligned_option=1",
111+
"-p nsim_isa_atomic_option=1",
112+
"-p nsim_isa_ll64_option=1",
113+
"-p nsim_isa_fp_wide_option=1",
114+
"-p nsim_isa_shift_option=0",
115+
"-p nsim_isa_bitscan_option=0"
116+
],
117+
"hs5x": [
118+
"-prop=nsim_hlink_gnu_io_ext=1",
119+
"-p nsim_isa_family=av3hs",
120+
"-p nsim_isa_pc_size=32",
121+
"-p nsim_isa_addr_size=32",
122+
"-p nsim_isa_swap_option=1",
123+
"-p nsim_isa_bitscan_option=1",
124+
"-p nsim_isa_div_rem_option=2",
125+
"-p nsim_isa_mpy_option=9",
126+
"-p nsim_isa_unaligned_option=1",
127+
"-p nsim_isa_atomic_option=1",
128+
"-p nsim_isa_fp_wide_option=1",
129+
"-p nsim_isa_shift_option=0",
130+
"-p nsim_isa_bitscan_option=0"
131+
],
132+
"hs68": [
133+
"-prop=nsim_hlink_gnu_io_ext=1",
134+
"-p nsim_isa_family=arc64",
135+
"-p nsim_isa_div_rem_option=2",
136+
"-p nsim_isa_mpy_option=9",
137+
"-p nsim_isa_mpy64=1",
138+
"-p nsim_isa_div64_option=1",
139+
"-p nsim_isa_has_fp=1",
140+
"-p nsim_isa_fp_vec_option=1",
141+
"-p nsim_isa_fp_hp_option=1",
142+
"-p nsim_isa_fp_dp_option=1",
143+
"-p nsim_isa_fp_div_option=1",
144+
"-p nsim_isa_fp_num_regs=32",
145+
"-p nsim_isa_unaligned_option=1",
146+
"-p nsim_isa_atomic_option=1",
147+
"-p nsim_isa_m128_option=1",
148+
"-p nsim_isa_fp_wide_option=1",
149+
"-p nsim_isa_shift_option=0",
150+
"-p nsim_isa_bitscan_option=0"
151+
],
152+
"hs6x": [
153+
"-prop=nsim_hlink_gnu_io_ext=1",
154+
"-p nsim_isa_family=arc64",
155+
"-p nsim_isa_div_rem_option=2",
156+
"-p nsim_isa_mpy_option=9",
157+
"-p nsim_isa_mpy64=1",
158+
"-p nsim_isa_div64_option=1",
159+
"-p nsim_isa_has_fp=1",
160+
"-p nsim_isa_fp_vec_option=1",
161+
"-p nsim_isa_fp_hp_option=1",
162+
"-p nsim_isa_fp_dp_option=1",
163+
"-p nsim_isa_fp_div_option=1",
164+
"-p nsim_isa_fp_num_regs=32",
165+
"-p nsim_isa_unaligned_option=1",
166+
"-p nsim_isa_atomic_option=1",
167+
"-p nsim_isa_fp_wide_option=1",
168+
"-p nsim_isa_shift_option=0",
169+
"-p nsim_isa_bitscan_option=0"
170+
]
171+
}
172+
173+
def print_nsim_opts():
174+
cpu_name = CPU_OPTIONS["name"]
175+
opts = " ".join(nsim_opts[cpu_name])
176+
return opts
177+
178+
def open_elf(path):
179+
try:
180+
elffile = elftools.elf.elffile.ELFFile(open(path, 'rb'))
181+
except elftools.common.exceptions.ELFError:
182+
raise Exception("%s is not ELF file!" % path)
183+
return elffile
184+
185+
def get_xlen(path):
186+
elffile = open_elf(path)
187+
return elffile.elfclass
188+
189+
def get_arc_cpu_name_bits(path):
190+
elffile = open_elf(path)
191+
192+
sec = elffile.get_section_by_name(".ARC.attributes")
193+
if not sec:
194+
raise RuntimeError(".ARC.attributes section not found")
195+
196+
data = sec.data()
197+
for i, b in enumerate(data):
198+
if b == 0x07: # Tag_ARC_CPU_name
199+
# Extract following null-terminated string
200+
j = i + 1
201+
while j < len(data) and data[j] != 0:
202+
j += 1
203+
return data[i+1:j].decode()
204+
205+
raise RuntimeError("CPU name not found")
206+
207+
def parse_elf_file(elf_file_path):
208+
xlen = get_xlen(elf_file_path)
209+
cpu_name = get_arc_cpu_name_bits(elf_file_path)
210+
CPU_OPTIONS["name"] = cpu_name
211+
CPU_OPTIONS["xlen"] = xlen
212+
213+
def parse_opt(argv):
214+
parser = argparse.ArgumentParser()
215+
parser.add_argument('--elf-file-path', type=str)
216+
parser.add_argument('--print-xlen', action='store_true', default=False)
217+
parser.add_argument('--print-cpu', action='store_true', default=False)
218+
parser.add_argument('--print-nsim-opts', action='store_true', default=False)
219+
opt = parser.parse_args()
220+
return opt
221+
222+
def main(argv):
223+
opt = parse_opt(argv)
224+
225+
parse_elf_file(opt.elf_file_path)
226+
227+
if opt.print_xlen:
228+
print(CPU_OPTIONS['xlen'])
229+
return
230+
231+
if opt.print_cpu:
232+
print(CPU_OPTIONS['name'])
233+
return
234+
235+
if opt.print_nsim_opts:
236+
print(print_nsim_opts())
237+
238+
if __name__ == '__main__':
239+
sys.exit(main(sys.argv))

0 commit comments

Comments
 (0)